このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1357748713/33
#  [1] 授業単元: リスト処理 
#  [2] 問題文(含コード&) http://codepad.org/3DdhcBUM  
#  
#  /*
#  
#  seito.dat ( http://db.tt/RfFwIKXU )を構造体のリストのセルに(EOFになるまで)入力し、リスト処理による挿入法で得点の降順に整列して表示しなさい。
#  また、整列する際に要素どうしを比較した回数も表示しなさい。
#  
#  【実行例】
#  
#  番号 氏名        得点
#  1021  Machida  Masato   100
#  1017  Nonaka   Fujio     98
#  1011  Suzuki   kenichi   93
#  1019  Fujimoto Kaoru     92
#  1006  kato     Ichiro    91
#   ・         ・     ・
#   ・         ・     ・
#   ・         ・     ・
#  1020  Hoshi    Izumi     32
#  整列の為の比較回数=132回
#  
#  ※長いので実行結果は途中省略しています。
#  ※比較回数はコードによって異なる場合があります。
#  
#  */

'seito.dat ( http://db.tt/RfFwIKXU )を構造体のリストのセルに(EOFになるまで)入力し、リスト処理による挿入法で得点の降順に整列して表示しなさい。
また、整列する際に要素どうしを比較した回数も表示しなさい。' :-
        'seito.dat ( http://db.tt/RfFwIKXU )を構造体のリストのセルに(EOFになるまで)入力し、'(_生徒ならび),
        リスト処理による挿入法で得点の降順に整列して(_生徒ならび,[],_整列済み生徒ならび,0,_比較回数),
        表示しなさい(_整列済み生徒ならび,_比較回数).

'seito.dat ( http://db.tt/RfFwIKXU )を構造体のリストのセルに(EOFになるまで)入力し、'(_生徒ならび) :-
        get_split_lines('seito.dat',[' '],_生徒ならび).


リスト処理による挿入法で得点の降順に整列して([[_学籍番号,_姓,_名,_得点]|R1],L1,_整列済み生徒ならび,_比較回数_1,_比較回数) :-
        降順に挿入(_学籍番号,_姓,_名,_得点,L1,L2,_比較回数_1,_比較回数_2),
        リスト処理による挿入法で得点の降順に整列して(R1,L2,_整列済み生徒ならび,_比較回数_2,_比較回数),!.
リスト処理による挿入法で得点の降順に整列して([],_整列済み生徒ならび,_整列済み生徒ならび,_比較回数,_比較回数).


降順に挿入(_学籍番号,_姓,_名,_得点,[[_学籍番号_1,_姓_1,_名_1,_得点_1]|R],[[_学籍番号,_名,_名,_得点],[_学籍番号_1,_姓_1,_名_1,_得点_1]|R],_比較回数_1,_比較回数) :-
        比較回数 is _比較回数_1 + 1,
        _得点 >= _得点_1,!.
降順に挿入(_学籍番号,_姓,_名,_得点,[[_学籍番号_1,_姓_1,_名_1,_得点_1]|R1],[[_学籍番号_1,_姓_1,_名_1,_得点_1]|R2],_比較回数_1,_比較回数) :-
        降順に挿入(_学籍番号,_姓,_名,_得点,R1,R2,_比較回数_1,_比較回数).
降順に挿入(_学籍番号,_姓,_名,_得点,[],[[_学籍番号,_名,_名,_得点]],_比較回数,_比較回数) :- !.

表示しなさい(_整列済み生徒ならび,_比較回数) :-
        見出しの表示,
        append(_,[[_学籍番号,_姓,_名,_得点]|R],_整列済み生徒ならび),
        整形して表示する(_学籍番号,_姓,_名,_得点),
        R = [],
        writef('整列の為の比較回数=%t回\n',[_比較回数]).

見出しの表示 :-
        write('番号 氏名        得点\n').

