このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1301553333/470
#   
#  入力ファイル(成績ファイル)の仕様 
#   
#  ファイル名は、ASCII文字で構成されるものとする。 
#  ファイル名の最大長は FILENAME_MAX である(第2回の課題0を参照)。 
#  1行は、「学生番号」、「氏名」、「成績」の順に記述したもので、  
#  各項目の区切り文字は、「タブ('\t')」1個である。 
#  学生番号は、英数字からなる6桁の文字列である。 
#  氏名の文字列長の最大は20バイトとする。 
#  成績は、0〜100までの整数である。 
#  入力は、最大500行と仮定してよい。 
#   
#  出力形式 
#  入力ファイルを読み込み、最初に、成績の最高点と最低点と平均点を出力する。 
#  次に、成績の降順にソートして出力する。各項 目間は、「タブ('\t')」1個で区切る。 
#  平均点は、小数点以下1桁まで出力する。 
#  出力形式は、実行例を参照せよ。 
#  エラー処理 
#  呼出しでファイル名が指定されない場合はエラーとし、「ファイル名を指定してください」と表示し、プログラムを終了する。 
#  指定されたファイルのオープンに失敗した場合に、「ファイルを開けませんでした」と表示し、プログラムを終了する。 
#  今回のプログラムでは、a. b. 以外のエラー処理はしなくてよい。 
# 
#  % cat sample.txt  
#  03888 八 90  
#  03111 一 100  
#  03222 二 30  
#  03666 六 70  
#  03555 五 60  
#  03333 三 80  
#  03777 七 40  
#  03999 九 20  
#  03444 四 50  
#  % ./work31.exe sample.txt  
#  最高点:100  
#  最低点: 20  
#  平均点: 60.0  
#  100 03111 一  
#  90 03888 八  
#  80 03333 三  
#  70 03666 六  
#  60 03555 五  
#  50 03444 四  
#  40 03777 七  
#  30 03222 二  
#  20 03999 九  
#  % 
#   
#  言語はCです 
#  よろしくおねがいします 
# 

program :-
        user_parameters([_ファイル名]),
        '入力ファイルを読み込み、最初に、成績の最高点と最低点と平均点を出力する、次に、成績の降順にソートして出力する。各項 目間は、「タブ(''\\t''[B')」1個で区切る。' (_ファイル名).

'入力ファイルを読み込み、最初に、成績の最高点と最低点と平均点を出力する、次に、成績の降順にソートして出力する。各項 目間は、「タブ(''\\t'')」1個で区切る。'(_ファイル名) :-
        入力ファイルを読み込み(_ファイル名,LL),
        '最初に、成績の最高点と最低点と平均点を出力する'(LL),
        '次に、成績の降順にソートして出力する。各項 目間は、「タブ(''\\t'')」1個で区切る。'(LL).

入力ファイルを読み込み(_ファイル名,LL) :-
        get_lines(_ファイル名,Lines),
        三項ならびに変換(Lines,LL).

三項ならびに変換([],[]) :- !.
三項ならびに変換([Line|R1],[[_成績,_学生番号,_氏名]|R2]) :-
        atom_chars(Line,Chars),
        append(L0,['\t'|L1],['\t'|L2],Chars),
        atom_chars(_学生番号,L0),
        atom_chars(_氏名,L1),
        atom_chars(_成績文字列,L2),
        atom_to_term(_成績文字列,_成績,_),
        三項ならびに変換(R1,R2).

最初に、成績の最高点と最低点と平均点を出力する(LL) :-
        findmax(_成績,
                    append(_,[[_成績,_,_]|_],LL),
                _最高点成績),
        findmin(_成績,
                    append(_,[[_成績,_,_]|_],LL),
                _最低点成績),
        findavg(_成績,
                    append(_,[[_成績,_,_]|_],LL),
                _平均点),
        writef('最高点: %t\n',[_最高点成績]),
        writef('最低点: %t\n',[_最低点成績]),
        writef('平均点: %t\n',[_平均点]),!.

'次に、成績の降順にソートして出力する。各項 目間は、「タブ(''\\t'')」1個で区切る。'(LL) :-
        sort(LL,LL1),
        reverse(LL1,LL2),
        append(_,[L|R],LL2),
        writef('%t\t%t\t%t\t\n',L),
        R = [],!.

% *** user: append / 4 ***
append([],L1,L2,L) :-
        append(L1,L2,L).
append([A|R1],L1,L2,[A|R]) :-
        append(R1,L1,L2,R).

% *** user: findmax / 3 ***
findmax(V,P,Max) :-
        findall(V,P,L),
        max(L,Max).

% *** user: findmin / 3 ***
findmin(V,P,Max) :-
        findall(V,P,L),
        min(L,Max).

% *** user: findavg / 3 ***
findavg(_集約項,_項,_算術平均) :-
        findall(_集約項,_項,_値ならび),
        sum(_値ならび,_合計値),
        length(_値ならび,_ならびの長さ),
        _算術平均 is _合計値 / _ならびの長さ,!.

% *** user: sum / 2 ***
sum([],0).
sum([N|R],S) :-
        sum(R,S1),
        S is N + S1.