このディレクトリの索引

% 以下のサイトは ワンペア(_手札,_ペア数字,_残りの手札) :- 二枚の同位な数字を取り出す(_手札,_ペア数字,_ペア数字,_残りの手札), この数字は残りの手札の中にはない(_ペア数字,_残りの手札), 残りの手札の中に同位数字がない(_残りの手札),!. 二枚の同位な数字を取り出す(_手札,_数字,_数字,_残りの手札) :- 二枚の札を取り出す(_手札,(_数字,_),(_数字,_),_残りの手札). 二枚の札を取り出す(_手札,(_数字_1,_スート_1),(_数字_2,_スート_2),_残りの手札) :- select((_数字_1,_スート_1),_手札,_残りの手札_1), select((_数字_2,_スート_2),_残りの手札_1,_残りの手札). この数字は残りの手札の中にはない(_数字,_残りの手札) :- \+(member((_数字,_),_残りの手札)). 残りの手札の中に同位数字がない(_残りの手札) :- \+(同位数字がある(_残りの手札)). 同位数字がある(_残りの手札) :- select((_同位数字,_),_残りの手札,_残りの手札_1), select((_同位数字,_),_残りの手札_1,_). % 以下のサイトは ハイカード(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- 五枚の数字は(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5), '大きい順に並んでいて、全て異なっている'(_数字_1,_数字_2,_数字_3,_数字_4,_数字_5), スートは二種類以上混じっている(_手札),!. '大きい順に並んでいて、全て異なっている'(_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- 数字順位(L), findall(_数字,( 大きい順に重複しない数字を取り出す(L,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5)), [_数字_1,_数字_2,_数字_3,_数字_4,_数字_5]). 大きい順に重複しない数字を取り出す(L,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- member(_数字,L), select(_数字,[_数字_1,_数字_2,_数字_3,_数字_4,_数字_5],R), \+(member(_数字,R)). ワンペア(_手札,_同位数字,_残りの手札) :- 二枚の同位な数字を取り出す(_手札,_数字,_数字,_残りの手札), この数字は残りの手札の中にはない(_数字,_残りの手札), 残りの手札の中に同位数字がない(_残りの手札),!. 二枚数字を取り出す(_手札,_数字_1,_数字_2,_残りの手札) :- select((_数字_1,_),_手札,_残りの手札_1), select((_数字_2,_),_残りの手札_1,_残りの手札). この数字は残りの手札の中にはない(_数字,_残りの手札) :- \+(member((_数字,_),_残りの手札)). 残りの手札の中に同位数字がない(_残りの手札) :- \+(同位数字がある(_残りの手札)). 同位数字がある(_手札) :- select((_数字,_),_手札,_残りの手札_2), select((_数字,_),_残りの手札_2,_). ツーペア(_手札,_数字_1,_数字_2,_残りの手札) :- 二枚数字を取り出す(_手札,_数字_1,_数字_1,_残りの手札), 二枚数字を取り出す(_残りの手札,_数字_2,[(_数字_3,_)]), '_数字_1と_数字_2は同位でなく、それぞれは_数字_3とも同位ではない'(_数字_1,_数字_2,_数字_3),!. '_数字_1と_数字_2は同位でなく、それぞれは_数字_3とも同位ではない'(_数字_1,_数字_2,_数字_3) :- '_数字_1と_数字_2は同位でなく、'(_数字_1,_数字_2), '_数字_1と_数字_2は_数字_3とも同位でない'(_数字_1,_数字_2,_数字_3). '_数字_1と_数字_2は同位でなく、'(_数字_1,_数字_2) :- \+(_数字_1 = _数字_2). '_数字_1と_数字_2は_数字_3とも同位でない'(_数字_1,_数字_2) :- \+(_数字_3 = _数字_1), \+(_数字_3 = _数字_2). 二枚数字を取り出す(_手札,_数字_1,_数字_2,_残りの手札) :- select((_数字_1,_),_手札,_残りの手札_1), select((_数字_2,_),_残りの手札_1,_残りの手札). 残りの手札に_数字がない(_数字,_残りの手札) :- \+(member((_数字,_),_残りの手札)). 残りの手札に同位数字がない(_残りの手札) :- \+((select((_数字,_),_残りの手札,_残りの手札_2),select((_数字,_),_残りの手札_2,_))). スリーカーズ(_手札,_数字) :- 三枚数字を取り出す(_手札,_数字,_数字,_数字,[(A,_),(B,_)]), 'A,B,_数字はそれぞれ異なる'(_数字,_残りの手札),!. 三枚数字を取り出す(_手札,_数字_1,__数字_2,_数字_3,_残りの手札) :- select((_数字_1,_),_手札,_残りの手札_1), select((_数字_2,_),_残りの手札_1,_残りの手札_2), select((_数字_3,_),_残りの手札_2,_残りの手札). 'A,B,_数字はそれぞれ異なる'(_数字,A,B) :- \+(A = B), '_数字はAでもBでもない'(_数字,_A,B). '_数字はAでもBでもない'(_数字,_A,B) :- \+(_数字 = A), \+(_数字 = B). 'フォー・オブ・ア・カインド'(_手札,_数字) :- 四枚数字を取り出す(_手札,_数字,_数字,_数字,_数字,_残りの手札),!. 五枚数字を取り出す(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- select((_数字_1,_),_手札,_残りの手札_1), select((_数字_2,_),_残りの手札_1,_残りの手札_2), select((_数字_3,_),_残りの手札_2,_残りの手札_3), select((_数字_4,_),_残りの手札_3,_残りの手札_4), select((_数字_5,_),_残りの手札_4,_). 四枚数字を取り出す(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_残りの手札) :- select((_数字_1,_),_手札,_残りの手札_1), select((_数字_2,_),_残りの手札_1,_残りの手札_2), select((_数字_3,_),_残りの手札_2,_残りの手札_3), select((_数字_4,_),_残りの手札_3,_残りの手札). フルハウス(_手札,_3枚の数字,_2枚の数字) :- 三枚の数字と二枚の数字が同位(_手札),!. 三枚の数字と二枚の数字が同位(_手札,_3枚の数字,_2枚の数字) :- 三枚数字を取り出す(_手札,_3枚の数字,_3枚の数字,_3枚の数字,[(_2枚の数字,_),(_2枚の数字,_)]), \+(_数字_1 = _数字_2),!. フラッシュ(_手札,_スート,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- 五枚の数字は(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5), \+(連続している(_数字_1,_数字_2,_数字_3,_数字_4,_数字_5)), 全てのスートが同じ(_手札,_スート),!. ストレート(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- 五枚の数字は連続している(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5), スートは二種類以上混じっている(_手札),!. ストレートフラッシュ(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- 五枚の数字は連続している(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5), 全てのスートが同じ(_手札,_スート),!. 五枚の数字は連続している(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- 五枚の数字は(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5), 連続している(_数字_1,_数字_2,_数字_3,_数字_4,_数字_5),!. 五枚の数字は(_手札,_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- select((_数字_1,_),_手札,_残りの手札_1), select((_数字_2,_),_残りの手札_1,_残りの手札_2), select((_数字_3,_),_残りの手札_2,_残りの手札_3), select((_数字_4,_),_残りの手札_3,_残りの手札_4), select((_数字_5,_),_残りの手札_4,_残りの手札_5). '連続している'(_数字_1,_数字_2,_数字_3,_数字_4,_数字_5) :- 数字の連続(_数字_1,_数字_2), 数字の連続(_数字_2,_数字_3), 数字の連続(_数字_3,_数字_4), 数字の連続(_数字_4,_数字_5),!. スートは二種類以上混じっている(_手札) :- select((_,_スート_1),_手札,_残りの手札_1), select((_,_スート_2),_残りの手札_1,_), \+(_スート_1 = _スート_2),!. 全てのスートが同じ(_手札,_スート) :- _手札 = [(_,_スート),(_,_スート),(_,_スート),(_,_スート),(_,_スート)]. 数字の連続('A','2'). 数字の連続('2','3'). 数字の連続('3','4'). 数字の連続('4','5'). 数字の連続('5','6'). 数字の連続('6','7'). 数字の連続('7','8'). 数字の連続('8','9'). 数字の連続('9','10'). 数字の連続('10','J'). 数字の連続('J','Q'). 数字の連続('Q','K'). 数字の連続('K','A'). 数字順位(['A','K','Q','J','10','9','8','7','6','5','4','3','2']). % 以下のサイトは # 出題場所 :: http://peace.2ch.net/test/read.cgi/tech/1392388003/740 # [1] 授業単元: プログラミング基礎 # [2] 問題文、ブラックジャックの判定処理を行う # 1人目の数字列を入力(1個〜10個まで) # 2人目の数字列を入力(1個〜10個まで) # 数字は、1から13。 # 合計が21を超えたら点数は、0点。 # 1は、1点または、11点として使える。 # 11以上は10点として数える。 # それ以外は、数字がそのまま点数。 # 勝った方を番号で表示(1 or 2) # 引き分けは、2の勝ちとする # 実行例) # 1 5 8 入力1(14) # 5 7 4 入力2(16) # 2 出力 # 13 1 入力1(21) # 12 10 入力2(20) # 1 出力 # 13 8 入力1(18) # 1 9 入力2(20) # 2 出力 # 1 1 8 入力1(20) # 3 4 7 入力2(14) # 1 出力 # 10 8 7 入力1(25) # 3 5 8 入力2(16) # 2 出力 # 'ブラックジャックの判定処理を行う 合計が21を超えたら点数は、0点。 1は、1点または、11点として使える。 11以上は10点として数える。 それ以外は、数字がそのまま点数。 勝った方を番号で表示(1 or 2) 引き分けは、2の勝ちとする' :- ブラックジャックの札を配る(_1人目の数字ならび,_2人目の数字ならび), '合計が21を超えたら点数は、0点。 1は、1点または、11点として使える。 11以上は10点として数える。 それ以外は、数字がそのまま点数。'(_1人目の数字ならび,_2人目の数字ならび,_点数_1,_点数_2), ブラックジャックの判定(_点数_1,_点数_2,_勝者), 勝った方を番号で表示(_勝者). ブラックジャックの札を配る(_1人目の数字ならび,_2人目の数字ならび) :- カードの準備(_配り札_1), ブラックジャックの札を配る(_配り札_1,[],_1人目の数字ならび,_配り札_2), ブラックジャックの札を配る(_配り札_2,[],_2人目の数字ならび,_),!. カードの準備(_配り札) :- findall(N,( between(1,13,N), between(1,4,_)), _配り札). ブラックジャックの札を配る(_配り札,_数字ならび,_数字ならび,_配り札) :- 合計点の最高(_数字ならび,_合計点の最高), between(14,21,_合計点の最高),!. ブラックジャックの札を配る(_配り札_1,_現在までの数字ならび,_数字ならび,_残り配り札) :- 一枚配る(_配り札_1,_数字,_配り札_2), ブラックジャックの札を配る(_配り札_2,[_数字|_現在までの数字ならび],_数字ならび,_残り配り札). 一枚配る(_配り札_1,_数字,_配り札_2) :- length(_配り札_1,_配り札の枚数), _抜き位置 is random(_配り札の枚数), length(L1,_抜き位置), append(L1,[_数字|L2],_配り札_1), append(L1,L2,_配り札_2). '合計が21を超えたら点数は、0点。 1は、1点または、11点として使える。 11以上は10点として数える。 それ以外は、数字がそのまま点数。'(_1人目の数字ならび,_2人目の数字ならび,_点数_1,_点数_2) :- 合計点の最高(_1人目の数字ならび,_点数_1), 合計点の最高(_2人目の数字ならび,_点数_2). 合計点の最高(_数字ならび,_合計点の最高) :- findall(_合計点,( 合計点(_数字ならび,_合計点)), _合計点ならび), findmax(_合計点,( member(_合計点,_合計点ならび), _合計点 =< 21), _合計点の最高),!. 合計点の最高(_,0). 合計点([],0). 合計点([N|R],S) :- 合計点(R,S_2), 点数の数え方(N,N_2), S is N_2 + S_2. 点数の数え方(1,1). 点数の数え方(1,11). 点数の数え方(11,10). 点数の数え方(12,10). 点数の数え方(13,10). 点数の数え方(N,N) :- between(2,10,N). ブラックジャックの判定(_点数_1,_点数_2,2) :- _点数_2 >= _点数_1,!. ブラックジャックの判定(_,_,1). 勝った方を番号で表示(_勝者) :- writef('勝ったのは %t です\n',[_勝者]). % 以下のサイトは # 出典 :: C言語の宿題片付けます 160代目 #400 # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク): http://ime.nu/codepad.org/QdOnaWYm # # /* # ビンゴゲームを作る # # 仕様 # ・5×5のビンゴカードをint型の2次元配列として宣言する # ・ビンゴカードの数字は重複しない1〜100の乱数を作り、それから先頭の25個をビンゴカードに適用 # ・最初にビンゴカード作成に使うための重複しない100個の乱数を見やすい形で表示 # ・値を交換する処理は関数化する # ・実際のビンゴゲームのようにガラガラで1つずつ数字が出てくる # ・ガラガラは1〜100までの重複しない乱数を作る機械であり、ビンゴカード作成に用いた乱数列とガラガラで使う乱数列は別物である # ・ビンゴカード作成用の乱数とガラガラ用の乱数はヒープ領域に確保した配列に格納 # ・カードの縦、横、斜めのいずれかがそろったらゲーム終了 # */ # :- dynamic(賞品/1). ビンゴ参加者(ケイスケ). ビンゴ参加者(ユウヤ). ビンゴ参加者(タダシ). ビンゴ参加者(マッチ). ビンゴ参加者(トオル). 賞品('フェラーリ(模型)'). 賞品('コルト45(模型)'). 賞品(ティー野球セット). 賞品(武豊の使っていた鞭). 賞品(ビンゴセット). ビンゴゲーム :- findall(_ビンゴ参加者,ビンゴ参加者(_ビンゴ参加者),_ビンゴ参加者ならび), ビンゴゲーム(_ビンゴ参加者ならび). ビンゴゲーム(_ビンゴ参加者ならび) :- ゲーム参加者のビンゴカード(_ビンゴ参加者ならび,_ビンゴカードならび), 'ガラガラは1〜100までの重複しない乱数を作る機械であり、ビンゴカード作成に用いた乱数列とガラガラで使う乱数列は別物である'(_ガラガラで使う乱数列), 参加者全員がビンゴとなるまでガラガラを繰り返す(_ビンゴカードならび,_ガラガラで使う乱数列). 参加者全員がビンゴとなるまでガラガラを繰り返す([],_) :- write('ビンゴ終了\nご苦労さまでした\n'),!. 参加者全員がビンゴとなるまでガラガラを繰り返す(_参加者ビンゴカードならび,L2) :- ガラガラ(L1,_数,L2), ビンゴになったカードを探し賞品を渡してそのカードを削除(_数,_参加者ビンゴカードならび,_ビンゴになった人を削除した参加者ビンゴカードならび), 参加者全員がビンゴとなるまでガラガラを繰り返す(_ビンゴになった人を削除した参加者ビンゴカードならび,L2). '5×5のビンゴカードをint型の2次元配列として宣言する'(_ビンゴカード) :- length(_ビンゴカード,5), findall(L,( member(L,_ビンゴカード), length(L,5)), _ビンゴカード). ゲーム参加者のビンゴカード(_ビンゴ参加者ならび,_ビンゴカードならび) :- findall([_ビンゴ参加者,_ビンゴカード],( member(_ビンゴ参加者,_ビンゴ参加者ならび), 'ビンゴカードの数字は重複しない1〜100の乱数を作り、それから先頭の25個をビンゴカードに適用'(_ビンゴカード)), _ビンゴカードならび). 'ビンゴカードの数字は重複しない1〜100の乱数を作り、それから先頭の25個をビンゴカードに適用'(_ビンゴカード) :- 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(L), それから先頭の25個をビンゴカードに適用(L,_ビンゴカード). 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(L) :- findall(N,between(1,100,N),L1), 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(100,L1,L). 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(0,_,[]) :- !. 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(Nth,L1,[N|R2]) :- '重複しない1〜100の乱数'(Nth,L1,N,L2), Nth_1 is Nth - 1, 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(Nth_1,L2,R2). '重複しない1〜100の乱数'(Nth,L1,N,L2) :- Nth0 is random(Nth), length(L0,Nth0), append(L0,[N|R1],L1), append(L0,R1,L2),!. それから先頭の25個をビンゴカードに適用(L,_ビンゴカード) :- ビンゴカード(_重複しない100個の乱数ならび,_ビンゴカード). ビンゴカード(_重複しない100個の乱数ならび,_ビンゴカード) :- _ビンゴカード=[[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]], flatten(_ビンゴカード,_重複しない100個の乱数ならび). 'ガラガラは1〜100までの重複しない乱数を作る機械であり、ビンゴカード作成に用いた乱数列とガラガラで使う乱数列は別物である'(_ガラガラで使う乱数列) :- 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(_ガラガラで使う乱数列),!. ビンゴになったカードを探し商品を渡してそのカードを削除(_,[],[]). ビンゴになったカードを探し商品を渡してそのカードを削除(_数字,[[_ビンゴ参加者,_ビンゴカード_1]|R1],R2) :- 一致した数字があったら穴をあける(_数字,_ビンゴ参加者,_ビンゴカード_1,_ビンゴカード_2), ビンゴだったら賞品を渡してその人は上がり(_ビンゴカード_2,_ビンゴ参加者,R1,R2), ビンゴになったカードを探し賞品を渡してそのカードを削除(_数字,R1,R2),!. ビンゴだったら賞品を渡してその人は上がり(_ビンゴカード,_ビンゴ参加者,R,R) :- ビンゴ(_ビンゴカード), 賞品を渡す(_ビンゴ参加者),!. ビンゴだったら賞品を渡してその人は上がり(_ビンゴカード,_ビンゴ参加者,R,[[_ビンゴ参加者,_ビンゴカード]|R]) :- \+(ビンゴ(_ビンゴカード)). 一致した数字があったら穴をあける(_数字,_ビンゴカード_1,_ビンゴカード_2) :- findall(L2,( member(L,_ビンゴカード_1), 一致した場合だけ穴を開ける(_数字,L,L2)), _ビンゴカード_2). 一致した場合だけ穴を開ける(_数字,L,L2) :- append(L0,[_数字|R],L), append(L0,[穴|R],L2),!. 一致した場合だけ穴を開ける(_,L,L). ビンゴ([穴,_,_,_,_],[_,穴,_,_,_,_],[_,_,穴,_,_],[_,_,_,穴,_],[_,_,_,_,穴]) :- !. ビンゴ([_,_,_,_,穴],[_,_,_,穴,_],[_,_,穴,_,_],[_,穴,_,_,_,_],[穴,_,_,_,_]) :- !. ビンゴ(_ビンゴカード) :- member(L,_ビンゴカード), all(L,穴),!. ビンゴ(_ビンゴカード) :- 転置(_ビンゴカード,_ビンゴカード_2), member(L,_ビンゴカード_2), all(L,穴),!. 賞品を渡す(_参加者) :- retract(賞品(_賞品)), writef('%t君はビンゴになりました。賞品は %t です!\n',[_参加者,_賞品]),!. all([],_). all([A|R],A) :- all(R,A). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1349527750/165 # # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク): http://ime.nu/codepad.org/YKwOhX0L # # /* # ・仕様 # ・配るカードは13枚 # ・スートはSuiteという列挙体で定義され、Spade(スペード)、Club(クラブ)、Heart(ハート) # Dia(ダイア)という定数を持つ # ・カードはCARDという構造体で定義され、Suite列挙体のsuiteと、カードのランクを表す # int型のrankという2つのメンバを持つ # ・カードは配列 # ・13枚のカードのスートとランクは乱数で決定。現実にはありえないカードの配り方 # になってもよい(例:13枚の中にスペードのエースが5枚ある等) # ・スートはスペード→ハート→クラブ→ダイヤの順にソートし、ランクは小さい順(1,2,3,…13) # にソート、またランクよりもスートを優先 # 例:4枚のカードの内訳がスペードの2と5、ハートの3、クラブの10なら # スペードの2→スペードの5→ハートの3→クラブの10とソートされる # ・ソートのアルゴリズムはバブルソートを使う # ソートの前とソートの後のカードを表示する # */ '乱数を使ってカードを13枚配りそれをバブルソートする'(_配られたカード,_ソートされたカード) :- '乱数を使ってカードを13枚配り'(_配られたカード), それをバブルソートする(_配られたカード,_ソートされたカード). '乱数を使ってカードを13枚配り'(_配られたカード) :- 'カードを13枚'(_配られたカード), スートとランクを当て嵌める(_配られたカード). 'カードを13枚'(_配られたカード) :- length(_配られたカード,13). スートとランクを当て嵌める(_配られたカード) :- findall([_スート,_ランク],( member(_カード,_配られたカード), スートを決める(_スート), ランクを決める(_ランク)), _配られたカード). スートを決める(_スート) :- _乱数 is random(4), スートを決める(_乱数,_スート). スートを決める(0,スペード). スートを決める(1,ハート). スートを決める(2,クラブ). スートを決める(3,ダイヤ). ランクを決める(_ランク) :- _ランク is random(13) + 1. それをバブルソートする(_配られたカード,_ソートされたカード) :- 'スート・ランク仕様のバブルソート'(_配られたカード,_ソートされたカード). 'スート・ランク仕様のバブルソート'(L1,L2) :- 軽い泡はちょっと浮き上がる(L1,L3), 泡が浮き上がったら最初からやり直す(L3,L2),!. 'スート・ランク仕様のバブルソート'(L,L) :- 浮き上がる泡がなくなったらバブルソート終了. 軽い泡はちょっと浮き上がる(L1,L3) :- append(L0,[_重い泡,_軽い泡|R],L1), 泡の重さを量る(_重い泡,_軽い泡), append(L0,[_軽い泡,_重い泡|R],L3). 泡の重さを量る([_スート_1,_],[_スート_2,_]) :- スート強度(_スート_1,_スート_2),!. 泡の重さを量る([_スート,_ランク_1],[_スート,_ランク_2]) :- _ランク_1 >= _ランク_2. スート強度(_スート_1,_スート_2) :- nth1(N1,[ダイヤ,クラブ,ハート,スペード],_スート_1), nth1(N2,[ダイヤ,クラブ,ハート,スペード],_スート_2), N1 > N2,!. 泡が浮き上がったら最初からやり直す(L3,L2) :- 'スート・ランク仕様のバブルソート'(L3,L2). 浮き上がる泡がなくなったらバブルソート終了. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1349527750/165 # # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク): http://ime.nu/codepad.org/YKwOhX0L # # /* # ・仕様 # ・配るカードは13枚 # ・スートはSuiteという列挙体で定義され、Spade(スペード)、Club(クラブ)、Heart(ハート) # Dia(ダイア)という定数を持つ # ・カードはCARDという構造体で定義され、Suite列挙体のsuiteと、カードのランクを表す # int型のrankという2つのメンバを持つ # ・カードは配列 # ・13枚のカードのスートとランクは乱数で決定。現実にはありえないカードの配り方 # になってもよい(例:13枚の中にスペードのエースが5枚ある等) # ・スートはスペード→ハート→クラブ→ダイヤの順にソートし、ランクは小さい順(1,2,3,…13) # にソート、またランクよりもスートを優先 # 例:4枚のカードの内訳がスペードの2と5、ハートの3、クラブの10なら # スペードの2→スペードの5→ハートの3→クラブの10とソートされる # ・ソートのアルゴリズムはバブルソートを使う # ソートの前とソートの後のカードを表示する # */ '乱数を使ってカードを13枚配りそれをバブルソートする'(_配られたカード,_ソートされたカード) :- '乱数を使ってカードを13枚配り'(_配られたカード), それをバブルソートする(_配られたカード,_ソートされたカード). '乱数を使ってカードを13枚配り'(_配られたカード) :- 'カードを13枚'(_配られたカード), スートとランクを当て嵌める(_配られたカード). 'カードを13枚'(_配られたカード) :- length(_配られたカード,13). スートとランクを当て嵌める(_配られたカード) :- findall([_スート,_ランク],( member(_カード,_配られたカード), スートを決める(_スート), ランクを決める(_ランク)), _配られたカード). スートを決める(_スート) :- _乱数 is random(4), スートを決める(_乱数,_スート). スートを決める(0,スペード). スートを決める(1,ハート). スートを決める(2,クラブ). スートを決める(3,ダイヤ). ランクを決める(_ランク) :- _ランク is random(13) + 1. それをバブルソートする(_配られたカード,_ソートされたカード) :- 'スート・ランク仕様のバブルソート'(_配られたカード,_ソートされたカード). 'スート・ランク仕様のバブルソート'(L1,L2) :- 軽い泡はちょっと浮き上がる(L1,L3), 泡が浮き上がったら最初からやり直す(L3,L2),!. 'スート・ランク仕様のバブルソート'(L,L) :- 浮き上がる泡がなくなったらバブルソート終了. 軽い泡はちょっと浮き上がる(L1,L3) :- append(L0,[_重い泡,_軽い泡|R],L1), 泡の重さを量る(_重い泡,_軽い泡), append(L0,[_軽い泡,_重い泡|R],L3). 泡の重さを量る([_スート_1,_],[_スート_2,_]) :- スート強度(_スート_1,_スート_2),!. 泡の重さを量る([_スート,_ランク_1],[_スート,_ランク_2]) :- _ランク_1 >= _ランク_2. スート強度(_スート_1,_スート_2) :- nth1(N1,[ダイヤ,クラブ,ハート,スペード],_スート_1), nth1(N2,[ダイヤ,クラブ,ハート,スペード],_スート_2), N1 > N2,!. 泡が浮き上がったら最初からやり直す(L3,L2) :- 'スート・ランク仕様のバブルソート'(L3,L2). 浮き上がる泡がなくなったらバブルソート終了. % 以下のサイトは 分数の計算と表示 :- 分数を2項読み込む([一,分子,一,分母,二,分子,二,分母],[_分子_1,_分母_1,_分子_2,_分母_2]), _答え仮分数分子 is _分子_1 * _分母_2 + _分子_2 * _分母_1, _答え仮分数分母 is _分母_1 * _分母_2, 最大公約数(_答え仮分数分子,_答え仮分数分母,_最大公約数), _答え仮分数分子_2 is _答え仮分数分子 // _最大公約数, _答え仮分数分母_2 is _答え仮分数分母 // _最大公約数, 帯分数(_答え仮分数分子_2,_答え仮分数分母_2,_答え整数部分, _答え分子,_答え分母), 分数計算表示(_分子_1,_分子_2,_答え分子,_答え整数部分,_分母_1,_分母_2,_答え分母). 分数を2項読み込む([],[]). 分数を2項読み込む([A,B|R1],[C|R2]) :- writef('第%t項の%tを整数で入力してください : ',[A,B]), get_integer(C), 分数を2項読み込む(R1,R2). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, \+(_答えの分子=0), writef(' %2r %2r %2r \n',[_分子_1,_分子_2,_答え分子]), writef('---- + ---- =%2r---- \n',[_整数部分]), writef(' %2r %2r %2r \n',[_分母_1,_分母_2,_答え分母]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, 答えの分子=0, writef(' %2r %2r\n',[_分子_1,_分子_2]), writef('---- + ---- = %2r \n',[_整数部分]), writef(' %2r %2r\n',[_分母_1,_分母_2]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 = 0, writef(' %2r %2r %2r \n',[_分子_1,_分子_2,_答え分子]]), write('---- + ---- = ---- \n'), writef(' %2r %2r %2r \n',[_分母_1,_分母_2,_答え分子]]). 帯分数(_仮分数分子,_仮分数分母,_帯分数整数部分, _帯分数分子,_帯分数分母) :- _帯分数整数部分 is _仮分数分子 // _仮分数分母, _帯分数分子 is _仮分数分子 mod _仮分数分母. _帯分数分母 = _仮分数分母. % 行列の掛算の中での分数 行列の掛算(L1,L2,X) :- 転置(L2,L4), 行列の掛算_1(L1,L4,X). 行列の掛算_1([],_,[]) :-!. 行列の掛算_1([A|R1],L,[S1|R3]) :- 行列の掛算_2(A,L,S1), 行列の掛算_1(R1,L,R3). 行列の掛算_2(_,[],[]) :-!. 行列の掛算_2(A,[B|R2],[C|R3]) :- 行列の掛算_3(A,B,C), 行列の掛算_2(A,R2,R3). 行列の掛算_3([],[],0) :-!. 行列の掛算_3([A|R1],[B|R2],S) :- 分数を含む掛算(A,B,S1), 行列の掛算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 分数を含む掛算(A1 / A2,B1 / B2,C) :- S1 is A1 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む掛算(A1 / A2,B,C) :- S1 is A1 * B, 約分(S1 / A2,C),!. 分数を含む掛算(A,B1 / B2,C) :- S1 is B1 * A, 約分(S1 / B2,C),!. 分数を含む掛算(A,B,C) :- C is A * B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % get_numberのなかでの分数 get_number(_数値) :- get_line(Line), get_number_診断(Line,_数値),!. get_number(_数値) :- get_number(_数値). get_number_診断(Line,_数値,_) :- atom_to_term(Line,_数値,_), 数値か(_数値),!. get_number_診断(Line,_数値,_) :- writef('入力された %t からは数値が得られません。再入力をお願いします。\n',[Line]), fail. 数値か(_分子/_分母) :- integer(_分子), integer(_分母),!. 数値か(_数値) :- number(_数値). % '1/3 + 3/5 + 7/9 + 9/11 + 11/13+..........+95/97 + 97/99 を合計する' :- 分子ならび(_分子ならび), 分母ならび(_分母ならび), 分子(_分子ならび,_分母ならび,_分子), 分母(_分母ならび,_分母), _合計 is _分子 / _分母, writef('合計は %t です\n',[_合計]). 分子([N],_分母ならび,_分子) :- '重複のないならびからNを取り除く'(N,_分母ならび,L), 全てを掛ける([N|L],_分子),!. 分子([N|R1],_分母ならび,_分子) :- '重複のないならびからNを取り除く'(N,_分母ならび,L), 全てを掛ける(L,_分子_1), 分子式(R1,_分母ならび,_分子_2), _分子 is _分子_1 + _分子_2. 分子ならび(_分子ならび) :- findall(N,( for(1,N,97), 1 is N mod 2), _分子ならび). 分母([X],X) :- !. 分母([A|R],_分母) :- 分母(R,_分母_1) _分母 is A * _分母_1. 分母ならび(_分母ならび) :- findall(N,( for(3,N,99), 1 is N mod 2), _分母ならび). '重複のないならびからNを取り除く'(N,L,R) :- append(L0,[N|R1],L), append(L0,R1,R),!. % 分数の加算 分数の加算(_分子1/_分母1,_分子2/_分母2,_分子/_分母) :- A is _分母1 * _分母2, B is _分子1 * _分母2 + _分子2 * _分母1, 約分(B/A,_分子/_分母). 約分(B/A,_分子/_分母) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C. % 荷重移動平均 加重移動平均(_データならび,_サンプル数,_加重移動平均) :- reverse(_データならび,_反転したデータならび), length(L0,_サンプル数), append(L0,L1,_反転したデータならび), _分母 is _サンプル数 * (_サンプル数 + 1) / 2, 加重移動平均分子の計算(_サンプル数,L0,_分子), _加重移動平均 is _分子 / _分母,!. 加重移動平均分子の計算(_,[],0) :- !. 加重移動平均分子の計算(N,[A|R],S) :- N1 is N - 1, V is A * N, 加重移動平均分子の計算(N1,R,S1), S is S1 + V. % '2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求める'(_確率) :- '左からi番目のカードに書かれた数がi以上の度数'(1,2,0,0,_分子,_分母), \+(_分母 = 0), _確率 is _分子 / _分母,!. '左からi番目のカードに書かれた数がi以上の度数'(5,_カード,X,Y,X,Y) :- _カード > 6,!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード > 6, _i2 is _i + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i2,2,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分子2 is _分子1 + 1, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母2,_分子,_分母),!. '2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求める'(_確率) :- '左からi番目のカードに書かれた数がi以上の度数'(1,2,0,0,_分子,_分母), \+(_分母 = 0), _確率 is _分子 / _分母,!. '左からi番目のカードに書かれた数がi以上の度数'(5,_カード,X,Y,X,Y) :- _カード > 6,!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード > 6, _i2 is _i + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i2,2,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分子2 is _分子1 + 1, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母2,_分子,_分母),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/190 # # [1] 授業単元:プログラミング # [2] 問題文: # 1つの整数n(但しn>=1)を入力するとn!を返すseki関数を作成する。 # そしてn枚のカードからr枚のカードを選ぶ組み合わせを計算するプログラムを作成しなさい。 # 但し、n≧1、r≧1、n≧rを前提とする。 # :- dynamic('1つの整数n(但しn>=1)を入力するとn!を返す'/2). '1つの整数n(但しn>=1)を入力するとn!を返す'(1,1) :- !. '1つの整数n(但しn>=1)を入力するとn!を返す'(_n,X) :- _n_1 is _n - 1, '1つの整数n(但しn>=1)を入力するとn!を返す'(_n_1,X_1), X is _n * X_1, asserta(('1つの整数n(但しn>=1)を入力するとn!を返す'(_n,X) :- !)),!. 'そしてn枚のカードからr枚のカードを選ぶ組み合わせを計算する'(_n,_r,_組み合わせ数) :- '1つの整数n(但しn>=1)を入力するとn!を返す'(_n,_nの階乗), '1つの整数n(但しn>=1)を入力するとn!を返す'(_r,_rの階乗), Y is _nの階乗 // _rの階乗, _組み合わせ数 is Y // _rの階乗. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/49 # # [1] 授業単元 情報工学 # [2] 問題文 # n枚のカードからr枚のカードを選ぶ組み合わせを計算するプログラムを作成せよ。 # 但し、n≧1  r≧1  n≧rを前提してよい。(入力エラーの処理は不要) # 'n枚のカードからr枚のカードを選ぶ組み合わせを計算する'(_n,_r,_n枚のカードからr枚のカードを選ぶ組み合わせ) :- findall(N,between(1,_n,N),L), count(組合せ(L,_r,_),_n枚のカードからr枚のカードを選ぶ組み合わせ). 組合せ(X,1,[A]) :- member(A,X). 組合せ([A|Y],N,[A|X]) :- N > 1, M is N - 1, 組合せ(Y,M,X). 組合せ([_|Y],N,A) :- N > 1, 組合せ(Y,N,A). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nCr(_n,_r,_組合せ数) :- _z is _n - _r + 1, 階乗(_n,_z,_組合せ数). 階乗(_r,_r,_r). 階乗(_n,_r,_組合せ数) :- _n_1 is _n - 1, 階乗(_n_1,_r,_組合せ数_1), _組合せ数 is _組合せ数_1 * _n. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1331904826/120 # # コマンドプロンプトにてワイルドカードで複数マッチングしてそれぞれ別のsetを置きたいんですけど # うまく行きません。 # for %%A in ("%folder%~n1*.txt") do ( # set tatoeba1=%%A # set tatoeba2=%%A # ) # こういう形まで考えたんですが結局最後のマッチングにsetされます。 # どのような形が正解なのでしょうか? # # 順に置換対象が現れる度に置換ならびから順に取り出して書き換える(_文字列,_置換対象,[_置換要素|R],_置換された文字列) :- 置換対象に合致したら(_文字列,_置換対象,S1,S3), 順に置換対象が現れる度に置換ならびから順に取り出して書き換える(S3,_置換対象,R,_置換された文字列_2), concat_atom([S1,_置換要素,_置換された文字列_2],_置換された文字列),!. 順に置換対象が現れる度に置換ならびから順に取り出して書き換える(_文字列,_,_,_文字列). 置換対象に合致したら(_文字列,_置換対象,S1,S3) :- sub_atom(_文字列,_,_,_,S1,S2,S3,L1,L2,L3), 置換対象と合致(S2,_置換対象). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/816 # # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): # 1〜10の数が書かれたカードが1枚ずつ、全部で10枚あります。 # 今、これらのカードを並べ、隣り合った数の差を左から次々に加えて # いくことにします。例えば、 # 2,5,6,8,1,4,3,9,7,10 # と並べたならば、 # 3+1+2+7+3+1+6+2+3=28 # ということになります。 # この計算結果が最も大きくなるようにカードを並べると、 # 結果はいくらになるでしょうか。 # (注)元の問題は算数の問題なので論理で答えを出すものだが、 # ここではプログラムを書いてその最大値を求めて欲しい。 # # '1〜10の数が書かれたカードが1枚ずつ、全部で10枚あります。今、これらのカードを並べ、隣り合った数の差を左から次々に加えていくことにします。例えば、 2,5,6,8,1,4,3,9,7,10 と並べたならば、 3+1+2+7+3+1+6+2+3=28 ということになります。この計算結果が最も大きくなるようにカードを並べると、結果はいくらになるでしょうか。'(_カードの差の合計が最大のカードならび,_カード差の合計) :- '1〜10の数が書かれたカードが1枚ずつ、全部で10枚あります'(_10枚のカードならび), '前後5要素ずつに分割する'(_10枚のカードならび,_前半カードならび,_後半カードならび), 後半カードならびを反転する(_後半カードならび,_反転した後半カードならび), 偶数要素を交換する(_前半カードならび,_反転した後半カードならび,_前半カードならび_2,_反転した後半カードならび_2), 前半部分も反転する(_前半カードならび_2,_反転した前半カードならび_2), 前半部分と後半部分を結合してカード差の合計が最大のカードならびを完成する(_反転した前半カードならび_2,_反転した後半カードならび_2,_カードの差の合計が最大のカードならび), カード差の合計(_カードの差の合計が最大のカードならび,_カード差の合計). '前後5要素ずつに分割する'(_10枚のカードならび,_前半カードならび,_後半カードならび) :- length(_前半のカードならび,5), length(_後半のカードならび,5), append(_前半のカードならび,_後半のカードならび,_10枚のカードならび). 後半カードならびを反転する(_後半カードならび,_反転した後半カードならび) :- reverse(_後半カードならび,_反転した後半カードならび). 偶数要素を交換する([],[],[],[]). 偶数要素を交換する([A,B|R1],[C,D|R2],[A,D|R3],[C,B|R4]) :- 偶数要素を交換する(R1,R2,R3,R4). 前半部分も反転する(_前半カードならび_2,_反転した前半カードならび_2) :- reverse(前半部分も反転する(_前半カードならび_2,_反転した前半カードならび_2). 前半部分と後半部分を結合してカード差の合計が最大のカードならびを完成する(_反転した前半カードならび_2,_反転した後半カードならび_2,_カードの差の合計が最大のカードならび) :- append(_反転した前半カードならび_2,_反転した後半カードならび_2,_カードの差の合計が最大のカードならび). カード差の合計([A,B],S) :- S is abs(A-B),!. カード差の合計([A,B|R1],S) :- カード差の合計([B|R1],S1), S is abs(A-B)+S1. % % ここでは算数的解法(これが正しいか疑問ではあるが)の順序を % Prologの述語にしてみた。 % なぜ、この解法で合計が最大になると考えたかについて述語定義の % の中で言及できていない。 % これは致命的な欠陥と言えるのだろう。 % % 以下のサイトは # # 与えたリストをシャッフルするshuffle/2を実装してください。 # # ?- shuffle([a,b,c], X). # X = [b,a,c]; # false # shuffle(_カードの束,_切られたカードの束) :- length(_カードの束,_カードの枚数), _カードの枚数 > 2, M is _カードの枚数 // 12 + 3, _乱数値 is random(M), length(L0,_乱数値), append(L0,L1,_カードの束), shuffle(L1,_カードの束_2), append(_カードの束_2,L0,_切られたカードの束),!. shuffle(_カードの束,_カードの束). % 以下のサイトは # # 与えたリストをシャッフルするshuffle/2を実装してください。 # # ?- shuffle([a,b,c], X). # X = [b,a,c]; # false # shuffle(_カードの束,_切られたカードの束) :- shuffle([_,_,_,_,_],_カードの束,_切られたカードの束). shuffle([],_カードの束,_カードの束) :- !. shuffle([_|Ln],_カードの束,_切られたカードの束) :- 概ね分割する(_カードの束,_カードの束_1,_カードの束_2), カードを雑に併合(1,_カードの束_1,_カードの束_2,_カードの束_3), shuffle(Ln,_カードの束_3,_切られたカードの束). 概ね分割する(_カードの束,_カードの束_1,_カードの束_2) :- _分割数1 is random(7) + 20, length(_カードの束_1,_分割数1), append(_カードの束_1,_カードの束_2,_カードの束), カードを雑に併合(_カードの束_1,_カードの束_2,_カードの束_3), カードを雑に併合(1,_カードの束_1,_カードの束_2,_カードの束) :- _重なる枚数 is truncate(random(4) * 0.4 + 1), length(L,_重なる枚数), append(L,R1,_カードの束1), カードを雑に併合(2,R,_カードの束_2,_カードの束_3), append(L,_カードの束_3,_カードの束),!. カードを雑に併合(2,_カードの束_1,_カードの束_2,_カードの束_3) :- _重なる枚数 is truncate(random(4) * 0.4 + 1), length(L,_重なる枚数), append(L,R2,_カードの束2), カードを雑に併合(1,_カードの束_1,R,_カードの束_3), append(L,_カードの束_3,_カードの束),!. カードを雑に併合(_,_カードの束_1,_カードの束_2,_カードの束) :- append(_カードの束_1,_カードの束2,_カードの束),!. % 以下のサイトは # # 与えたリストをシャッフルするshuffle/2を実装してください。 # # ?- shuffle([a,b,c], X). # X = [b,a,c]; # false # shuffle_n(0,_,_リスト,_リスト) :- !. shuffle_n(_n,_カードの枚数,_入力リスト,_出力リスト) :- shuffle(_入力リスト,_切られたリスト), _n_1 is _n - 1, shuffle_n(_n_1,_カードの枚数,_切られたリスト,_出力リスト). shuffle(_カードの枚数,_入力リスト,_出力リスト) :- _乱数値1 is random(_カードの枚数) + 1, _乱数値2 is random(_カードの枚数) + 1, 交換(1,[_乱数値1,_乱数値2],V1,V2,_入力リスト,_出力リスト). 交換(N,_交換位置リスト,V1,V2,[A|R1],[A|R2]) :- \+(member(N,_交換位置リスト)), N2 is N + 1, 交換(N2,_交換位置リスト,V1,V2,R1,R2),!. 交換(N,_交換位置リスト,V1,V2,[A|R1],[V2|R2]) :- var(V1), V1 = A, N2 is N + 1, 交換(N2,_交換位置リスト,V1,V2,R1,R2),!. 交換(_,_,V1,V2,[A|R],[V1|R]) :- var(V2), V2 = A,!. % 以下のサイトは # # 与えたリストをシャッフルするshuffle/2を実装してください。 # # ?- shuffle([a,b,c], X). # X = [b,a,c]; # false # % 一回ずつ非決定性述語仕様で切っていくには、 shuffle(_元のカードの束,_切られたカードの束) :- length(_元のカードの束,_カードの枚数), _乱数値 is random(_カードの枚数), length(L0,_乱数値), shuffle(L0,_元のカードの束,_切られたカードの束). shuffle(L0,_元のカードの束,_切られたカードの束) :- append(L0,L1,_元のカードの束), append(L1,L0,_切られたカードの束). shuffle(L0,_元のカードの束,_切られたカードの束) :- append(L0,L1,_元のカードの束), append(L1,L0,_切られたカードの束1), shuffle(_切られたカードの束1,_切られたカードの束). % 以下のサイトは # # 与えたリストをシャッフルするshuffle/2を実装してください。 # # ?- shuffle([a,b,c], X). # X = [b,a,c]; # false # shuffle(_元のカードの束,_切られたカードの束) :- length(_元のカードの束,_カードの枚数), length(Ln,100), shuffle(Ln,_カードの枚数,_元のカードの束,_切られたカードの束). shuffle([],_,_カードの束,_カードの束) :- !. shuffle([_|Ln],_カードの枚数,_カードの束1,_カードの束) :- shuffle(_カードの枚数,_カードの束1,_カードの束2), shuffle(Ln,_カードの枚数,_カードの束2,_カードの束). shuffle(_カードの枚数,_カードの束1,_カードの束2) :- _乱数値 is random(_カードの枚数), length(L0,_乱数値), append(L0,L1,_カードの束1), append(L1,L0,_カードの束2). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1260532772/487 # [1] 授業単元:計算機入門及び演習 # [2] 問題文(含コード&リンク):http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10311.txt # # 以下の問題を解くプログラムをC言語を用いて作成しなさい. # # AさんとBさんは点数が書かれたカードを何枚か持っている. Aさんのカードと # Bさんのカードを1枚ずつ交換して,Aさんの持つカードの合計点数とBさんの持つ # カード合計点数が等しくなるようにしたい. # このときどのカードとどのカードを交換したらよいか.ただし,カードを # 交換しなくても合計点数が等しい場合でも,必ずカードの交換を行うものとする. # # 入力は,いくつかのデータセットからなる.各データセットは次の形式で与えられる. n m # s1 # s2 # ... # sn # sn+1 # sn+2 # ... # sn+m # 各データセットの最初の行は空白ひとつで区切られたふたつの数 n と m を含み, # n はAさんのカードの枚数,m はBさんのカードの枚数を表す.続く n+m 行には, # 各カードの点数が 1 行にひとつずつ並ぶ. # 最初の n 個の点数 (s1 から sn まで) はAさんのカードの点数,残りの # m 個の点数 (sn+1 から sn+m まで) はBさんのカードの点数を表す. # n および m は 100 以下の正の整数とし,カードの点数は 0 以上 100 以下の # 整数値とする.入力の終わりは,空白ひとつで区切られたふたつの 0 を含む # 1 行で示される. # 各データセットに対し,Aさん,Bさんの交換前のすべてのカードと交換すべき2つの # カードを出力すること.形式は特に問わない(実行例を参考にすること). # なお,合計を等しくするようなカードの交換の方法が複数ある場合は, # 交換するカードの点数の和が最小となるもののみを出力すること. # また,カードの点数の合計を等しくするような交換が存在しない場合はその旨を # 出力すること. # 'AさんとBさんは点数が書かれたカードを何枚か持っている. AさんのカードとBさんのカードを1枚ずつ交換して,Aさんの持つカードの合計点数とBさんの持つカード合計点数が等しくなるようにする'(LA,LB,LX) :- quicksort(LA,LA1), quicksort(LB,LB1), length(LA1,LenA), length(LB1,LenB), append(LA1,LB1,L), findall([L1,L2],( 組合せ(L,LenA,L1), sum(L1,Sum), 'L1分をLから取り除く'(L1,L,L3), 組合せ(L3,LenB,L2),sum(L2,Sum)), LX), 最短手順を探る(LA1,LX,_交換候補). 'L1分をLから取り除く'([],L,L) :- !. 'L1分をLから取り除く'([A|R1],L1,L2) :- 'AをL1から取り除く'(A,L1,L3), 'L1分をLから取り除く'(R1,L3,L2). 'AをL1から取り除く'(A,L1,L2) :- append(L0,[A|R],L1), append(L0,R,L2),!. sum([],0) :- !. sum([A|R],X) :- sum(R,Y), X is A + Y. 最短手順を探る(LA1,LL,_放出,_受け取り) :- findall([_放出,_受取],( append(_,[[L1,_]|_],LL), 交換候補(LA1,L1,_放出,_受取)), LX), findmin(Len,( append(_,[[U1,U2]|_],LX), length(U1,Len)), Min), append(_,[[_放出,_受け取り]|_],LX), length(U1,Min). 交換候補([],L,[],L) :- !. 交換候補(L,[],L,[]) :- !. 交換候補([A|R1],[A|R2],R3,R4) :- 交換候補(R1,R2,R3,R4),!. 交換候補([A|R1],[B|R2],[A|R3],R4) :- A < B, 交換候補(R1,[B|R2],R3,R4),!. 交換候補([A|R1],[B|R2],R3,[B|R4]) :- A > B, 交換候補([A|R1],R2,R3,R4),!. % 以下のサイトは # 出典:: http://hibari.2 # ch.net/test/read.cgi/tech/1267796762/657 # 【 課題 】 # (6)2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求めるプログラム # # 【 形態 】http://ime.nu/www.javadrive.jp/install/jdk/で設定したのですが1でしょうか… # 【 期限 】12月16日です # 【 Ver  】1.6.0_22 # 【 補足 】ぎりぎりで丸投げですがよろしくお願いします! # # '2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求める'(_確率) :- '左からi番目のカードに書かれた数がi以上の度数'(1,2,0,0,_分子,_分母), \+(_分母 = 0), _確率 is _分子 / _分母,!. '左からi番目のカードに書かれた数がi以上の度数'(5,_カード,X,Y,X,Y) :- _カード > 6,!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード > 6, _i2 is _i + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i2,2,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分子2 is _分子1 + 1, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母2,_分子,_分母),!. % 以下のサイトは # <問題> # ポーカーの役、ストレートとフラッシュについての問題です。 # どちらの役が出現し難いかを示すPrologプログラムを書きなさい。 # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % この解答は http://hibari.2ch.net/test/read.cgi/tech/1289016056/85 に示されたリンクから % 取り出したものです。www.dotup.orgの掲載時間は有限で後に参照できなくなってしまうことが % 多いので、ここに転記させていただきました。したがって、 % このプログラムの著作権は上記2chに書き込まれた匿名の方に帰属すると考えます。 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2010-11-23 7:17 %%%% /*汎用*/ append([], Z, Z). append([W|X1], Y, [W|Z1]) :- append(X1, Y, Z1). last([], []). last([A], A). last([A|B], C) :- last(B, C). /* 1〜52 でスペードの 1〜クラブの13を表す。ジョーカーは除いている。 */ /******* フラッシュを数える *******/ /* 「マーク(スート)が同じである」組み合わせの定義 */ isSameMark(C, D) :- toMark(C, CMark), toMark(D, DMark), CMark = DMark. /* 「カードのコード(1〜52) とマーク」の組み合わせの定義 */ toMark(C, Mark) :- ( 1 =< C, C =< 13, Mark = spade); (14 =< C, C =< 26, Mark = heart); (27 =< C, C =< 39, Mark = dia ); (40 =< C, C =< 52, Mark = club ). /* 5枚のカードでフラッシュ役になる組み合わせの定義。 ストレート群からストレートフラッシュを除く時使う。 */ isFlush([A,B,C,D,E]) :- isSameMark(A, B), isSameMark(B, C), isSameMark(C, D), isSameMark(D, E). /* フラッシュとなりうるパターンの定義。*/ /* すなわち、空リストに対して 1枚目候補(あくまで候補)を スペードの1とした場合の、その後とりうる全パターンのこと。*/ flushSearch(Patterns) :- flushSearch(1, [], Patterns). /* 長さ5でかつストレートフラッシュで無いものであるとき パターンとみなす(フラッシュか否かの判断は、 計算回数を短縮するため既に行われている) */ flushSearch(_, Path, Patterns) :- length(Path, 5), \+ isStraight(Path), Patterns = [Path]. /* これは strSearch群との対象性のために最初作ってただけ。結局無駄 */ flushSearch(C, N, Path, Patterns) :- flushSearch(C, [N|Path], Patterns). /* 与えられたリストに、C を足した場合と、Cを足さなかった場合にわけて、 フラッシュとなりうるパターンを収集して混ぜ合わせる。 なお、前回足したもの(F) と今回足すもの(C) との2枚で フラッシュ役が成立しなければ、 もはやフラッシュが作られることはありえない。 それを配慮して計算回数を節約している。 C は 1 から順繰りに重複無く試行される */ flushSearch(C, Path, Patterns) :- length(Path, Length), Length < 5, (Length = 0; (Path = [F|R], isSameMark(C, F))), C1 is C + 1, (C =< 52, flushSearch(C1, C, Path, Patterns1); Patterns1 = []), (C1 =< 52, flushSearch(C1, Path, Patterns2); Patterns2 = []), append(Patterns1, Patterns2, Patterns). /* ストレートを数える */ /* 「D の次に C が来うる」という組み合わせ */ isNext(C, D) :- toNumber(C, CNum), toNumber(D, DNum), ( (CNum = 1, DNum = 13); (C1 is DNum + 1, C1 = CNum) ). /* カードのコードをエース〜キングに変換する */ toNumber(Card, CNum) :- (Card =< 13, CNum = Card); (13 < Card, CM is Card - 13, toNumber(CM, CNum) ). /* ストレート役を構成する組み合わせの定義。 フラッシュ群からストレートフラッシュを除く時使う。 なお、flushSearch の実装により、このリストはかならず降順である。 また、必ずフラッシュなので、5,30,3,15,1 的なことは起こらない */ isStraight([A,B,C,D,E]) :- (isNext(A, B); isNext(E, A)), isNext(B, C), isNext(C, D), isNext(D, E). /* flushSearch と似たような構成をしている。 最初にリストに追加するのは エース〜10 である。 また、最後にリストに追加したものの次は、+1かキングの次のエースである。 つまり、カード種別が予測できるため、 追加直後の再帰呼出しで配慮し(NX,Nのところ)、計算時間を短縮している */ strSearch(Patterns) :- strSearch(1, [], Patterns). strSearch(_, Path, Patterns) :- length(Path, 5), \+ isFlush(Path), Patterns = [Path]. strSearch(_, New, Path, Patterns) :- length(Path, Length), toNumber(New, NewNum), ( (Length = 0, NewNum =< 10); (Path = [Last|Rest], isNext(NewNum, Last)) ), NX is NewNum + 1,((NX = 14, N = 1);(N = NX)), strSearch(N, [New|Path], Patterns). strSearch(Top, Path, Patterns) :- length(Path, Length), Length < 5, ((Length=0,C1 is Top + 1);(C1 is Top + 13)), (Top =< 52, strSearch( 1, Top, Path, Patterns1); Patterns1 = []), (C1 =< 52, strSearch(C1, Path, Patterns2); Patterns2 = []), append(Patterns1, Patterns2, Patterns). /* 件数カウントおよび比較結果の表示 */ flushCount(N) :- flushSearch(L), length(L, N). strCount(N) :- strSearch(L), length(L, N). difficult(D) :- flushCount(F), strCount(S), ((S% 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1289913298/83 # # ポーカーゲームを作るプログラムの課題を教えてください。 # [1] プログラムまとめ # [2] 課題1のストレート、フラッシュ、フルハウスをヒントを使って判定する関数を作る。 # ポーカーの役(_手札ならび,フラッシュ) :- フラッシュとは5枚の手札が全部同じマークになること。ただし、番号が連続している場合はストレートフラッシュといって別の役となる(_手札ならび). ポーカーの役(_手札ならび,ストレート) :- ストレートとは5枚の手札が連続した番号になること。ただし、マークが全部同じ場合はストレートフラッシュといって別の役となる(_手札ならび). ポーカーの役(_手札ならび,フルハウス) :- フルハウスとは3枚が同一番号で、別の番号の残り2枚も同一番号であるもの(_手札ならぴ). フラッシュとは5枚の手札が全部同じマークになること。ただし、番号が連続している場合はストレートフラッシュといって別の役となる(_手札ならび) :- 全部同じマーク(_手札ならび), ストレートフラッシュになるものを除外する(_手札ならび). 全部同じマーク(_手札ならび) :- all(_手札ならび,[_,_共通マーク]),!. ストレートフラッシュになるものを除外する(_手札ならび) :- 判断しやすいように番号順に並べ直す(_手札ならび,_番号順に整列した手札ならび), \+(番号が連続している(_番号順に整列した手札ならび)),!. ストレートとは5枚の手札が連続した番号になること。ただし、マークが全部同じ場合はストレートフラッシュといって別の役となる(_手札ならび) :- 判断しやすいように番号順に並べ直す(_手札ならび,_番号順に整列した手札ならび), 番号が連続している(_番号順に整列した手札ならび), \+(全部同じマーク(_手札ならび)). 判断しやすいように番号順に並べ直す(_手札ならび,_番号順に整列した手札ならび) :- sort(_手札ならび,_番号順に整列した手札ならび). 番号が連続している(_番号順に整列した手札ならび) :- 番号が連続していることを再帰的に確かめる(_番号順に整列した手札ならび). 番号が連続していることを再帰的に確かめる([[_カード番号1,_],[_カード番号2,_]|R]) :- _カード番号2 is _カード番号1 + 1, 番号が連続していることを再帰的に確かめる([_カード番号2|R]). 番号が連続していることを再帰的に確かめる([_]). フルハウスとは3枚が同一番号で、別の番号の残り2枚も同一番号であるもの(_手札ならぴ) :- 判断しやすいように番号順に並べ直す(_手札ならび,_番号順に整列した手札ならび), それぞれ同一番号の二枚、三枚組(_番号順に整列した手札ならび). それぞれ同一番号の二枚・三枚組([[_A,_],[_A,_],[_A,_],[_B,_],[_B,_]]) :- \+(A=B),!. それぞれ同一番号の二枚・三枚組([[_A,_],[_A,_],[_B,_],[_B,_],[_B,_]]) :- \+(A=B),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1289913298/83 # # ポーカーゲームを作るプログラムの課題を教えてください。 # [1] プログラムまとめ # [2] 課題1のストレート、フラッシュ、フルハウスをヒントを使って判定する関数を作る。 # ポーカーの役(_手札ならび,フラッシュ) :- すべての手札のマークが共通である(_手札ならび), ストレートではない(_手札ならび,ストレート),!. ポーカーの役(_手札ならび,ストレート) :- 並べ直して、番号は連続したカードは5枚あることを確認する(_整列した手札ならび), '同一マークではない'(_整列した手札ならび),!. ポーカーの役(_手札ならび,フルハウス) :- 並べ直して、同一番号の2枚、3枚組になっているか確認する(_手札ならび). すべての手札のマークが共通である(_手札ならび) :- all(_手札ならび,[_,_共通マーク]),!. ストレートではない(_手札ならび) :- \+(ポーカーの役(_手札ならび,ストレート)). 並べ直して(_手札ならび,_整列した手札ならび) :- sort(_手札ならび,_整列した手札ならび). 並べ直して、番号は連続したカードは5枚あることを確認する(_手札ならび) :- 並べ直して(_手札ならび,_整列した手札ならび), _整列した手札ならび = [_最小値|R], _最大値 is _最小値 + 4, findall(_番号,for(_最小値,_番号,_最大値),_整列した手札ならび), 同一マークではない(_整列した手札ならび) :- \+(all(_整列した手札ならび,[_,_共通マーク])),!. 並べ直して、同一番号の2枚、3枚組になっているか確認する(_手札ならび) :- 並べ直して(_手札ならび,_整列した手札ならび), 同一番号の2枚、3枚組になっている(_整列した手札ならび). 同一番号の2枚、3枚組になっている([[A,_],[A,_],[B,_],[B,_],[B,_]]) :- \+(A = B),!. 同一番号の2枚、3枚組になっている([[A,_],[A,_],[A,_],[B,_],[B,_]]) :- \+(A = B),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1289913298/83 # # ポーカーゲームを作るプログラムの課題を教えてください。 # [1] プログラムまとめ # [2] 課題1のストレート、フラッシュ、フルハウスをヒントを使って判定する関数を作る。 # # /* ヒント: この関数を使うと、 判定が簡単かも */ # void distrib(struct card h[], int dist[]){ # int i; # for(i = 0; i < 14; i++){ # dist[i] = 0;} # for(i = 0; i < 5; i++){ # dist[h[i].pips]++;}} # # int is_straight(struct card h[]){ # /* 課題1 */ # return 0;} # # int is_flush(struct card h[]){ # /* 課題1 */} # # int is_fullhouse(struct card h[]){ # /* 課題1 */ # return 0;} # # card h[] は手札のカード # h[].pips は手札のカードの番号 # h[].suit は手札のカードのマークのことです ポーカーの役(_手札ならび,フラッシュ) :- all(_手札ならび,[_,_共通マーク]), \+(ポーカーの役(_手札ならび,ストレート)),!. ポーカーの役(_手札ならび,ストレート) :- sort(_手札ならび,L), L = [Min|R], Max is Min + 4, findall(N,for(Min,N,Max),L), \+all(_手札ならび,[_,_共通マーク])),!. ポーカーの役(_手札ならび,フルハウス) :- findsetof(_番号,append(_,[[_番号,_]|_],_手札ならび),[_番号1,_番号2]), count(append(_,[[_番号1,_]|_],_手札ならび),Count1), Count1 >= 2, count(append(_,[[_番号2,_]|_],_手札ならび),Count2), Count2 >= 2,!. ポーカーの役(_手札ならび,フルハウス) :- sort(_手札ならび,L), フルハウス(L). フルハウス([[_A,_],[_A,_],[_B,_],[_B,_],[_B,_]]) :- \+(A = B),!. フルハウス([[_A,_],[_A,_],[_A,_],[_B,_],[_B,_]]) :- \+(A = B),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1267796762/451 # # 【 課題 】ttp://rg550.hp.infoseek.co.jp/cgi-bin/joyful/img/1040.zip # 【 形態 】Javaアプリケーション(main()で開始)/ # 【 期限 】10/15 # 【 Ver  】"1.6.0_21" # 【 補足 】丸投げですがよろしくお願いします。 # # [問3] # [ファイル名] Lesson1_3.java # Lesson1_2 で作成したTrumpCard を拡張します.トランプでゲームを行う場合,そのカードが表を向いているか裏を向いているかという要素は重要なので,それを表現できるようにします. # この場合の表とはマークや数値が表示されている側,裏はその逆で絵柄が付いている側を指すこととします.サンプルプログラムが動作するように,以下の実装を付け加えなさい. # 1. クラスTrumpCard は,インスタンス変数として,boolean openStat を持ちます.そのインスタンスが表の場合はtrue,裏の場合はfalse の値を持つものとします. # 2. クラスTrumpCard は,コンストラクタTrumpCard(String mark, int number, booleanopen)を持ちます.open によって,インスタンスの初期状態での表裏の値(openStat の値)を決めることができるものとします.また,指定されない場合の初期値はfalse(裏向き)とします. # 3. クラスTrumpCard は,メソッドとしてpublic void setOpened(boolean open)を持ちます.このメソッドが呼ばれた場合そのインスタンスが持つopenStat の値をopen の値に置き換えます. # 4. クラスTrumpCard は,メソッドとしてpublic boolean getOpened()を持ちます.このメソッドが呼ばれた場合そのインスタンスが持つopenStat の値を返り値として返します. # トランプのカード初期状態(_マーク,_数字,_トランプ_前状態,_トランプ_後状態) :- 0 is random mod 2, append(L0,[[_マーク,_数字,_,_位置]|R],_トランプ_前状態), append(L0,[[_マーク,_数字,表,_位置]|R],_トランプ_後状態). トランプのカード初期状態(_マーク,_数字,_トランプ_前状態,_トランプ_後状態) :- 1 is random mod 2, append(L0,[[_マーク,_数字,_,_位置]|R],_トランプ_前状態), append(L0,[[_マーク,_数字,裏,_位置]|R],_トランプ_後状態). 表にする(_マーク,_数字,_トランプ_前状態,_トランプ_後状態) :- append(L0,[[_マーク,_数字,_,_位置]|R],_トランプ_前状態), append(L0,[[_マーク,_数字,表,_位置]|R],_トランプ_後状態). 裏にする(_マーク,_数字,_トランプ_前状態,_トランプ_後状態) :- append(L0,[[_マーク,_数字,_,_位置]|R],_トランプ_前状態), append(L0,[[_マーク,_数字,裏,_位置]|R],_トランプ_後状態). 表である(_マーク,_数字,_トランプ) :- append(L0,[[_マーク,_数字,表,_]|R],_トランプ),!. 裏である(_マーク,_数字,_トランプ) :- append(L0,[[_マーク,_数字,裏,_]|R],_トランプ),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/488 # # updateのwhere in句でワイルカードを使いたいのですが、 # mysqlで、 UPDATE table SET col='新しいデータ' where col in ('001古%', '003古%'.) としたのですが、 # 上手く出来ませんでした。 # # どうしたら出来るのでしょうか。 # # % 新しいデータ(新しいデータ). 節の定義順を保って述語を更新したい :- findall(_col,retract(table(_col)),L), append(_,[A|R],L), update_data(A,B), assertz(table(B)), R = [],!. update_data(_col,_新しいデータ) :- sub_atom(_col,0,4,_,'001古'),新しいデータ(_新しいデータ),!. update_data(_col,_新しいデータ) :- sub_atom(_col,0,4,_,'003古'),新しいデータ(_新しいデータ),!. update_data(_col,col). % 以下のサイトは ?- 'a##'. # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1260532772/827 # # 770で一度投稿しましたが問題文に不足が多かったため再度投稿します。 # [1] 授業単元:プログラミング # [2] 問題文:http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10362.txt[3] 環境 # 下記の機能を備えた極めて単純なデータベースシステムであるカード型データベースシステムの構築を考える。 # 課題7-1 # 下記のような方針でプログラムを作成せよ。 # # 新しい科目を登録する機能 # すでに登録されている科目を修正(更新)する機能 # 登録科目のソート(並び替え)を行う機能 # 登録科目の一部分のみを検索して取り出し、表示する機能 # 登録科目から、卒業までに必要な単位を計算し、表示する機能 # データベースファイルの仕様 # データベースファイルについては、本格的なデータベースになると、アクセス性や # 安定性など様々な要求を満たす必要があるが、ここでは最も単純なテキストファイルとする。 # さらに、書き込みをfprintfで、読み込みをfscanfで行えるように、 1行中に、 # それぞれの項目(フィールド)がスペースで区切られているようなファイルとする。 # なお、この場合、それぞれの項目はスペースを含んでいけないこととなる。 # 履修科目データベースシステムの例においては、例えば、 # 単位の種類(必修、選択必修など)、単位数、年次、前期か後期か、再履修かどうか、成績の6項目を含むこととする。 # ここで、いくつかの選択肢から選択するものについては、数字で置き換えることとする。 # このような仕様に基づいたファイルの例は以下のようなものになる。ここでは、ファイル名は、"ユーザ名_kamokudb.txt"とする。 # typedef struct _KAMOKU { # char name[MAX_KAMOKU_NAME]; /* 科目名 */ # int tanni_type; /* 必修、選択必修、選択、自由のいずれか */ # int tanni; /* 何単位か */ # int nenji; /* 何年次か */ # int kouki_flag; /* 前期なら0、後期なら1 */ # int sairi_flag; /* 再履修なら1、そうでないなら0 */ # int seiseki; /* 59点以下は不可、-1は未履修であることを示す */ # } KAMOKU; # # KAMOKU kamoku_list[200]; 履修科目データベースシステムを実装し、実行した例を以下に示す。なお、これは一例であって、課題は以下の通りに動作する必要はない。 ****** 単位データベースシステム ****** ユーザー名を入力して下さい:yamada ユーザー yamada は存在しません。データベースを新規に作成しますか? [1] Yes [2] No 番号を選択してください:1 **** 機能選択 **** [1] 科目登録 [2] 科目修正・削除 [3] データベース表示 [4] 必要単位数の表示 [5] 検索 [6] 並び替え [99] プログラム終了 機能を選択してください:1 **** 科目登録 **** 登録する科目を入力します。スペースを含まないローマ字で入力して下さい。 エンターキーのみを入力すると、科目の登録が終了します。 科目名:programming_ennsyuu_2 programming_ennsyuu_2 の情報を入力して下さい。 [1] 必修 [2] 選択必修 [3] 選択 [4] 自由 単位の種類:1 単位数:1 年次:2 [1] 前期 [2] 後期 前期・後期:2 [1] 非再履修 [2] 再履修 再履修:1 成績(-1:未履修):70 programming_ennsyuu_2 の情報を次のように登録します:必修, 1単位, 2年次, 後期, 非再履修, 70点 [1] 登録 [2] 再入力 番号を選択してください:1 programming_ennsyuu_2 の情報を登録しました。 科目名:denki_kairo_ennsyuu : 科目名: 科目登録を終了します。 **** 機能選択 **** : 機能を選択してください:2 **** 科目修正・削除 **** [1] programming_ennsyuu_2 [2] denki_kairo_ennsyuu [3] denki_kairo_kiso [4] digital_shingou_syori : 修正・削除する科目を選択して下さい:2 denki_kairo_ennsyuu の情報を修正して下さい。 最初の単位の種類で、[0] 削除 を選択すると、削除されます。 また、エンターキーを押すと、大括弧内の値が選択されます。 [0] 削除 [1] 必修 [2] 選択必修 [3] 選択 [4] 自由 単位の種類[3]: 単位数[1]: 年次[2]: [1] 前期 [2] 後期 前期・後期[1]: [1] 非再履修 [2] 再履修 再履修[1]: 成績(-1:未履修)[75]:85 denki_kairo_ennsyuu の情報を次のように修正します:選択, 1単位, 2年次, 前期, 非再履修, 85点 [1] 登録 [2] 再入力 番号を選択してください:1 denki_kairo_ennsyuu の情報を修正しました。 : 機能を選択してください:5 **** 検索 **** [1] 科目名 [2] 年次 [3] 前期・後期 [4] 不可の科目 検索したい項目を選択して下さい:2 年次を検索します。 検索対象:2 年次が 2 であるのは以下のものです: denki_kairo_kiso: 選択必修, 2単位, 2年次, 前期, 非再履修, 65点 denki_kairo_ennsyuu: 選択, 1単位, 2年次, 前期, 非再履修, 85点 programming_ennsyuu_1: 必修, 1単位, 2年次, 前期, 非再履修, 75点 programming_ennsyuu_2: 必修, 1単位, 2年次, 後期, 非再履修, 70点 digital_shingou_syori: 必修, 2単位, 2年次, 後期, 非再履修, 30点 : : 機能を選択してください:6 **** 並び替え **** [1] 科目名 [2] 年次 [3] 点数 どの項目で並べ替えるか選択して下さい:3 点数を昇順で並べ替えます。 digital_shingou_syori: 必修, 2単位, 2年次, 前期, 非再履修, 30点 denki_kairo_kiso: 選択必修, 1単位, 2年次, 前期, 非再履修, 65点 programming_ennsyuu_2: 必修, 1単位, 2年次, 後期, 非再履修, 70点 programming_ennsyuu_1: 必修, 1単位, 2年次, 前期, 非再履修, 75点 denki_kairo_ennsyuu: 選択, 1単位, 2年次, 前期, 非再履修, 85点 : : 機能を選択してください:4 **** 必要単位数の表示 **** 卒業に必要な単位数は、合計 62単位 総合基礎部門 計0単位 選択必修科目 0単位 選択科目 0単位 専門教育部門 計62単位 必修科目 12単位 選択必修科目 16単位 選択科目 34単位 : 機能を選択してください:99 プログラムを終了します。 データベースファイル yamada_kamokudb.txt を更新しました。 拡張 上記のプログラムの拡張を考える。例えば、以下のようなものが考えられる。 修得済み単位数や、不可となった科目を表示するなど、上記以外の機能を提供する。 検索において、完全一致のものだけでなく、条件に見合ったものを出力するようにする。 並び替えにおいて、年次だけでなく、年次と前期・後期を考慮した並べ替えをするなど、 他の並び替え方法を提供する。 データベースファイルとして、コンマ区切りのテキストファイルを用いる。 上記では、データファイルにスペース区切りのテキストファイルを用いたが、コンマ区切りのテキストファイル(CSVファイル)が用いられることも多い。この場合、フィールドにスペースが含まれていても問題なく動作する(ただし、コンマが含まれる場合には何らかの対策が必要になる)。 CSVファイルの読み込みのためには、いくつかの方法があるが、fgetsで読み込み、文字','を探す方法などが考えられる。また、strchrという関数が、文字列から特定の文字を含む箇所を取り出すものであるため、 fgetsとこれを組み合わせる方法もある。 構造体の配列を用いるのではなく、構造体へのポインタに対しmallocでメモリ確保する方法を用いる。 この場合、状況に応じてサイズを変えることが可能となる。ただし、確保したメモリは、使わなくなった場合には解放する必要がある。 KAMOKU *kamoku_list = NULL; : int num_list = 200; : kamoku_list = malloc(sizeof(struct _KAMOKU) * num_list); /* これ以降は、200の要素を持つ構造体の配列と同様に使用できる */ : printf("成績:%d\n", kamoku_list[0].seiseki); : free(kamoku_list); その他、既存のデータベースシステム等を参考にして機能を追加する。 履修科目データベースの検索(_検索項目,_検索鍵,_検索データ) :- get_split_lines('ユーザ名_kamokudb.txt',[' '],LL), member(_検索データ,LL), 鍵情報(_検索項目名,_検索データ,_検索鍵). 鍵情報(科目名,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_科目名). 鍵情報(単位の種類,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_単位の種類). 鍵情報(単位数,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_単位数). 鍵情報(年次,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_年次). 鍵情報(後期,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_後期). 鍵情報(前期,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_前期). 鍵情報(再履修,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_再履修). 鍵情報(成績,[_科目名,_単位の種類,_単位数,_年次,_後期,_前期,_再履修,_成績],_成績). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 鍵情報ソースプログラムの生成(_項目名ならび) :- append(_,[_項目名|R],_項目名ならび), findall(B,(member(A,_項目名ならび),concat_atom(['_',A],B)),L2), concat_atom(L2,',',_項目名ならび文字列), write_formatted('鍵情報(%t,[%t],_%t).\n',[_項目名,_項目名ならび文字列,_項目名]), R = []. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1276810079/602 # # [1] 授業単元: プログラミング演習 # [2] 問題文(含コード&リンク):http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10791.txt # 問題文 # # 0から7までの数字が描かれたカードがある。ただし、0だけ2枚で、合計9枚とする。 # この中から4枚を選ぶ組合せを考える。ただし、6と7は同時に選ばない(両方選ばなくてもよい)。 # このような組合せを列挙し、何通りあるかを、C言語のプログラムで求める。何通りあるかは、数学的に解いて確認せよ。 # 例題プログラムEnumFull.c を修正する。 # # 部分問題への分解 0が現れる枚数で場合分けして、それぞれの個数を集計 # 弱化問題への緩和 0および6と7に関する条件を無視して、とりあえず全てを列挙し、題意に合わないものを排除 # 等価問題への還元 2枚の0を、0と8に読み換え、8は単独で選ばないという条件に置換 # 7は外して列挙し、6が現れる場合に、7に読み換えたものも追加 '0から7までの数字が描かれたカードがある。ただし、0だけ2枚で、合計9枚とする。この中から4枚を選ぶ組合せを考える。ただし、6と7は同時に選ばない(両方選ばなくてもよい)。このような組合せを列挙する'(U) :- findall(L,( 組み合わせ([0,0,1,2,3,4,5,6,7],4,L), 許される組み合わせ(L)), X), sort(X,Y), append(_[U|R],Y). 許される組み合わせ(A) :- append(_[6|_],A),append(_,[7|_],A),!,fail. 許される組み合わせ(A) :- append(B,[0|C],A),append(D,[0|E],C),!,fail. 許される組み合わせ(A). '0から7までの数字が描かれたカードがある。ただし、0だけ2枚で、合計9枚とする。この中から4枚を選ぶ組合せを考える。ただし、6と7は同時に選ばない(両方選ばなくてもよい)。このような組合せを列挙し何通りあるか'(_何通り) :- count('0から7までの数字が描かれたカードがある。ただし、0だけ2枚で、合計9枚とする。この中から4枚を選ぶ組合せを考える。ただし、6と7は同時に選ばない(両方選ばなくてもよい)。このような組合せを列挙する'(_),_何通り). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/944 # # num0からnum50までの連番でフィールドがあるのですが、 # この中で、レコードの値が0より大きいものをSELECTするにはどうしたらいいでしょうか? # ワイルドカード的な書き方はないのでしょうか? 'num0からnum50までの連番でフィールドの中で0より大きいものを選択'(L) :- フィールド名の連番を作る(_フィールド名ならび), 選択項を変数引数で構成し(_選択項,_引数ならび), call(P), findall([_フィールド名,_値], フィールドの中で0より大きいもの(_フィールド名ならび,_引数ならび,_フィールド名,_値), L). フィールドの中で0より大きいもの(_フィールド名ならび,L2,_フィールド名,_値) :- for(1,M,51), list_nth(M,L2,_値), _値 > 0, list_nth(M,_フィールド名ならび,_フィールド名). フィールド名の連番を作る(_フィールド名ならび) :- findall(S,(for(0,N,50),concat_atom([num,N],S)),_フィールド名ならび). 選択項を変数引数で構成し(_選択項,_変数ならび) :- length(_変数ならび,51), _選択項 =.. [テーブル|_変数ならび]. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1263824755/683 # # [1] 授業単元:プログラミング # [2] 問題文(含コード&リンク): http://ime.nu/ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10530.zip # ポーカープログラム # # 1,二つのクラス(Card,Deck)が与えられていて、 # game1.hとgame1.cppのプラグラムを書け。 # このプログラムはデッキから5枚配る事を1回とし、 # その中に何回ペアまたはフラッシュ(同じ手札に同じマークが5枚揃う事)が # あるかの10000回の統計であり、以下を表示させること # # 何回の統計か # そのうち何個の手札がペアを持つか # そのうち何個の手札がフラッシュを持つか # ペアは全体の何%か # フラッシュは全体の何%か # # 無作為化する為に以下を必ず含める事 # stand(unsigned)time(NULL); # # #2,新しいクラスhand(hand.hとhand.cpp)と、これを実行させる為の # game2.hとgame2.cppを書け。 # これはカードの配布、ペア・フラッシュの確認、そしてデッキにカードを戻す為の # プログラムである。 # ペアまたはフラッシュの出現度数(_回数,_ペアの度数,_フラッシュの度数) :- findsum([M1,M2],(for(1,N,_回数),トランプの準備([A,B,C,D,E|R]),役([A,B,C,D,E],M1,M2)),[_ペアの度数,_フラッシュの度数]). 役(L,1,0) :- sort(L,L1),ペア(L1),!. 役([A|R],0,1) :- sub_atom(A,1,1,_,_種類),フラッシュ(_種類,R),!. ペア([A,B]) :- sub_atom(A,0,1,_,C),sub_atom(B,0,1,_,C),!. ペア([A,B,C|R]) :- sub_atom(A,0,1,_,E),sub_atom(B,0,1,_,E),sub_atom(C,0,1,_,E),ペア(R),!. ペア([A,B,C|R]) :- sub_atom(A,0,1,_,E),sub_atom(B,0,1,_,E),\+(sub_atom(C,0,1,_,E)),!. ペア([A|R]) :- ペア(R). フラッシュ(_,[]) :- !. フラッシュ(A,[B|R]) :- sub_atom(B,1,1,_,A),フラッシュ(A,R). トランプの準備(X) :- findall(U,(for(1,N,52),一枚のカードを作る(N,U)),_整列したカード), トランプを切るようにならびを切る(41,53,_整列したカード,X),!. 一枚のカードを作る(N,U) :- M is N mod 13, M2 is (N - 1) // 13, 数字カード・絵カード(M,U1), カードの種類(M2,U2), concat_atom([U1,U2],U),!. 数字カード・絵カード(1,'A') :- !. 数字カード・絵カード(10,'T') :- !. 数字カード・絵カード(11,'J') :- !. 数字カード・絵カード(12,'Q') :- !. 数字カード・絵カード(0,'K') :- !. 数字カード・絵カード(N,N). カードの種類(0,s) :- !. カードの種類(1,h) :- !. カードの種類(2,d) :- !. カードの種類(3,c) :- !. トランプを切るようにならびを切る(0,_要素数,L,L) :- !. トランプを切るようにならびを切る(N,_要素数,L,X) :- M1 is (random mod _要素数) + 1, M2 is (random mod _要素数) + 1, \+(M1=M2), swap_nth(M1,M2,L,L1), N2 is N - 1, トランプを切るようにならびを切る(N2,_要素数,L1,X),!. トランプを切るようにならびを切る(N,_要素数,L,X) :- トランプを切るようにならびを切る(N,_要素数,L,X),!. swap_nth(M,N,L1,L2) :- list_nth(M,L1,A), list_nth(N,L1,B), swap(A,B,L1,L2),!. swap(A,B,L,LX) :- append(L1,[A|L2],[B|L3],L), append(L1,[B|L2],[A|L3],LX),!. swap(A,B,L,LX) :- append(L1,[B|L2],[A|L3],L), append(L1,[A|L2],[B|L3],LX),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1260532772/388 # # [1] 授業単元:計算機入門及び演習 # [2] 問題文(含コード&リンク):http://ime.nu/ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10300.txt # http://ime.nu/prolog.asia/txt/10300.txt # レポート課題 # 以下の問題を解くプログラムをC言語を用いて作成しなさい. # # AさんとBさんは点数が書かれたカードを何枚か持っている. AさんのカードとBさんのカードを1枚ずつ交換して,Aさんの持つカードの合計点数とBさんの持つカード合計点数が等しくなるようにしたい.このときどのカードとどのカードを交換したらよいか.ただし,カードを交換しなくても合計点数が等しい場合でも,必ずカードの交換を行うものとする. # # 入力は,いくつかのデータセットからなる.各データセットは次の形式で与えられる. # # n m # s1 # s2 # ... # sn # sn+1 # sn+2 # ... # sn+m # # 各データセットの最初の行は空白ひとつで区切られたふたつの数 n と m を含み, n はAさんのカードの枚数,m はBさんのカードの枚数を表す.続く n+m 行には,各カードの点数が 1 行にひとつずつ並ぶ.最初の n 個の点数 (s1 から sn まで) はAさんのカードの点数,残りの m 個の点数 (sn+1 から sn+m まで) はBさんのカードの点数を表す. n および m は 100 以下の正の整数とし,カードの点数は 0 以上 100 以下の整数値とする.入力の終わりは,空白ひとつで区切られたふたつの 0 を含む 1 行で示される. # # 各データセットに対し,Aさん,Bさんの交換前のすべてのカードと交換すべき2つのカードを出力すること.形式は特に問わない(実行例を参考にすること).なお,合計を等しくするようなカードの交換の方法が複数ある場合は,交換するカードの点数の和が最小となるもののみを出力すること.また,カードの点数の合計を等しくするような交換が存在しない場合はその旨を出力すること. # # 実行例 # # # nodat000% cat ~j-teru/sample-input.txt # 2 2 # 1 # 5 # 3 # 7 # 6 5 # 3 # 9 # 5 # 2 # 3 # 3 # 12 # 2 # 7 # 3 # 5 # 4 5 # 10 # 0 # 3 # 8 # 1 # 9 # 6 # 0 # 6 # 7 4 # 1 # 1 # 2 # 1 # 2 # 1 # 4 # 2 # 3 # 4 # 3 # 2 3 # 1 # 1 # 2 # 2 # 2 # 2 2 # 5 # 1 # 7 # 3 # 0 0 # nodat000% ./cardchange < ~j-teru/sample-input.txt # Aさんのカード: 1 5 # Bさんのカード: 3 7 # Aさんの1とBさんの3を交換 # # Aさんのカード: 3 9 5 2 3 3 # Bさんのカード: 12 2 7 3 5 # Aさんの3とBさんの5を交換 # # Aさんのカード: 10 0 3 8 # Bさんのカード: 1 9 6 0 6 # 合計を等しくする交換はありません # # Aさんのカード: 1 1 2 1 2 1 4 # Bさんのカード: 2 3 4 3 # Aさんの2とBさんの2を交換 # # Aさんのカード: 1 1 # Bさんのカード: 2 2 2 # 合計を等しくする交換はありません # # Aさんのカード: 5 1 # Bさんのカード: 7 3 # Aさんの1とBさんの3を交換 # # nodat000% 入力したデータセットを一枚交換して合計が一致する組をすべて示す(AL,BL,A,B) :- データセットの入力(N,M,AL,BL), 一枚ずつ全てを交換してみる(N,M,AL,BL,A,B). データセットの入力(N,M,AL,BL) :- get_split_line([' '],[N,M]),\+((N=0,M=0)),'Aの入力'(N,AL),'Bの入力'(M,BL),!. 'Aの入力'(N,AL) :- findall(A,(for(1,_,N),get_integer(A)),AL). 'Bの入力'(M,AL) :- findall(B,(for(1,_,M),get_integer(B)),BL). 一枚ずつ全てを交換してみる(0,M,AL,BL,_,_) :- !,fail. 一枚ずつ全てを交換してみる(N,M,AL,BL,A,B) :- ならびの回転(左方向,1,AL,[A|R1]), 交換して合計が一致する(M,BL,A,B). 一枚ずつ全てを交換してみる(N,M,AL,BL,A,B) :- ならびの回転(左方向,1,AL,AL2), N1 is N - 1, 一枚ずつ全てを交換してみる(N1,M,AL2,BL,A,B). 交換して合計が一致する(0,[A|R1],[B|R2],A,B) :- !,fail. 交換して合計が一致する(M,[A|R1],[B|R2],A,B) :- sum([B|R1],Sum), sum([A|R2],Sum). 交換して合計が一致する(M,[A|R1],[B|R2],A,B) :- ならびの回転(左方向,1,BL,BL2), M1 is M - 1, 交換して合計が一致する(M1,[A|R1],BL2,A,B). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1245853701/244 # # 〔1〕授業単元:C言語 # 〔2〕問題文:http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9601.txt # ・2つの整数型の変数を入れ替える関数 swapを定義して、それを用いて配列中の数字をランダムに入れ替えるプログラムを作りなさい。 # 1から52までの数が順番に入った配列を用意し、十分に入れ替えた結果を表示すること。 # これができた人は、次のように表示を変更しなさい。 # ・ 52個の数字を1〜13、14〜26、27〜39、40〜52の4組に分けて考える # ・ それぞれ1番目から13番目の数字を、A、2、3、4、5、6、7、8、9、T、J、Q、K と表示する(TはTenのT) # 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,2,0,21,22,… # ↓ # A,2,3,4,5,6,7,8,9,T,J,Q,K,A,2,3,4,5,6,7,8,9,T,… # ?これができた人は、次のように表示を変更しなさい。 # ・トランプの4つのスートをアルファベットで表示することにする(スペードは s, ハート #  はh、ダイヤはd、 クラブはc) # ・ 1〜13はスペード(s)、14〜26はハート(h)、27〜39はダイヤ(d)、40〜52はクラブ(c)とする # ・ それぞれの数字をA〜Kとshdcの組合せで表示する # ・ 例:1ならAs(スペードのA)、52ならKc(クラブのK) # As,2s,…..,Ks,Ah,2h,……,Kh,Ad,2d,……,Kd,Ac,2c,…..,Kc swap(A,B,L,LX) :- append(L1,[A|L2],[B|L3],L), append(L1,[B|L2],[A|L3],LX),!. swap(A,B,L,LX) :- append(L1,[B|L2],[A|L3],L), append(L1,[A|L2],[B|L3],LX),!. t319_2(X) :- findall(U,( between(1,52,N), t319_2_1(N,U)),X). t319_2_1(N,U) :- M is N mod 13, '数字カード・絵カード'(M,U). '数字カード・絵カード'(1,'A') :- !. '数字カード・絵カード'(10,'T') :- !. '数字カード・絵カード'(11,'J') :- !. '数字カード・絵カード'(12,'Q') :- !. '数字カード・絵カード'(0,'K') :- !. '数字カード・絵カード'(N,N). トランプの準備(X) :- findall(U,( between(1,52,N), 一枚のカードを作る(N,U)),_整列したカード), トランプを切る(100,_整列したカード,X). 一枚のカードを作る(N,U) :- M is N mod 13, M2 is (N - 1) // 13, 数字カード・絵カード(M,U1), カードの種類(M2,U2), atom_concat(U1,U2,U). カードの種類(0,s). カードの種類(1,h). カードの種類(2,d). カードの種類(3,c). トランプを切る(0,L,L) :- !. トランプを切る(N,L,X) :- M1 is random(52) + 1, M2 is random(52) + 1, swap_nth(M1,M2,L,L1), N2 is N - 1,!, トランプを切る(N2,L1,X). swap_nth(M,N,L1,L2) :- nth1(M,L1,A), nth1(N,L1,B), swap(A,B,L1,L2),!. swap(A,B,L,LX) :- append(L1,[A|L2],[B|L3],L), append(L1,[B|L2],[A|L3],LX),!. swap(A,B,L,LX) :- append(L1,[B|L2],[A|L3],L), append(L1,[A|L2],[B|L3],LX),!. append([],L2,L3,L4) :- append(L2,L3,L4). append([U|L1],L2,L3,[U|L4]) :- append(L1,L2,L3,L4).