整形して表示する(_学籍番号,_姓,_名,_得点) :-
        姓名をそれぞれ8桁に(_姓,_名,_姓文字列,_名文字列),
        得点を頭部空白3桁に(_得点,_得点文字列),
        atomic_list_concat([_学籍番号,_姓文字列,_名文字列,_得点文字列],' ',_表示文字列),
        writef('%t\n',[_表示文字列]).

姓名をそれぞれ8桁に(_姓,_名,_姓文字列,_名文字列) :-
        '8桁に'(_姓,_姓文字列),
        '8桁に'(_名,_名文字列).

'8桁に'(_項,_8桁文字列) :-
        atom_chars(_項,Chars_1),
        length(L,8),
        append(L1,L2,L),
        all(L2,' '),
        atom_chars(_8桁文字列,L).

得点を頭部空白3桁に(_得点,_得点文字列) :-
        number_chars(_得点,Chars),
        length(L,3),
        append(L0,Chars,L),
        all(L0,' '),
        atom_chars(_得点文字列,L).




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

get_split_lines(File,Sep,Lines) :-
        get_lines(File,Lines1),
        findall(Line,(
                   member(A,Lines1),
                   split(A,Sep,Line)),
                Lines).

get_lines(Instream,end_of_file,_,_,[]) :-!.
get_lines(Instream,S,[],_終了検索対象ならび,[S]) :-
        member(A,_終了検索対象ならび),
        検索(S,A),!.
get_lines(Instream,S,[],[],[S|R]) :-
        get_line(Instream,S2),
        get_lines(Instream,S2,[],[],R),!.
get_lines(Instream,S,[],_終了検索対象ならび,[S|R]) :-
        member(A,_終了検索対象ならび),
        \+(検索(S,A)),
        get_line(Instream,S2),
        get_lines(Instream,S2,[],_終了検索対象ならび,R),!.
get_lines(Instream,S,_開始検索対象ならび,_終了検索対象ならび,[S]) :-
        \+(_開始検索対象ならび = []),
        member(A,_開始検索対象ならび),
        検索(S,A),
        member(B,_終了検索対象ならび),
        検索(S,B),!.
get_lines(Instream,S,_開始検索対象ならび,_終了検索対象ならび,[S|R]) :-
        \+(_開始検索対象ならび = []),
        member(A,_開始検索対象ならび),
        検索(S,A),
        !,
        get_line(Instream,S2),
        get_lines(Instream,S2,[],_終了検索対象ならび,R),!.
get_lines(Instream,_,_開始検索対象ならび,_終了検索対象ならび,X) :-
        get_line(Instream,S2),
        get_lines(Instream,S2,_開始検索対象ならび,_終了検索対象ならび,X),!.

get_lines(_ファイル,_スタート行,_最終行,X) :-
        integer(_スタート行),
        integer(_最終行),
        行位置指定選択(_ファイル,_スタート行,_最終行,X).
get_lines(_ファイル,_開始検索対象ならび,_終了検索対象ならび,X) :-
        \+(integer(_開始検索対象ならび)),
        \+(integer(_終了検索対象ならび)),
        open(_ファイル,read,Instream),
        get_line(Instream,S),
        get_lines(Instream,S,_開始検索対象ならび,_終了検索対象ならび,X),
        close(Instream),!.

get_lines(File,Lines) :-
        get_chars(File,L),
        chars_lines(L,Lines),!.

get_lines(Lines) :-
        findall(Line,(
                    repeat,
                    get_line(user_input,Line),
                    (Line = end_of_file , (!) , fail ; true)),
                Lines).

get_line(Instream,X) :-
        get_char(Instream,C),
        get_line_3(Instream,C,Chars),
        atom_chars(X,Chars),!.

get_chars(Instream,end_of_file,[]) :- !.
get_chars(Instream,_,[]) :-
        at_end_of_stream(Instream),!.
get_chars(Instream,X,[X|R]) :-
        get_char(Instream,Y),
        get_chars(Instream,Y,R) .

get_chars(File,L) :-
        \+(is_stream(_,File,_)),
        slush_op(File,File_1),
        exists_file(File_1),
        open(File_1,read,Instream),
        get_char(Instream,X),
        get_chars(Instream,X,L),
        close(Instream),!.
