このディレクトリの索引
#  http://www.ioi-jp.org/joi/2011/2012-yo/2012-yo-t1/2012-yo-t1.html
#  問題
#  1	    ランチ (Lunch)
#  問題
#  
#  JOI パスタ店では,ランチのおすすめパスタと搾りたてジュースのセットメニューが
#  好評である.このセットメニューを注文するときは,その日の 3 種類のパスタと
#  2 種類のジュースから 1 つずつ選ぶ.パスタとジュースの値段の合計から 50 円を
#  引いた金額が代金となる.
#  
#  ある日のパスタとジュースの値段が与えられたとき,その日のセットメニューの
#  代金の最小値を求めるプログラムを作成せよ.
#  
#  入力
#  
#  入力は 5 行からなり,1 行に 1 つずつ正の整数が書かれている.
#  1 行目の整数は 1 つ目のパスタの値段である.
#  2 行目の整数は 2 つ目のパスタの値段である.
#  3 行目の整数は 3 つ目のパスタの値段である.
#  4 行目の整数は 1 つ目のジュースの値段である.
#  5 行目の整数は 2 つ目のジュースの値段である.
#  ただし,与えられる入力データにおいては全てのパスタとジュースの値段は
#   100 円以上 2000 円以下であることが保証されている.
#  
#  出力
#  
#  その日のセットメニューの代金の最小値を 1 行で出力せよ.
#  
#  入出力例
#  
#  入力例 1	入力例 2
#  800          1999
#  700          1999
#  900           100
#  198           189
#  330           100
#    
#  出力例 1	出力例 2
#  848           150
#  
#     
#  入出力例 1 では,2 つ目のパスタと 1 つ目のジュースを組み合わせた場合の 700 + 198 - 50 = 848 がその日のセットメニューの代金の最小値である.
#  
#  入出力例 2 では,3 つ目のパスタと 2 つ目のジュースを組み合わせた場合の 100 + 100 - 50 = 150 がその日のセットメニューの代金の最小値である.
#  
#  ※各入出力例のデータは,右クリック等によりファイルに保存して利用可能です.
#  

program :-
        'JOI パスタ店では,ランチのおすすめパスタと搾りたてジュースのセットメニューが好評である.このセットメニューを注文するときは,その日の 3 種類のパスタと 2 種類のジュースから 1 つずつ選ぶ.パスタとジュースの値段の合計から 50 円を引いた金額が代金となる.ある日のパスタとジュースの値段が与えられたとき,その日のセットメニューの代金の最小値を求める'.

'JOI パスタ店では,ランチのおすすめパスタと搾りたてジュースのセットメニューが好評である.このセットメニューを注文するときは,その日の 3 種類のパスタと 2 種類のジュースから 1 つずつ選ぶ.パスタとジュースの値段の合計から 50 円を引いた金額が代金となる.ある日のパスタとジュースの値段が与えられたとき,その日のセットメニューの代金の最小値を求める' :-
        '3書類のパスタと2種類のジュースの価格を得る'(_3種類のパスタの価格,_2種類のジュースの価格),
        最小値を探しだす(_セットメニューの代金,(
                    セットメニューを代金を得る(_3種類のパスタの価格,_2種類のジュースの価格,_セットメニューの代金)),
                _その日のセットメニューの代金の最小値),
        writef('%t\n',[_その日のセットメニューの代金の最小値]).

'3書類のパスタと2種類のジュースの価格を得る'(_3種類のパスタの価格,_2種類のジュースの価格) :-
        '3種類のパスタの価格を得る'(_3種類のパスタの価格),
        '2種類のジュースの価格を得る'(_2種類のジュースの価格).

'3種類のパスタの価格を得る'(_3種類のパスタの価格) :-
        length(_3種類のパスタの価格,3),
        findall(_パスタの価格,(
                    append(_,[_パスタの価格|_],_3種類のパスタの価格),
                    整数入力(_パスタの価格)),
                _3種類のパスタの価格).

'2種類のジュースの価格を得る'(_2種類のジュースの価格) :-
        length(_2種類のジュースの価格,2),
        findall(_ジュースの価格,(  % _パスタの価格となっていた 12/23訂正
                    append(_,[_ジュースの価格|_],_2種類のジュースの価格),
                    整数入力(_ジュースの価格)),
                _2種類のジュースの価格).

最小値を探しだす(_対象となる値,_副目標,_最小値) :-
        findall(_対象となる値,_副目標,L),
        最小値(L,_最小値).

最小値(L,_最小値) :-
        append(L1,[_最小値|L2],L),
        \+((append(_,[A|_],L1),A @< _最小値)),
        \+((append(_,[B|_],L2),B @< _最小値)),!.

セットメニューを代金を得る(_3種類のパスタの価格,_2種類のジュースの価格,_セットメニューの代金) :-
        append(_,[_パスタの価格|_],_3種類のパスタの価格),
        append(_,[_ジュースの価格|_],_2種類のジュースの価格),
        _セットメニューの代金 is _パスタの価格 + _ジュースの価格 - 50.

整数入力(N) :-
        get_line(Line),
        整数入力診断(Line,N),!.
整数入力(N) :-
        整数入力(N).

整数入力診断(Line,N) :-
        atom_to_term(Line,N,_),
        integer(N),!.
整数入力診断(Line,N) :-
        writef('入力された %t からは整数が得られません。再入力をお願いします。\n',[Line]),
        fail.

get_line(Line) :-
        get_char(Char),
        get_line_2(Char,Chars),
        atom_chars(Line,Chars).

get_line_2(end_of_file,[]) :- !.
get_line_2('\n',[]) :- !.
get_line_2(Char,[Char|R]) :-
        get_char(Char2),
        get_line_2(Char2,R).