このディレクトリの索引

#  問4
#  
#  以下のプログラムを作成せよ.
#  
#  入力
#      正整数n,ならびにn個の名前と電話番号の組,および文字列.
#      ただし,いずれの入力文字列も長さ20以下と仮定して良い. 
#  処理
#      構造体型配列で電話帳を作成し,名前をキーとして,
#      文字列がselectionのときは選択ソート,文字列がbubbleのときは
#      バブルソートをする. 
#  出力
#      名前をキーとして辞書順にソートされた電話帳.同名の人は,どの順序に
#      出力してもよい. 
#  
#  実行例
#  人数 > 2
#  0人目:名前 > bbb
#  電話番号 > 111
#  1人目:名前 > aaa
#  電話番号 > 222
#  
#  文字列 > selection
#  
#  aaa, 222
#  bbb, 111
#  
#  実行例
#  人数 > 5
#  0人目:名前 > Taro
#  電話番号 > 090-111-1111
#  1人目:名前 > Hanako
#  電話番号 > 090-222-2222
#  2人目:名前 > Ichiro
#  電話番号 > 090-333-3333
#  3人目:名前 > Jiro
#  電話番号 > 090-444-4444
#  4人目:名前 > Hanayo
#  電話番号 > 090-555-5555
#  
#  文字列 > bubble
#  
#  Hanako, 090-222-2222
#  Hanayo, 090-555-5555
#  Ichiro, 090-333-3333
#  Jiro, 090-444-4444
#  Taro, 090-111-1111

プログラム :-
        入力(_正整数n,_n個の名前ならび,_電話番号の組,_および文字列),
        処理(_文字列,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組),
        出力(_名前をキーとして整列されたn個の名前と電話番号の組).

入力(_正整数n,_n個の名前ならび,_電話番号の組,_および文字列) :-
        '正整数n,ならびにn個の名前と電話番号の組,および文字列.ただし,いずれの入力文字列も長さ20以下と仮定して良い.'(_正整数n,_n個の名前ならび,_電話番号の組,_および文字列).

'正整数n,ならびにn個の名前と電話番号の組,および文字列.ただし,いずれの入力文字列も長さ20以下と仮定して良い.'(_正整数n,_n個の名前ならび電話番号の組,_および文字列) :-
        正整数nの入力(_正整数n),
        n個の名前と電話番号の組の入力(_正整数n,_n個の名前と電話番号の組),
        および文字列の入力(_文字列).

'正整数nの入力'(_正の整数n) :-
        write('正の整数を入力してください : '),
        get_integer(_正の整数n),
        _正の整数n > 0,!.

n個の名前と電話番号の組の入力(_正整数n,_n個の名前と電話番号の組) :-
        length(_n個の名前と電話番号の組,_正整数n),
        findall([_名前,_電話番号],(
                    append(L0,[_|_],_n個の名前と電話番号の組),
                    length([_|L0],_人目),
                    writef('%t人目 : ',[_人目]),
                    名前の入力(_名前),
                    電話番号の入力(_電話番号)),
                _n個の名前と電話番号の組).

名前の入力(_名前) :-
        write('名前を入力してください : '),
        get_line(_名前).

電話番号の入力(_電話番号) :-
        write('電話番号を入力してください : '),
        get_line(_電話番号).

および文字列の入力(_文字列) :-
        write('selection or bubble : '),
        get_line(_文字列).

処理(_文字列,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組) :-
        '名前をキーとして,文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをする.'.(_文字列,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組).

'名前をキーとして,文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをする.'(selection,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組) :-
        選択ソート(_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組).
'名前をキーとして,文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをする.'(bubble,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組) :-
        バブルソート(_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組).

出力(_名前をキーとして整列されたn個の名前と電話番号の組) :-
        '名前をキーとして辞書順にソートされた電話帳.同名の人は,どの順序に出力してもよい.'(_名前をキーとして整列されたn個の名前と電話番号の組).

'名前をキーとして辞書順にソートされた電話帳.同名の人は,どの順序に出力してもよい.'(_名前をキーとして整列されたn個の名前と電話番号の組) :-
        append(_,[[_名前,_電話番号]|R],_名前をキーとして整列されたn個の名前と電話番号の組),
        writef('%t, %t\n',[_名前,_電話番号]),
        R = [].

選択ソート([A],[A]) :- !.
選択ソート(L1,[N|R2]) :-
        append(L0,[N|R],L1),
        \+((member(N1,L0),N1 @> N)),
        \+((member(N2,R),N2 @> N)),
        swap(L0,[N|R],R1),
        選択ソート(R1,R2).

swap([],[N|R],R) :- !.
swap(L0,[N|R],R1) :-
        L0=[S|R0],
        append(R0,[S|R],R1).

バブルソート(_対象ならび,_整列済みならび) :-
        交換(_対象ならび,_対象ならびの一),!,
        バブルソート(_対象ならびの一,_整列済みならび).
バブルソート(_整列済みならび,_整列済みならび).

交換([],[]) :- !,fail.
交換([A,B|R],[B,A|R]) :-
        A @> B,!.
交換([A|R1],[A|R2]) :-
        交換(R1,R2).