このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1272006124/192
#  <問題> 
#  選手の成績順のリストと、一位からの入賞賞金のリストがあります。一位から 
#  順に賞金を賦与するのですが、入賞者の中で同順位があった場合はその順位の 
#  賞金と一つ下位の賞金の合計を両者で分け合います。さらに多くの同順位者が 
#  いた場合は、同様に下位の賞金を合計していって、同順位者で分け合います。 
#  下位の入賞者が多数いて入賞者数を超えてしまったら、該当する全員を入賞扱い 
#  として一番下位の賞金を分け合うこととします。 
#  このような3引数の述語 入賞賞金賦与を定義しなさい。 
# 
# 

入賞賞金賦与([],[],[]) :- !.
入賞賞金賦与([[_名前1,_成績1],[_名前2,_成績2]|R1],[_賞金額|R2],[[_名前1,_成績1,_賞金額]|R3]) :-
        同一順位者がいない場合は賞金額をそのまま賦与(_成績1,_成績2,R1,R2,R3),!.
入賞賞金賦与(_成績順ならび,_賞金額ならび,_入賞賞金賦与ならび) :-
        同一順位者がいる場合は賞金を等分する(_同一順位者ならび,_賞金額ならび,_残りならび,_残り賞金額ならび,_入賞賞金賦与ならび_1),
        入賞賞金賦与(_残りならび,_残り賞金額ならび,_入賞賞金賦与ならび_2),
        append(_入賞賞金賦与ならび_1,_入賞賞金賦与ならび_2,_入賞賞金賦与ならび),!.

同一順位者がいない場合は賞金額をそのまま賦与(_成績1,_名前2,_成績2,R1,R2,R3) :-
        \+(_成績1 = _成績2),
        入賞賞金賦与([[_名前2,_成績_2]|R1],R2,R3),!.

同一順位者を得る(_成績順ならび,[[A,_成績1]|R1]) :-
        append([[A,_成績1]|R1],[[B,_成績2]|R2],_成績順ならび),
        \+(_成績1 = _成績2),!.

同一順位者がいる場合は賞金を等分する(_成績順ならび,_賞金額ならび,_残りならび,_残り賞金額ならび,_入賞賞金賦与ならび_1) :-
        同一順位者を得る(_成績順ならび,_同一順位者ならび,_残りならび),
        length(_同一順位者ならび,_同一順位者の数),
        賞金を等分する(_同一順位者ならび,_同一順位者の数,_平均賞金額,_残り賞金額ならび),
        平均賞金額を付加(_同一順位者ならび,_平均賞金額,_入賞賞金賦与ならび_1),!.

賞金を等分する(_同一順位者ならび,_同一順位者の数,_平均賞金額,_残り賞金額ならび) :-
        length(L1,_同一順位者の数),
        append(L1,_残り賞金額ならび,_賞金額ならび),
        平均賞金額(L1,_同一順位者の数,_平均賞金額),!.
賞金を等分する(_同一順位者ならび,_同一順位者の数,_賞金額ならび,_入賞賞金賦与ならび) :-
        平均賞金額(_賞金額ならび,_同一順位者の数,_平均賞金額),!.


平均賞金額(_賞金額ならび,_同一順位者の数,_平均賞金額) :-
        sum(_賞金額ならび,_合計賞金額),
        _平均賞金額 is _合計賞金額 / _同一順位者の数.

平均賞金額を付加(_同一順位者ならび,_平均賞金額,_入賞賞金賦与ならび) :-
        findall([_氏名,_成績,_平均賞金額],(
                    append(_,[[_氏名,_成績]|_],_同一順位者ならび)),
                _入賞賞金賦与ならび).

sum([],0).
sum([N|R],_sum) :-
        sum(R,_sum_1),
        _sum is _sum_1 + N.