このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1357748713/33
#  [1] 授業単元:リスト構造  
#  [2] 問題文(含コード&リンク): 
#  http://ime.nu/iup.2ch-library.com/i/i0825590-1357830189.gif  
#  
#  以下のようなメニューを表示,各項目の機能を実現して結果を表示するプログラムを作
成せよ.
#  リストは1つとし,初期値は「15 4 32 1」である.
#  ・データの追加,削除は練習課題(挿入や削除)のものを参考にすればよい.
#  ・データの追加に関して,そのデータはリストの最後に挿入されるものとする.
#  ・データのソート(降順)を行う関数を作成する.
#  ・リストの平均値を計算し出力する関数を作成する。
#  
#  ------表示例------
#  1. データの追加
#  2. データの削除
#  3. データのソート(降順)
#  4. リストの平均値
#  5. 終了
#  何を実行しますか : 
#  ------------------
#  
#  ------実行例-------
#  1. データの追加
#  2. データの削除
#  3. データのソート(降順)
#  4. リストの平均値
#  5. 終了
#  何を実行しますか : 1
#  追加するデータを入力してください : 10
#  リスト : 15 4 32 1 10
#  
#  1. データの追加
#  2. データの削除
#  3. データのソート(降順)
#  4. リストの平均値
#  5. 終了
#  何を実行しますか : 4
#  リストの平均値 : 12.4
#  リスト : 15 4 32 1 10
#  
#  1. データの追加
#  2. データの削除
#  3. データのソート(降順)
#  4. リストの平均値
#  5. 終了
#  何を実行しますか : 3
#  リスト : 32 15 10 4 1
#  

:- dynamic(リスト/1).

'以下のようなメニューを表示,各項目の機能を実現して結果を表示するプログラムを作成せよ.
リストは1つとし,初期値は「15 4 32 1」である.
・データの追加,削除は練習課題(挿入や削除)のものを参考にすればよい.
・データの追加に関して,そのデータはリストの最後に挿入されるものとする.
・データのソート(降順)を行う関数を作成する.
・リストの平均値を計算し出力する関数を作成する。

------表示例------
1. データの追加
2. データの削除
3. データのソート(降順)
4. リストの平均値
5. 終了
何を実行しますか : ' :-
        'リストは1つとし,初期値は「15 4 32 1」である',
        メニューを表示,
        各項目の機能を実現して結果を表示する.

'リストは1つとし,初期値は「15 4 32 1」である' :-
        assertz(リスト([15,4,32,1])).

メニューを表示 :-
        write('1. データの追加\n2. データの削除\n3. データのソート(降順)\n4. リストの平均値\n5. 終了\n何を実行しますか : ').
メニューを表示 :-
        メニューを表示.

各項目の機能を実現して結果を表示する :-
        機能番号を選択する(_機能番号),
        機能を実現して結果を表示する(_機能番号),
        _機能番号 = 5,!.

機能番号を選択する(_機能番号) :-
        get_line(Line),
        '診断:: メニューの選択'(Line,_機能番号),!.
機能番号を選択する(_機能番号) :-
        機能番号を選択する(_機能番号).

'診断:: メニューの選択'(Line,_機能番号) :-
        atom_number(Line,_機能番号),
        integer(_機能番号),
        between(1,5,_機能番号),!.
'診断:: メニューの選択'(Line,_機能番号) :-
        writef('選択された %t からは適切な機能番号が得られません。再入力をお願いします。\n',[Line]),
        fail.

機能を実現して結果を表示する(5) :- !.
機能を実現して結果を表示する(1) :-
        データの追加.
機能を実現して結果を表示する(2) :-
        データの削除.
機能を実現して結果を表示する(3) :-
        'データのソート(降順)'.
機能を実現して結果を表示する(4) :-
        リストの平均値.

データの追加 :-
        write('追加するデータを入力してください : '),
        整数を得る(_データ),
        retract(リスト(L1)),
        append(L1,[_データ],L2),
        assertz(リスト(L2)).

データの削除 :-
        write('削除するデータを入力してください : '),
        整数を得る(_データ),
        retract(リスト(L1)),
        ならびから削除(_データ,L1,L2),
        assertz(リスト(L2)).

'データのソート(降順)' :-
        リスト(L1),
        降順整列(L1,L2),
        atomic_list_concat(L2,' ',S),
        writef('リスト : %t\n',[S]).

リストの平均値 :-
        リスト(L1),
        findavg(_データ,(
                    member(_データ,L1)),
                _平均値),
        atomic_list_concat(L1,_リスト表示),
        writef('平均値 : %t\nリスト : %t\n',[_平均値,_リスト表示]).


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

get_line(Stream,X) :-
        get_char(Stream,C),
        get_line_1(Stream,C,Chars),
        atom_chars(X,Chars).

get_line_1(Stream,'\n',[]) :- !.
get_line_1(Stream,_,[e,n,d,'_',o,f,'_',f,i,l,e]) :-
        at_end_of_stream(Stream),!.
get_line_1(Stream,end_of_file,[e,n,d,'_',o,f,'_',f,i,l,e]) :- !.
get_line_1(Stream,C,[C|R]) :-
        get_char(Stream,C2),
        get_line_1(Stream,C2,R).

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


ならびから削除(_,[],[]) :- !.
ならびから削除(_削除する要素,[_削除する要素|_残り対象ならび],_削除されたならび) :-
        ならびから削除(_削除する要素,_残り対象ならび,_削除されたならび),!.
ならびから削除(_削除する要素,[_要素|_残り対象ならび],[_要素|_残り削除ならび]) :-
        ならびから削除(_削除する要素,_残り対象ならび,_残り削除ならび),!.


降順整列([],[]).
降順整列([_軸要素|R1],_降順に整列されたならび) :-
        降順分割(_軸要素,R,_軸要素に等しいか大きいならび,_軸要素より小さいならび),
        降順整列(_軸要素に等しいか大きいならび,_整列した軸要素に等しいか大きいならび),
        降順整列(_軸要素より小さいならび,_整列した軸要素より小さいならび),
        append(_整列した軸要素に等しいか大きいならび,[_軸要素|_整列した軸要素より小さいならび],_降順に整列したならび).

降順分割(_,[],[],[]).
降順分割(_軸要素,[_要素|R],[_要素|_軸要素に等しいか大きいならび],_軸要素より小さいならび) :-
        _要素 @>= _軸要素,
        降順分割(_軸要素,R,_軸要素に等しいか大きいならび,_軸要素より小さいならび).
降順分割(_軸要素,[_要素|R],_軸要素に等しいか大きいならび,[_要素|_軸要素より小さいならび]) :-
        _要素 @< _軸要素,
        降順分割(_軸要素,R,_軸要素に等しいか大きいならび,_軸要素より小さいならび).

findavg(_集約項,_項,_相加平均) :-
        findall(_集約項,_項,_値ならび),
        sum(_値ならび,_合計値),
        length(_値ならび,_ならびの長さ),
        _相加平均 is _合計値 / _ならびの長さ,!.

sum([],0).
sum([N|R],S) :-
        sum(R,S_1),
        S is N + S_1.