get_chars(Instream,L) :-
        is_stream(_,Instream,_),
        get_char(Instream,X),
        get_chars(Instream,X,L),!.

get_chars(L) :-
        findall(U,(
                    repeat,
                    get_char(U),
                    (U = end_of_file , (!) , fail ; true)),
                L).

get_line(X) :-
        get_line(user_input,X).

get_line_3(_,'\n',[]) :- !.
get_line_3(Instream,_,[]) :-
        at_end_of_stream(Instream),!.
get_line_3(Instream,end_of_file,[]) :- !.
get_line_3(Instream,C,[C|R]) :-
        get_char(Instream,C2),
        get_line_3(Instream,C2,R).

chars_lines([],[],[]) :- !.
chars_lines(['\r'],[],[]) :- !.
chars_lines(['\r',A|R],[],[A|R]) :-
        \+(A = '\n'),!.
chars_lines(['\r','\n'|R],[],R) :- !.
chars_lines(['\n'|R],[],R) :- !.
chars_lines([A|R1],[A|R2],Z) :-
        chars_lines(R1,R2,Z).

chars_lines([],[]) :- !.
chars_lines(L,[A|R2]) :-
        chars_lines(L,U,R),
        atomic_list_concat(U,A),
        chars_lines(R,R2).

split(_文字列,_区切り符号ならび,X) :-
        sPlit(_文字列,_区切り符号ならび,Y),
        findall(U,(
                    member(U,Y),
                    \+(U = '')),
                L),
        L = X,!.

sPlit(_文字列,_区切り符号ならび,X) :-
        atom_chars(_文字列,L),
        split_00(L,_区切り符号ならび,Y),
        findall(U,(
                    member(U,Y) ,
                    \+(member(U,_区切り符号ならび))),
                Z),
        Z = X,!.

split_00(_文字ならび,_区切り符号ならび,X) :-
        findall([B,A],(
                    member(A,_区切り符号ならび) ,
                    atom_chars(A,B)),
                _区切り符号ならびの二),
        split_0(_文字ならび,_区切り符号ならびの二,X).

split_0(_文字ならび,_区切り符号ならび,['',_区切り符号,'']) :-
        member([_区切り文字ならび,_区切り符号],_区切り符号ならび),
        _文字ならび = _区切り文字ならび,!.
split_0(_文字ならび,_区切り符号ならび,['',_区切り符号|R2]) :-
        member([_区切り文字ならび,_区切り符号],_区切り符号ならび),
        append(_区切り文字ならび,R,_文字ならび),
        split_1(R,_区切り符号ならび,R2),!.
split_0(L,_区切り符号ならび,X) :-
        split_1(L,_区切り符号ならび,X).

split_1([],_,[]) :- !.
split_1(_文字ならび,_区切り符号ならび,['',_区切り符号,'']) :-
        member([_区切り文字ならび,_区切り符号],_区切り符号ならび),
        _文字ならび = _区切り文字ならび,!.
split_1(_文字ならび,_区切り符号ならび,['',_区切り符号_1,C,_区切り符号_2|X]) :-
        member([_区切り文字ならび,_区切り符号_1],_区切り符号ならび),
        append(_区切り文字ならび,R,_文字ならび),
        split_2(R,R2,_区切り符号_2,_区切り符号ならび,B),
        split_5(B,C),
        split_0(R2,_区切り符号ならび,X),!.
split_1(_文字ならび,_区切り符号ならび,[C|X]) :-
        split_2(_文字ならび,R2,_区切り符号,_区切り符号ならび,B),
        _区切り符号 = '',
        split_5(B,C),
        split_0(R2,_区切り符号ならび,X),!.
split_1(_文字ならび,_区切り符号ならび,[C,_区切り符号|X]) :-
        split_2(_文字ならび,R2,_区切り符号,_区切り符号ならび,B),
        \+(_区切り符号 = ''),
        split_5(B,C),
        split_0(R2,_区切り符号ならび,X),!.

