このディレクトリの索引
http://pc12.2ch.net/test/read.cgi/tech/1260532772/38
#  [1] 授業単元: プログラミング演習 
#  [2] 問題文(含コード&リンク): http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10261.txt 

# 以下のプログラムを作成せよ。
。# プログラムは日付・休日かどうか・出費の分類(朝食・昼食・夕食・本・休日)、
# 出費の金額・買ったものの名前を順に尋ね、2にある構造体の配列(最大20件)に格納して
# 最後に配列のデータをファイルに追記する。連続で入力できるようにし、もしユーザが
# 日付で0年と入力すると終了するようにする。
# 
# 
# 課題の流れ
# 
# ・繰り返し構造
#      年月日、休日かどうか、出費の分類、金額、商品名を聞き、
#     syuppi構造体の配列に順次記録する。
#      0年と入力されたら、繰り返しを終了
# 
# ・配列に記録した件数分、ファイルに1行ずつ記録する
# 
# ・プログラムの最後で、ファイルに記録されているデータを表示せよ。
# 
# ###分類の2進数の計算の仕方
# 1ビット目から5ビット目まで朝食、昼食、夕食、本、休日の順でビットが立つ。
# 朝食なら1、昼食なら2、夕食なら4、本なら8、休日なら16
# として、合計をとれば良い。
# 休日の夕食なら 16+4=20となる
# 
# ###たとえば、以下の行は以下を
# 休日の2009年12月11日に朝食で食パンを350円 買い
# 休日の2009年12月11日にJumpという本を240円 買った
# 
# syokupan 17 2009 12 11 350
# Jump 24 2009 12 11 200
# 
解析上鍵となる言葉([休日,年,月,日,円,朝食,夕食,本,は,が,の,に,で,ために,へ,を, 
買]). 

入力された行動要素を分類してから数値として記録する(_記録ならび) :-
        findall([_年,_月,_日,_記録,_購入物,_金額]),
           ( 入力文の解析(_文,_解析した文の要素),
                         (  _文=end_of_file,!,fail;
                                要素の分類と記録([本,夕食,朝食,昼食,休日],_解析した文の要素,0,_記録),
                                日付の取得(_解析した文の要素,_年,_月,_日),
                                購入物と金額(_購入物,_金額)
                         ))),
           _記録ならび).

日付の取得(_解析した文の要素,_日付) :-
        member([年,_年],_解析した文の要素),
        member([月,_月],_解析した文の要素),
        member([日,_日],_解析した文の要素),!.

購入物と金額(_解析した文の要素,_購入物,_金額) :-
        member([購入物,_購入物],_解析した文の要素),
        member([金額,_金額],_解析した文の要素),!.
購入物と金額(_,なし,0).

要素の分類と記録(R,_,_数値,_数値) :- !.
要素の分類と記録([_要素|R],_解析した文の要素,_数値1,_数値) :-
        member(_解析した文の要素),
        _要素に対応した加算数字(_要素,_加算数字),
        _数値2 is _数値1 + _加算数字,
        要素の分類と記録(R,_解析した文の要素,_数値2,_数値).

要素に対応する加算数値(朝食,1).
要素に対応する加算数値(昼食,2).
要素に対応する加算数値(夕食,4).
要素に対応する加算数値(本,8).
要素に対応する加算数値(休日,16).

入力文の解析(_文,_解析した文の要素) :- 
        解析上鍵となる言葉(_鍵言葉ならび), 
        sPLIT(_文,_鍵言葉ならび,L1), 
        有意な要素の収集(L1,_解析した文の要素),!. 

有意な要素の収集(L,L1,_解析した文要素) :- 
        member(_出費の分類,[朝食,昼食,夕食,本,休日]), 
        \+(member(_出費の分類,L1)), 
        有意な要素の収集(L,[_出費の分類|L1],_解析した文要素),!. 
有意な要素の収集(L,L1,_解析した文要素) :- 
        member(X,[年,月,日,円], 
        \+(member([X,_],L1)), 
        append(_,[A,X|_],L), 
        '整数か?ただし全角文字は整数に変換する'(A,N), 
        有意な要素の収集(L,[[X,N]|L1],_解析した文要素),!. 
有意な要素の収集(L,L1,_解析した文要素) :- 
        append(L0,[_購入物,を|R],L), 
        \+(member(_購入物,[本,夕食,昼食,朝食,休日])), 
        \+(member([購入物_購入物],L1)), 
        有意な要素の収集(L,[[購入物,_購入物]|L1],_解析した文要素),!. 
有意な要素の収集(_,解析した文要素,_解析した文要素) :- !.  

/*
解析上鍵となる言葉([休日,年,月,日,円,朝食,夕食,昼食,本,は,が,の,に,で,ために,へ,を,買]).
形態素解析(文,'休日の2009年12月11日に朝食で食パンを350円買い',X).
*/
% *** user: '全角文字列整数変換' / 4 ***
'全角文字列整数変換'(E,E,_全角文字列,_整数) :-
        '副文字列'(_全角文字列,E,1,_全角文字),
        '全角文字整数変換'(_全角文字,_整数),!.
'全角文字列整数変換'(N,E,_全角文字列,_整数) :-
        '副文字列'(_全角文字列,N,1,_全角文字),
        '全角文字整数変換'(_全角文字,_整数の一),
        F is E - N,
        _整数の二 'は' trunc(10 ^ F * _整数の一),
        M is N + 1,
        '全角文字列整数変換'(M,E,_全角文字列,_整数の三),
        _整数 'は' _整数の三 + _整数の二,!.

% *** user: '全角文字列整数変換' / 2 ***
'全角文字列整数変換'(_全角文字列,_整数) :-
        '文字列長'(_全角文字列,_文字列長),
        '全角文字列整数変換'(1,_文字列長,_全角文字列,_整数),!.

% *** user: '全角文字整数変換' / 2 ***
'全角文字整数変換'('0',0) :- !.
'全角文字整数変換'('1',1) :- !.
'全角文字整数変換'('2',2) :- !.
'全角文字整数変換'('3',3) :- !.
'全角文字整数変換'('4',4) :- !.
'全角文字整数変換'('5',5) :- !.
'全角文字整数変換'('6',6) :- !.
'全角文字整数変換'('7',7) :- !.
'全角文字整数変換'('8',8) :- !.
'全角文字整数変換'('9',9) :- !.