このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1312201995/573
#  [1] 授業単元:プログラミング  
#  [2] 問題文(含コード&リンク):  
#  挿入ソートを乱数配列に対して 100 回実行し, 一回のソートにおける 配列要素の値の比較回数とその平均値を表示するプログラムを作成せよ. また, 以下の機能も加えよ;  
#  1.整数 n, max を scanf で受け取り, 乱数配列の 長さ n と乱数の範囲 ( 1 から max まで )を指定できる. 
#  2.一回のソートにおける比較回数は見やすいように各行 10 個ずつ表示する.  
#   

'挿入ソートを乱数ならびに対して 100 回実行し, 一回のソートにおける ならび要素の値の比較回数とその平均値を表示する' :-
        ならびの長さを得る(_n),
        乱数の最大値を得る(Max),
        '挿入ソートを乱数ならびに対して 100 回実行し, 一回のソートにおける ならび要素の値の比較回数とその平均値を表示する'(1,_n,Max,_比較回数合計,_比較回数平均値),
        writef('比較平均回数: %t\n',[_比較回数平均]),!.

ならびの長さを得る(_n) :-
        write('ならびの長さを入力してください : '),
        get_line(Line),
        ならびの長さ検査(Line,_n),!.
ならびの長さを得る(_n) :-
        ならびの長さを得る(_n).

ならびの長さ検査(Line,_n) :-
        atom_to_term(Line,_n,_),
        interger(_n),!.
ならびの長さ検査(Line,_n) :-
        writef('入力された%tから適切な整数が得られません。再入力をお願いします。\n',[Line]),
        fail.

乱数の最大値を得る(Max) :-
        write('乱数の最大値を入力してください : '),
        get_line(Line),
        乱数の最大値検査(Line,Max),!.
乱数の最大値を得る(Max) :-
        乱数の最大値を得る(Max).

乱数の最大値検査(Line,Max) :-
        atom_to_term(Line,Max,_),
        interger(Max),!.
乱数の最大値検査(Line,Max) :-
        writef('入力された%tから乱数の最大値として適切な整数が得られません。再入力をお願いします。\n',[Line]),
        fail.

'挿入ソートを乱数ならびに対して 100 回実行し, 一回のソートにおける ならび要素の値の比較回数とその平均値を表示する'(N,_n,Max,_比較回数合計,_比較回数平均値) :-
        N > 100,
        _比較回数平均値 is _比較回数合計 / 100,!.
'挿入ソートを乱数ならびに対して 100 回実行し, 一回のソートにおける ならび要素の値の比較回数とその平均値を表示する'(N,_n,Max,_比較回数合計,_比較回数平均値) :-
        乱数ならびを得る(_n,_Max,_乱数ならび),
        比較回数を数えながら挿入整列(_乱数ならび,_整列されたならび,0,_比較回数),
        比較回数の表示(N,_比較回数),
        _比較回数のニ is _比較回数合計 + _比較回数,
        N2 is N + 1,
        '挿入ソートを乱数ならびに対して 100 回実行し, 一回のソートにおける ならび要素の値の比較回数とその平均値を表示する'(N2,_n,Max,_比較回数合計のニ,_比較回数平均値).

乱数ならびを得る(_n,_Max,_乱数ならび) :-
        length(_乱数ならび,_n),
        findall(N,(
                    append(_,[N|_],_乱数ならび),
                    N is random(_Max) + 1),
                _乱数ならび),!.

比較回数を数えながら挿入整列(L1) :-
        比較回数を数えながら挿入整列(L1,[],L2,0,_比較回数),
        writef('整列されたリストは %t 比較回数は %t です。\n',[L2,_比較回数]).

比較回数を数えながら挿入整列([],L,L,_比較回数,_比較回数).
比較回数を数えながら挿入整列([A|R1],L1,L,_比較回数1,_比較回数) :-
        'append挿入'(A,L1,L2,_比較回数2),
        writef('append挿入: %t,%t,%t,%t\n',[A,L1,L2,_比較回数2]),
        _比較回数3 is _比較回数1 + _比較回数2,
        比較回数を数えながら挿入整列(R1,L2,L,_比較回数3,_比較回数).
比較回数を数えながら挿入整列([A|R1],[],L,_比較回数1,_比較回数) :-
        _比較回数2 is _比較回数1 + 1,
        比較回数を数えながら挿入整列(R1,[A],L,_比較回数2,_比較回数).

'append挿入'(A,L1,L,_比較回数) :-
         append(L0,[B|R],L1),
         A < B,
         append(L0,[A,B|R],L),
         length(L0,Len),
         _比較回数 is ((Len * 2) + 1) * 2,!.
'append挿入'(A,L1,L,_比較回数) :-
        append(L1,[A],L),
        length(L1,Len),
        _比較回数 is Len * 2 + 1,!.

比較回数の表示(N,_比較回数) :-
        0 is N mod 10,
        N2 is N + 1,
        writef('%t:%t\n',[N,_比較回数]),!.
比較回数の表示(N,_比較回数) :-
        writef('%t:%t ',[N,_比較回数]),!.