split_2([],[],'',_,[]) :- !.
split_2(_文字ならび,R,_区切り符号,_区切り符号ならび,[]) :-
        member([_区切り文字ならび,_区切り符号],_区切り符号ならび),
        append(_区切り文字ならび,R,_文字ならび),!.
split_2([''''|R],R2,_区切り符号,_区切り符号ならび,X) :-
        split_3([''''|R],R2,_区切り符号,_区切り符号ならび,X),!.
split_2(['"'|R],R2,_区切り符号,_区切り符号ならび,X) :-
        split_32(['"'|R],R2,_区切り符号,_区切り符号ならび,X),!.
split_2([_文字|R],R2,_区切り符号,_区切り符号ならび,[_文字|X]) :-
        split_2(R,R2,_区切り符号,_区切り符号ならび,X),!.

split_3(['''',''''|R],R2,_区切り符号,_区切り符号ならび,[''''|X]) :-
        split_4(R,R2,_区切り符号,_区切り符号ならび,X),!.
split_3([_|R],R2,_区切り符号,_区切り符号ならび,X) :-
        split_4(R,R2,_区切り符号,_区切り符号ならび,X),!.

split_4(['''',''''|R],R2,_区切り符号,_区切り符号ならび,[''''|X]) :-
        split_4(R,R2,_区切り符号,_区切り符号ならび,X),!.
split_4([''''|R],R2,_区切り符号,_区切り符号ならび,X) :-
        split_2(R,R2,_区切り符号,_区切り符号ならび,X),!.
split_4([],[],'',_,[]) :- !.

split_4([_文字|R],R2,_区切り符号ならび,[_文字|X]) :-
        split_4(R,R2,_区切り符号,_区切り符号ならび,X),!.

split_5([],'') :- !.
split_5(B,C) :-
        numeric_list(B,Nl),
        C number Nl,!.
split_5(B,C) :-
        atomic_list_concat(B,C),!.

all([],_).
all([V|R],V) :-
        all(R,V).

検索(_文字列,_副文字列) :-
        atom_length(_文字列,_文字列の文字数),
        atom_length(_副文字列,_副文字列の文字数),
        Max is _文字列の文字数 - _副文字列の文字数,
        between(0,Max,N),
        sub_atom(_文字列,N,_副文字列の文字数,_副文字列),!.

行位置指定選択(_ファイル,_選択先頭行,_選択最終行,X) :-
        wc(_ファイル,[[_行,_,_,_]]),
        _行数_1 is _行 - _選択先頭行 + 1,
        _行数_2 is _選択最終行 - _選択先頭行,
        atomic_list_concat(['tail -',_行数_1,' ',_ファイル,' | head -',_行数_2],S),
        shs(S,X).

wc(F,X) :-
        exists_file(F1),
        atomic_list_concat(['wc ',F1],S),
        sh(S,X),!.
wc(F,X) :-
        atomic_list_concat([F,' | wc'],S),
        sh(S,X),!.

sh(Command,X) :-
        shs(Command,Y),
        findall(U,(member(V,Y) , make_list(V,[' ',','],U)),X).

shs(Command,X) :-
        popen(Command,L),
        shs_3(L,X).

shs_3(L,[S|R]) :-
        append(L0,['\n'|R1],L),
        atom_chars(S,L0),
        shs_3(R1,R).
shs_3([],[]) :- !.
shs_3(L,[S]) :-
        atom_chars(S,L).

system(Command,X) :-
        shell(Command,X).

system(Command) :-
        shell(Command).

popen(Command,Chars) :-
        open(pipe(Command),read,Instream),
        get_char(Instream,Char),
        popen(Instream,Char,Chars),
        close(Instream),!.

popen(Instream,end_of_file,[]) :- !.
popen(Instream,_,[]) :-
        at_end_of_stream(Instream),!.
popen(Instream,Char,[Char|R]) :-
        get_char(Instream,Char2),
        popen(Instream,Char2,R).