このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1284632294/479
#  [1] 授業単元: プログラミング基礎  
#  [2] 問題文(含コード&リンク):  
#  適正なおつりを出すプログラムを作成しなさい 
#  例として次のようにすること 
#  金額を入力してください。 
#  12345 
#  一万円:1枚 
#  五千円:0枚 
#   千円:2枚 
#  五百円:0枚 
#   百円:3枚 
#  五十円:0枚 
#   十円:4枚  
#   五円:1枚 
#   一円:0枚 
#  
% 現在のProlog仕様の弱点のひとつとして、定義述語データベースの素直な更新(節順序を変えずに
% 値だけ更新すること)ができないということがある。retractされた節はassertaで先頭に追加するか
% assertzで末尾の節として追加する他ない。この課題でも金種金額の大きい順に処理する必要から、
% findall/3で入手したレジの内容のリストを、その都度降順に整列することを余儀なくされている。
%

レジ(10000,7).
レジ(5000,1).
レジ(2000,0).
レジ(1000,9).
レジ(500,2).
レジ(100,20).
レジ(50,6).
レジ(10,14).
レジ(5,1).
レジ(1,30).

適正なおつりを出す(_発生したおつり) :-
        レジの中身をならびに変換(_金種と枚数ならび),
        金種問題(_発生したおつり,_金種と枚数ならび,_おつりの金種と枚数ならび),
        append(_,[[_金種,_枚数]|R],_おつりの金種と枚数ならび),
        金種の漢字表示(_金種,_金種の漢字表示),
        write_formatted('%6s : %t枚\n',[_金種の漢字表示,_枚数]),
        レジの金種残高の更新(_金種,_枚数),
        R = [].

金種問題(0,_,[]) :- !.
金種問題(_残高,[],_) :-
        _残高 > 0,
        write_formatted('レジの小銭が%t円不足しました\n',[_残高]),!,fail.
金種問題(_残高1,[[_金種,_レジの枚数]|R1],[[_金種,_枚数]|R2]) :-
        _枚数 is _残高1 // _金種,
        \+(_枚数=0),
        \+(_レジの枚数=0),
        _枚数 =< _レジの枚数,
        _残高2 is _円 mod _金種,
        金種問題(_残高2,R1,R2).
金種問題(_残高1,[[_金種,_レジの枚数]|R1],[[_金種,_レジの枚数]|R2]) :-
        _枚数 is _残高1 // _金種,
        \+(_枚数=0),
        \+(_レジの枚数=0),
        _枚数 > _レジの枚数,
        _残高2 is _残高1 - _金種 * _レジの枚数,
        金種問題(_残高2,R1,R2).
金種問題(_残高,[_|R1],R2) :-
        金種問題(_残高,R1,R2).

レジの中身をならびに変換(_降順に整列した金種と枚数ならび) :-
        findall([_金種,_レジの枚数],レジ(_金種,_レジの枚数),_金種と枚数ならび),
        金種を降順に整列(_金種と枚数ならび,_降順に整列した金種と枚数ならび).

金種を降順に整列(_金種と枚数ならび,_降順に整列した金種と枚数ならび) :-
        sort(_金種と枚数ならび,_昇順に整列した金種と枚数ならび),
        reverse(_昇順に整列した金種と枚数ならび,_降順に整列した金種と枚数ならび).

レジの金種残高の更新(_金種,_おつりに必要となった枚数) :-
        retract(レジ(_金種,_現在の枚数)),
        _おつりを支払った後の枚数 is _現在の枚数 - _おつりに必要となった枚数,
        assertz(レジ(_金種,_おつりを支払った後の枚数)).

金種の漢字表示(10000,一万円).
金種の漢字表示(5000,五千円).
金種の漢字表示(2000,二千円).
金種の漢字表示(1000,千円).
金種の漢字表示(500,五百円).
金種の漢字表示(100,百円).
金種の漢字表示(50,五十円).
金種の漢字表示(10,十円).
金種の漢字表示(5,五円).
金種の漢字表示(1,一円).