このディレクトリの索引

% 以下のサイトは 女王様(_女王様の数,_女王様縦変位順列) :- '1から_女王様の数までの_女王様縦変位順列を取り出す'(_女王様の数,_女王様縦変位順列), どれも他の女王様の角筋に入らない(_女王様縦変位順列). '1から_女王様の数までの_女王様縦変位順列を取り出す'(_女王様の数,_女王様縦変位順列) :- '1から_女王様の数までの自然数ならび'(_女王様の数,_1から_女王様の数までの自然数ならび), 順列(_1から_女王様の数までの自然数ならび,_女王様の数,_女王様縦変位順列). '1から_女王様の数までの自然数ならび'(_女王様の数,_1から_女王様の数までの自然数ならび) :- findall(N,between(1,_女王様の数,N),_1から_女王様の数までの自然数ならび). 順列(L,0,[]) :- !. 順列(L,N,[A|R2]) :- select(A,L,R), M is N - 1, 順列(R,M,R2). どれも他の女王様の角筋に入らない([]). どれも他の女王様の角筋に入らない([_女王様|_残り女王様ならび]) :- どれも他の女王様の角筋に入らない(_残り女王様ならび), 角筋に入らない(_女王様,_残り女王様ならび,1). 角筋に入らない(_,[],_). 角筋に入らない(_女王様の縦変位,[_別のある女王様の縦変位|_残り縦変位ならび],_横変位) :- 女王様からの縦変位距離と横変位が一致してはならない(_女王様の縦変位,_別のある女王様の縦変位,_横変位), _横変位_2 is _横変位 + 1, 角筋に入らない(_女王様の縦変位,_残り縦変位ならび,_横変位_2). 女王様からの縦変位距離と横変位が一致してはならない(_女王様の縦変位,_別のある女王様の縦変位,_横変位) :- abs(_別のある女王様の縦変位 - _女王様の縦変位) =\= _横変位. % 以下のサイトは # # 順列をリスト[a1,a2,・・・,an] で表すとき、その転倒数を計算しよう。 # 偶順列(_順列) :- 転倒数が偶数の順列を偶順列という(_順列). 転倒数が偶数の順列を偶順列という(_順列) :- 転倒数(_順列,_転倒数), 偶数(_転倒数). 奇順列(_順列) :- 転倒数が奇数の順列を奇順列という(_順列). 転倒数が奇数の順列を奇順列という(_順列) :- 転倒数(_順列,_転倒数), 奇数(_転倒数). 転倒数(_順列,_転倒数) :- 度数(転倒(_順列,_,_),_転倒数). 転倒(_順列,N,M) :- append(_,[N|R],_順列), append(_,[M|_],R), N > M. 度数(_目標,_度数) :- findall(1,_目標,L), length(L,_度数). 偶数(_整数) :- 0 is _整数 mod 2. 奇数(_整数) :- \+(0 is _整数 mod 2). % 以下のサイトは # 出典 :: C/C++の宿題片付けます 132代目 #72 # [1]授業単元:プログラミング演習 # [2] 1から100000までの数を列挙する。 # nまで書き終わった時点でそれぞれの数字dがtimes[d] (0<=d<=9)回使われていたとする。 # times[d]が小さい順にdを並べて順列を作る。(同じ回数の場合dが大きいほうが後)この順列が最初からそれまでに累積何回変わったか # nが1000の倍数毎に表にして出力(100000まで) # 回数と順位を要素とする構造体配列を使うこと # 整数の文字表現が増えると累計順位が変化する(_n個まで,_順位交代回数) :- 整数の文字表現が増えると累計順位が変化する(1,100000,[[0,'0'],[1,'1'],[0,'2'],[0,'3'],[0,'4'],[0,'5'],[0,'6'],[0,'7'],[0,'8'],[0,'9']],['0','2','3','4','5','6','7','8','9','1'],0,_n個まで,_順位交代回数). 整数の文字表現が増えると累計順位が変化する(Max,Max,_,_,_順位交代回数,Max,_順位交代回数) :- !. 整数の文字表現が増えると累計順位が変化する(N,Max,_,_,_順位交代回数,N,_順位交代回数) :- 0 is N mod 1000. 整数の文字表現が増えると累計順位が変化する(N,Max,LL1,_順位ならび_1,_順位交代回数_1,_n個まで,_順位交代回数) :- 整数の文字表現が増えると累計順位が変化して行く(N,Max,LL1,_順位ならび_1,_順位交代回数_1,_n個まで,_順位交代回数). 整数の文字表現が増えると累計順位が変化して行く(N,Max,LL1,_順位ならび_1,_順位交代回数_1,_n個まで,_順位交代回数) :- 整数の文字表現が増えると(N,N_2,_次の数字ならび), 最新の順位ならび(_次の数字ならび,LL1,LL2,_順位ならび_2), 累計順位が変化して行く(N_2,Max,LL2,_順位ならび_1,_順位ならび_2,_順位交代回数_1,_n個まで,_順位交代回数). 整数の文字表現が増えると(N,N_2,_次の数字ならび) :- succ(N,N_2), number_chars(N_2,_次の数字ならび). 最新の順位ならび(_次の数字ならび,LL1,LL2,_順位ならび_2) :- 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'(_次の数字ならび,LL1,LL2), 順位ならび(LL2,_順位ならび_2). 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'([],LL,LL). 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'(_標本値ならび,LL1,LL) :- 'select/4で鍵管理して標本値の出現度数を加算して行く(但し、[_度数,_標本値]の順に管理される)'(_標本値ならび,LL1,LL). 'select/4で鍵管理して標本値の出現度数を加算して行く(但し、[_度数,_標本値]の順に管理される)'([_標本値|R],LL1,LL) :- 'select/4で鍵管理して標本値の出現度数を加算(但し、[_度数,_標本値]の順に管理される)'(_標本値,LL1,LL2), 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'(R,LL2,LL). 'select/4で鍵管理して標本値の出現度数を加算(但し、[_度数,_標本値]の順に管理される)'(_標本値,LL1,LL2) :- select([_度数_1,_標本値],LL1,[_度数_2,_標本値],LL2), succ(_度数_1,_度数_2). 順位ならび(_度数標本値ならび,_順位ならび) :- '度数・標本値順に整列する'(_度数標本値ならび,_整列した度数標本値ならび), 整列された度数標本値ならびから標本値の順位を取り出す(_整列した度数標本値ならび,_順位ならび). '度数・標本値順に整列する'(_度数標本値ならび,_整列した度数標本ならび) :- sort(_度数標本値ならび,_整列した度数標本ならび). 整列された度数標本値ならびから標本値の順位を取り出す(_整列した度数標本値ならび,_順位ならび) :- findall(_標本値,member([_,_標本値],_整列した度数標本値ならび),_順位ならび). 累計順位が変化して行く(N_2,Max,LL2,_順位ならび_1,_順位ならび_2,_順位交代回数_1,_n個まで,_順位交代回数) :- 順位に変化があった場合だけ順位交代回数を更新する(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2), 整数の文字表現が増えると累計順位が変化する(N_2,Max,LL2,_順位ならび_2,_順位交代回数_2,_n個まで,_順位交代回数). 順位に変化があった場合だけ順位交代回数を更新する(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2) :- '順位に変化があった場合、交代回数が更新される'(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2),!. 順位に変化があった場合だけ順位交代回数を更新する(_,_,_順位交代回数,_順位交代回数). '順位に変化があった場合、交代回数が更新される'(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2) :- '順位に変化があった場合、'(_順位ならび_1,_順位ならび_2), 交代回数が変化する(_順位交代回数_1,_順位交代回数_2). '順位に変化があった場合、'(_順位ならび_1,_順位ならび_2) :- \+(sort(_順位ならび_1,_順位ならび_2)). 交代回数が変化する(_順位交代回数_1,_順位交代回数_2) :- succ(_順位交代回数_1,_順位交代回数_2). % 以下のサイトは # 中学生になるホンガツオ君はいつも学校の成績が悪く、父・海平に怒られます。 # 今回も中間テストでどれもひどい点数をとってしまい、海平の雷が落ちるのは間違いありません。 # # 全教科のテスト結果を同時にみせると、海平の怒りは最大級となり、1週間のおやつ抜きとなってしまいます。 # # おやつを毎日食べたいホンガツオ君は、海平の怒りを分散させるために、1日1教科ずつテスト結果をみせていくことを思いつきました。 # # ただ、テスト結果の報告が遅れることで、海平の怒りは日に日に上がっていきます。 # もしテスト結果を隠したりして報告しなかったことが後でバレたら最大級の怒りとなるため、すべての教科のテスト結果をみせた方がよさそうです。 # # 海平の怒りの度合いは教科といつみせるかによっても異ります。 # # たとえば、国語、数学、英語の3教科の点数が40点だった場合、1日1教科ずつみせるならば、3日必要です。 # 海平の怒りについては、ホンガツオ君は長年の経験から、スコア化できています。 # # 教科 点数 海平怒りのスコア初期値 1日目 2日目 3日目 # 国語(Ja) 40 10 1 2 3 # 数学(Ma) 40 10 1 4 6 # 英語(En) 40 10 1 6 9 # # # この例では、国語、数学、英語に対する海平怒りのスコアがすべて10です。 # あとは、何日目にみせるかによって、怒りが初期値に乗算されます。 # # 単純に怒りのスコアが小さい教科順にみせると、トータルの海平から被る怒りの量は以下のようになります。 # (10 * 1) + (10 * 4) + (10 * 9) = 140 # # しかし、3日目に被る怒りの量が大きい教科を先にみせることで、怒りの量は減ります。 # (10 * 1) + (10 * 4) + (10 * 3) = 80 # # # つまり、この場合は、1日目に英語→2日目に数学→3日目に国語(En->Ma->Ja)の順にみせることで、ホンガツオ君が海平から被る怒りの量は最も少ない80ですみます。 # # では、以下の7教科の場合、海平怒りのスコアが最も少なくてすむにはどの教科の順でテスト結果をみせればよいでしょうか? # # プログラミング言語はJavaScriptを使用してください。 # # 教科 点数 海平怒りのスコア初期値 1日目 2日目 3日目 4日目 5日目 6日目 7日目 # 国語(Ja) 15 35 1 1 2 3 5 8 13 # 数学(Ma) 35 15 1 5 9 13 17 21 25 # 英語(En) 30 20 1 5 8 12 15 19 22 # 社会(So) 20 30 1 3 5 7 9 11 13 # 理科(Sc) 25 25 1 2 4 6 8 10 12 # 音楽(Mu) 35 15 1 4 6 9 11 14 16 # 美術(Ar) 25 25 1 2 2 3 5 8 11 # # # 以下、問題のデータを用意しています。コピペして使ってください。 # また必ずしもこのデータを使う必要はありません。 # // 教科データ # var category=['Ja','Ma','En','So','Sc','Mu','Ar']; # // 海平怒りのスコア初期値 # var score=[35,15,20,30,25,15,25]; # // 海平怒りの倍数(7日分 # var multiplier=[ # [1,1,2,3,5,8,13], # [1,5,9,13,17,21,25], # [1,5,8,12,15,19,22], # [1,3,5,7,9,11,13], # [1,2,4,6,8,10,12], # [1,4,6,9,11,14,16], # [1,2,2,3,5,8,11], # ]; # # # ■資料 # answer_ikariscore_JavaScript.txt: # 解答用テキストファイルです。 # # ■解答方法 # 解答用テキストファイル(answer_ikariscore_JavaScript.txt)を完成させ、アップロードしてください。 # ※解答用テキストファイル以外のファイル形式(zipなど)をアップロードした場合は評価対象外となります。 # 毎日一教科ずつ示して怒りを最小にする表示順序(_表示順序) :- 毎日一教科ずつ示して怒りを(_表示順候補ならび), 最小にする表示順序(_表示順候補ならび,_表示順序). 毎日一教科ずつ示して怒りを(_表示順候補ならび) :- 教科と怒りの相関表から教科ならびを得て表示順候補ならびを得る(_表示順候補ならび). 教科と怒りの相関表から教科ならびを得て表示順候補ならびを得る(_表示順候補ならび) :- 教科と怒りの相関表から教科ならびを得て(_教科ならび), 表示順候補ならびを得る(_教科ならび,_表示順候補ならび). 教科と怒りの相関表から教科ならびを得て(_教科ならび) :- findall(_教科,教科と怒りの相関表(_教科,_,_,_),_教科ならび). 表示順候補ならびを得る(_教科ならび,_表示順候補ならび) :- findall([_怒り指数,_表示順序候補],( 表示順による怒り指数(_教科ならび,_表示順序候補,_怒り指数)), _表示順候補ならび). 表示順による怒り指数(_教科ならび,_表示順序候補,_怒り指数) :- 順列(_教科ならび,7,_表示順序候補), 怒り評価(_表示順序候補,_怒り指数). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). 怒り評価(_順序候補,_怒り指数) :- findsum(_怒りの点数,( 順序候補から教科を取り出し怒りの点数を計算する(_順序候補,_怒りの点数)),_怒り指数). 順序候補から教科を取り出し怒りの点数を計算する(_順序候補,_怒りの点数) :- 順序候補から教科を取り出し(_順序候補,_nth1,_教科), 怒りの点数を計算する(_nth1,_教科,_怒りの点数). 順序候補から教科を取り出し(_順序候補,_nth1,_教科) :- nth1(_nth1,_順序候補,_教科). 怒りの点数を計算する(_nth1,_教科,_怒りの点数) :- 教科と怒りの相関表(_教科,_,_初期値,L), nth1(_nth1,L,_怒りの倍数), _怒りの点数 is _初期値 * _怒りの倍数. findsum(A,P,Sum) :- findall(A,P,L), sum_list(L,Sum). 教科と怒りの相関表('国語(Ja)',15,35,[1,1,2,3,5,8,13]). 教科と怒りの相関表('数学(Ma)',35,15,[1,5,9,13,17,21,25]). 教科と怒りの相関表('英語(En)',30,20,[1,5,8,12,15,19,22]). 教科と怒りの相関表('社会(So)',20,30,[1,3,5,7,9,11,13]). 教科と怒りの相関表('理科(Sc)',25,25,[1,2,4,6,8,10,12]). 教科と怒りの相関表('音楽(Mu)',35,15,[1,4,6,9,11,14,16]). 教科と怒りの相関表('美術(Ar)',25,25,[1,2,2,3,5,8,11]). 最小にする表示順序(LL,_表示順序) :- once(最小の怒り指数(LL,_最小の怒り指数)), member([_最小の怒り指数,_表示順序],LL). 最小の怒り指数(LL,_最小の怒り指数) :- select([_最小の怒り指数|_],LL,R), 'Rの中に_最小の怒り指数より小さいものはない'(R,_最小の怒り指数). 'Rの中に_最小の怒り指数より小さいものはない'(R,_最小の怒り指数) :- forall(member([_怒り指数|_],R),_怒り指数 >= _最小の怒り指数). % 以下のサイトは # お題: # 例:数列[3,1,-7,1,5]について、 # ->[4,-3,-2,3] (累計) # ->12 (絶対値の合計) # のように計算する。 # 最初の数列の並び順を変えると、最後の合計計も変わる。 # 任意数列について、上記合計が最小になるように並び替える関数を作成 '例:数列[3,1,-7,1,5]について、 ->[4,-3,-2,3] (累計) ->12 (絶対値の合計) のように計算する。 任意数列について、上記合計が最小になるように並び替える'(_数列,_最小となる数列) :- 絶対値の合計が最小になるように並び替える(_数列,_,_最小となる数列). 絶対値の合計が最小になるように並び替える(_数列,_最小の絶対値,_絶対値の合計が最小となる数列):- length(_数列,_要素数), setof([_絶対値の合計,_順列], [_数列,_要素数,_順列,_絶対値の合計] ^ 並べ替える(_数列,_要素数,_順列,_絶対値の合計),_絶対値_数列ならび), 絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_最小の絶対値,_絶対値の合計が最小となる数列). 並べ替える(_数列,_要素数,_順列,_絶対値の合計):- 順列(_数列,_要素数,_順列), 絶対値の合計(_順列,_絶対値の合計). 絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_最小の絶対値,_絶対値の合計が最小となる数列) :- findmin(_絶対値,( member([_絶対値,_],_絶対値_数列ならび)),_最小の絶対値), member([_最小の絶対値,_絶対値の合計が最小となる数列],_絶対値_数列ならび). 絶対値の合計([_値],_絶対値の合計) :- _絶対値の合計 is abs(_値). 絶対値の合計(_値ならび,_絶対値の合計) :- 累計の途中経過得ながらそれを縮退して行って絶対値を得る(_値ならび,_絶対値の合計). 累計の途中経過得ながらそれを縮退して行って絶対値を得る(_値ならび,_絶対値の合計) :- 累計の途中経過を得る(_値ならび,_累計の途中経過ならび), 要素の絶対値の合計(_累計の途中経過ならび,_絶対値の合計). 累計の途中経過を得る([_],[]). 累計の途中経過を得る([_数_1,_数_2|R1],[_累計の途中経過|R2]) :- _累計の途中経過 is _数_1 + _数_2, 累計の途中経過を得る([_累計の途中経過|R1],R2). 要素の絶対値の合計(_累計の途中経過ならび,_絶対値の合計) :- findsum(_絶対値,( member(_値,_累計の途中経過ならび), _絶対値 is abs(_値)),_絶対値の合計). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 順列(_,0,[]). 順列(L1,N,[A|R]) :- select(A,L1,R1), N_1 is N - 1, 順列(R1,N_1,R). findmin(V,P,Min) :- findall(V,P,L), min_list(L,Min). findsum(V,P,Sum) :- findall(V,P,L), sum_list(L,Sum). % 以下のサイトは 軸要素の選定([_最初の位置の値|R],_軸要素,_残りならび) :- 軸要素の選定([_最初の位置の値|R],_軸要素), select(_軸要素,[_最初の位置の値|R],_残りならび),!. 軸要素の選定([_最初の位置の値|R],_軸要素) :- 中間位置の値([_最初の位置の値|R],_中間位置の値), last([_最初の位置の値|R],_最終位置の値), 三値の中央値(_最初の位置の値,_中間位置の値,_最終位置の値,_軸要素). 中間位置の値(L,_中間位置の値) :- length(L,Length), Length_1 is Length // 2, length(L1,Length_1), append(L1,[_中間位置の値|_],L). 三値の中央値(_1,_2,_3,_中央値) :- 順列([_1,_2,_3],3,[_中央値,A,B]), A @>= _中央値, B @=< _中央値. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), succ(M,N), 順列(Z,M,X). % 以下のサイトは # 出典 :: C/C++の宿題片付けます 152代目 #33 # [1] 授業単元: プログラミング # [2] 問題文(含コード&リンク):1から15の数字から5個の数字を取って同じ数字が # 使われない並びの通りをすべて表示させなさい。 # 例:1 2 3 4 5 # 1 3 2 4 5 # 11 12 10 9 8 # :- op(750,xfx,すべて). '1から15の数字から5個の数字を取って同じ数字が使われない並びの通りをすべて表示させる' :- '1から15の数字から'(_1から15の数字), '5個の数字を取って同じ数字が使われない並びの通りをすべて表示させる'(_1から15の数字). '1から15の数字から'(_1から15の数字) :- findall(N,between(1,15,N),_1から15の数字). '5個の数字を取って同じ数字が使われない並びの通りをすべて表示させる'(_1から15の数字) :- 同じ数字が使われない並びの通りを(_1から15の数字,5,_同じ数字が使われない並び) すべて 表示させる(_同じ数字が使われない並び). 同じ数字が使われない並びの通りを(_1から15の数字,5,_同じ数字が使われない並び) :- 順列(_1から15の数字,5,_同じ数字が使われない並び). 表示させる(_同じ数字が使われない並び) :- atomic_list_concat(_同じ数字が使われない並び,' ',_表示文字列), writef('%w\n',[_表示文字列]). P すべて Q :- forall(P,Q). 順列(_,0,[]). 順列(L1,N,[A|L2]) :- select(A,L1,R), succ(M,N), 順列(R,M,L2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/33 # # [1] 授業単元: プログラミング # [2] 問題文(含コード&リンク):1から15の数字から5個の数字を取って同じ数字が # 使われない並びの通りをすべて表示させなさい。 # 例:1 2 3 4 5 # 1 3 2 4 5 # 11 12 10 9 8 # '1から15の数字から5個の数字を取って同じ数字が使われない並びの通りをすべて表示させる' :- forall(順列([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],5,L),表示させる(L)). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), succ(M,N), 順列(Z,M,X). 表示させる(L) :- atomic_list_concat(L,' ',_表示文字列), writef('%w\n',[_表示文字列]). % 以下のサイトは 'コールユーブンゲン No.45 a) の階名'(['ミ-1','ミ-1','ド-1','ソ-1','ファ-1','ミ-1','ファ-1','レ-1','ラ-1','ソ-1','ファ-1','ソ-1','ミ-1','シ-1','ド-2','ファ-1','ラ-1','レ-1','ファ-1','シ-0','ソ-1','ファ-1','ミ-1','ド-1','ソ-1','ファ-1','ミ-1','ラ-1','ファ-1','ド-2','シ-1','ラ-1','ソ-1','ド-2','ミ-1','ラ-1','レ-1','ファ-1','シ-0','レ-1','ソ-1','ド-1','ミ-1','ド-2','シ-1','ラ-1','ド-2','ラ-1','シ-1','ミ-1','シ-1','ド-2','シ-1','ラ-1','ソ-1','ファ-1','ラ-1','ファ-1','ソ-1','ド-1','ソ-1','ラ-1','シ-1','ド-2','ソ-1','レ-2','シ-1','ド-2','ラ-1','ド-2','ラ-1','シ-1','ラ-1','ミ-1','レ-1','ラ-1','ソ-1','ラ-1','ファ-1','ミ-1','ソ-1','ド-1','ド-1','レ-1','ミ-1','ファ-1','ソ-1','ラ-1','ファ-1','ド-2','ラ-1','ソ-1','ファ-1','ラ-1','レ-1','レ-1','ミ-1','ファ-1','ソ-1','ラ-1','シ-1','ソ-1','レ-2','ド-2','シ-1','ド-2','ミ-1','シ-1','ド-2','シ-1','ラ-1','ド-1','ソ-1','ラ-1','ソ-1','ファ-1','ラ-1','ミ-1','ファ-1','ド-1','レ-1','シ-0','レ-1','ソ-1','ド-1']). 'この練習曲がコールユーブンゲンの代表曲だという根拠として、音程の出現数が最も多いことが挙げられる。それではそのことを示す資料を作っておくことにしよう。' :- 'コールユーブンゲン No.45 a) の音程出現表'. 'コールユーブンゲン No.45 a) の音程出現表' :- forall(('コールユーブンゲン No.45 a) に出現する音程とその出現数'(A,B,_出現数),_出現数 > 0), writef('%t,%t,%t\n',[A,B,_出現数])). 'コールユーブンゲン No.45 a) に出現する音程とその出現数'(A,B,_出現数) :- 'コールユーブンゲン No.45 a) に出現する音程と'(L,A,B), その出現数(L,A,B,_出現数). 'コールユーブンゲン No.45 a) に出現する音程と'(L,A,B) :- 'コールユーブンゲン No.45 a) の階名'(L), setof(A,member(A,L),L2), 順列(L2,2,[A,B]). その出現数(L,A,B,_出現数) :- 度数(append(_,[A,B|_],L),_出現数). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). 度数(_目標,_度数) :- findall(1,_目標,L), length(L,_度数). % 以下のサイトは ペア数の実装(0,0). ペア数の実装(X,Y) :- nth1(N,_,_), 'Nを1から増加しながら0-Nの内2要素を取り2項の合計がNであるような重複順列を生成'(N,X,Y). 'Nを1から増加しながら0-Nの内2要素を取り2項の合計がNであるような重複順列を生成'(N,X,Y) :- findall(M,between(0,N,M),L), 重複順列(L,2,[X,Y]), N is X + Y. 重複順列(L,0,[]). 重複順列(L,N,[A|R3]) :- N > 0, member(A,L), N_1 is N - 1, 重複順列(L,N_1,R3). % 以下のサイトは ペア数の実装(0,0). ペア数の実装(X,Y) :- nth1(N,_,_), findall(M,between(0,N,M),L), 重複順列(L,2,[X,Y]), N is X + Y. 重複順列(L,0,[]). 重複順列(L,N,[A|R3]) :- N > 0, member(A,L), N_1 is N - 1, 重複順列(L,N_1,R3). % 以下のサイトは ペア数の実装(0,0). ペア数の実装(X,Y) :- nth1(N,_,_), findall(M,between(0,N,M),L), 重複順列(L,2,[X,Y]), N is X + Y. 重複順列(L,0,[]). 重複順列(L,N,[A|R3]) :- N > 0, member(A,L), N_1 is N - 1, 重複順列(L,N_1,R3). %%%%%%%%%%%%%%%%%%%% ?- ペア数の実装(X,Y). X = Y, Y = 0 ; X = 0, Y = 1 ; X = 1, Y = 0 ; X = 0, Y = 2 ; X = Y, Y = 1 ; X = 2, Y = 0 ; X = 0, Y = 3 ; X = 1, Y = 2 ; X = 2, Y = 1 ; X = 3, Y = 0 ; X = 0, Y = 4 ; X = 1, Y = 3 ; X = Y, Y = 2 ; X = 3, Y = 1 ; X = 4, Y = 0 ; X = 0, Y = 5, ・・・ % 以下のサイトは % [1] 授業単元:C言語演習課題 % http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9422.txt % 問題 % 年と月を「YYYY/MM」と入力し、入力された月のカレンダーを表示しなさい。 % % 1752年10月以前、及び10000年1月以降はエラーを返す。 % % 出力形式は以下のとおり % ・1行目は該当月の1日が月曜日でなければ、前月の最終月曜日から表示。 % ・該当月の最終日が日曜日でなければ、翌月の第1日曜日まで表示。 % ・6行目の表示が必要ない場合は表示しない。 % % うるう年判定は以下のとおり % ・年が4で割り切れる年はうるう年。 % ・年が100で割り切れる年はうるう年でない。 % ・年が400で割り切れる年はうるう年である。 % % [出力例] % 年月日を入力:2009/07 % % 月 火 水 木 金 土 日 % 29 30 01 02 03 04 05 % 06 07 08 09 10 11 12 % 13 14 15 16 17 18 19 % 20 21 22 23 24 25 26 % 27 28 29 30 31 01 02 課題のカレンダー(_年/_月) :- not((_年/_月 >= 1752/10,_年/_月 =< 10000/1)), write('エラー: 入力された年月は範囲を逸脱しています\n'),!. 課題のカレンダー(_年/_月) :- _年/_月 @=< 2009/6,!, 曜日検索(_日付,_曜日,2009/6/13,土曜), _日付=_年/_月/1, 課題のカレンダー表示(_日付,_曜日). 課題のカレンダー(_年/_月) :- _年/_月 @>= 2009/6,!, 曜日検索(2009/6/13,土曜,_日付,_曜日), _日付=_年/_月/1, 課題のカレンダー表示(_日付,_曜日). 課題のカレンダー表示(_年/_月/_日,月曜) :- 日付候補を得る(_年/_月/_日,_年/_月/_日,月曜,_日付整数ならび), 課題のカレンダー見出し表示, 課題のカレンダー週表示(_日付整数ならび). 課題のカレンダー表示(_年/_月/_日,_曜日) :- not(_曜日=月曜), 前週の月曜日(_年/_月/_日,_曜日,_前週の月曜日), 日付候補を得る(_年/_月/_日,_前週の月曜日,月曜,_日付整数ならび), 課題のカレンダー見出し表示, 課題のカレンダー週表示(_日付整数ならび). 前週の月曜日(_年/_月/_日,_曜日,_前週の月曜日) :- 曜日検索(_前週の月曜日,_前週の曜日,_年/_月/_日,_曜日), _前週の曜日 = 月曜,!. 日付候補を得る(_年/_月/_日,_起点日付,_曜日,_日付整数ならび) :- findall(_日付,( 曜日(_起点日付,_曜日,_日付2,_),(_日付2=_年2/_月2/7,_年2/_月2 @> _年/_月,!,fail;true)),_日付整数ならび). 課題のカレンダー週表示(_日付整数ならび) :- n個組(7,_日付整数ならび,_7個組), 月曜から日曜までヘッドゼロサプライで表示(_7個組). 月曜から日曜までヘッドゼロサプライで表示([_年/_月/_日]) :- ヘッドゼロサプライ(2,_日,_日付文字列), write_formatted('%t\n',[_日文字列]),!. 月曜から日曜までヘッドゼロサプライで表示([_年/_月/_日|R]) :- ヘッドゼロサプライ(2,_日,_日付文字列), write_formatted('%t ',[_日付文字列]), 月曜から日曜までヘッドゼロサプライで表示(R). 課題のカレンダー見出し表示 :- write_formatted('月 火 水 木 金 土 日\n'). 曜日検索(_日付,_曜日,_今日,_今日の曜日) :- var(_日付), var(_曜日), 前日・今日(_日付,_曜日,_今日,_今日の曜日). 曜日検索(_日付,_曜日,_今日,_今日の曜日) :- var(_日付), var(_曜日), 前日・今日(_前日,_前日の曜日,_今日,_今日の曜日), 曜日検索(_日付,_曜日,_前日,_前日の曜日). 曜日検索(_今日,_今日の曜日,_日付,_曜日) :- var(_日付), var(_曜日), 前日・今日(_今日,_今日の曜日,_日付,_曜日). 曜日検索(_今日,_今日の曜日,_日付,_曜日) :- var(_日付), var(_曜日), 前日・今日(_今日,_今日の曜日,_翌日,_翌日の曜日), 曜日検索(_翌日,_翌日の曜日,_日付,_曜日). '曜日'(_日付,_曜日,_日付,_曜日) :- ! . '曜日'(_日付1,_曜日1,_日付2,_曜日2) :- _日付1 @> _日付2, '前日・今日'(_日付3,_曜日3,_日付1,_曜日1), '曜日'(_日付3,_曜日3,_日付2,_曜日2) . '曜日'(_日付1,_曜日1,_日付2,_曜日2) :- _日付1 @< _日付2, '前日・今日'(_日付1,_曜日1,_日付3,_曜日3), '曜日'(_日付3,_曜日3,_日付2,_曜日2) . 前日・今日(_前日の年/12/31,_前日の曜日,_年/1/1,_曜日) :- 一つ違い(_前日の年,_年), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/2/29,_前日の曜日,_年/3/1,_曜日) :- うるう年(_年), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/2/28,_前日の曜日,_年/3/1,_曜日) :- not(うるう年(_年)), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/_前月/30,_前日の曜日,_年/_月/1,_曜日) :- 一つ違い(_前月,_月), member(_前月,[4,6,9,11]), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/_前月/31,_前日の曜日,_年/_月/1,_曜日) :- 一つ違い(_前月,_月), member(_前月,[1,3,5,7,8,10,12]), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/_月/_前日,_前日の曜日,_年/_月/_日,_曜日) :- 一つ違い(_前日,_日), 曜日連鎖(_前日の曜日,_曜日),!. 一つ違い(M,N) :- integer(M),!, N is M + 1. 一つ違い(M,N) :- integer(N),!, M is N - 1. うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100,!,fail. うるう年(_年) :- 0 is _年 mod 4,!. うるう年(_年) :- not(0 is _年 mod 4),fail. 曜日連鎖(月曜,火曜). 曜日連鎖(火曜,水曜). 曜日連鎖(水曜,木曜). 曜日連鎖(木曜,金曜). 曜日連鎖(金曜,土曜). 曜日連鎖(土曜,日曜). 曜日連鎖(日曜,月曜). n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. ヘッドゼロサプライ(N桁,_整数,_ヘッドゼロ整数文字列) :- number_chars(_整数,_数字ならび), ヘッドゼロサプライ_1(N桁,_数字ならび,_ヘッドゼロ整数文字ならび), concat_atom(_ヘッドゼロ整数文字ならび,_ヘッドゼロ整数文字列),!. ヘッドゼロサプライ_1(N桁,L,L) :- length(L,N桁),!. ヘッドゼロサプライ_1(N桁,L,['0'|R]) :- M桁 is N桁 - 1, ヘッドゼロサプライ_1(M桁,L,R). # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1200175247/550 # # [1] 授業単元: Ruby演習 [2] 問題文、http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9426.txt # Rubyの問題がわかりません 助けてください # # (1)曜日を表す英語と日本語との対応を表すハッシュwdayを定義しなさい # # p wday["sunday"] #=> "日曜日" # p wday["monday"] #=> "月曜日" # p wday["saturday"] #=> "土曜日" # # (2)ハッシュのメソッドを使って(1)のハッシュwdayのペアの数を数えなさい # # (3)eachメソッドと(1)のハッシュwdayを使って以下の文字列を出力させてくださ い。 # 「sunday」は日曜日のことです。 # 「monday」は月曜日のことです。 # # (4)ハッシュには配列の%wのようなものがありません。そこで、空白とタブと改行(正 規表現で定義するなら「/\uff3cs+/」)で区切られた文字列をハッシュに変換するメソ ッドstr2hashを定義してください。 # # p str2hash("bule 青 white 白\uff3cnred赤"); # #=> {"bule"=>"青", "white"=>"白", "red"=>"赤"} :- op(450,xfx,(=>)). % (1) wday({ "sunday" => "日曜日","monday" => "月曜日","saturday" #=> "土曜日"}). % (2) hash_count(Hashname,Count) :- functor(P,Hashname,1), call(P), arg(1,P,H), count(H,Count). count(','(A,B),Count) :- count(B,Count2), Count is Count2 + 1. count(A,1). % (3) ?- each(wday.A=>B),write_formatted('「%t」は%tのことです。\n',[A,B]),fail;true. each(Hashname.Key=>Value) :- functor(P,Hashname,1), arg(1,P,V), each(V,Key=>Value). each(','(Key=>Value,B),Key=>Value). each(','(_,B),Key=>Value) :- each(B,Key=>Value). each(Key=>Value,Key=>Value). % (4) str2hash(Atom,Hash) :- split(Atom,[' ','\t','\n'],L), findall(U,n個組(2,L,U),L2), hashを成長させる(L2,Hash). hashを成長させる([A,B],{ A=>B }) :- !. hashを成長させる([[A,B]|R], { (A=>B,R2) }) :- hashを成長させる(R,{ R2 }). n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/103 # # 【質問テンプレ】 # [1] 授業単元: C言語演習 # [2] 問題文(含コード&リンク): http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9753.txt # 2.入力された年月の1日が何曜日かを調べる。 #   曜日のチェックはZellerの公式を使用する。Zellerの公式は、 #    #   曜日を表す値=(y + [ y / 4 ] - [ y / 100 ] + [ y / 400 ] + [ (( 13 * m ) + 8 ) / 5 ] + d ) % 7 # #           ※ 上記の公式中の y は年、 m は月、 d は日を表し、 #             []はその数を越えない最大の整数を表す。(例: [13.6]は13になる) # #   で、曜日を表す値は次のようになっている。 # #     日曜日 = 0, 月曜日 = 1, 火曜日 = 2, 水曜日 = 3, # # 木曜日 = 4, 金曜日 = 5, 土曜日 = 6, # #   ※但し、1月と2月は前年の13月14月として計算するものとする。 % (1) 年月の入力 年月入力処理(_年,_月) :- 年入力処理(_年), 月入力処理(_月). % (2) 曜日計算 :- op(450,xfx,が),op(500,xfx,であり),op(600,xfx,ならば),op(450,xfx,は). 'Zellerの公式'(年 が Y であり 月 が M であり 日 が D ならば 曜日を表す値 は (Y + Y // 4 - Y // 100 + Y // 400 + ((( 13 * M ) + 8 ) // 5 ) + D ) mod 7). 曜日計算処理(_年,_月,_日,_曜日) :- 'Zellerの公式を用いて曜日を得る'(_年,_月,_日,_曜日). 'Zellerの公式を用いて曜日を得る'(_年,_月,_日,_曜日) :- 'Zellerの公式を用いて曜日を表す値を得る'(_年,_月,_日,_曜日を表す値), 曜日を表す値(_曜日を表す値,_曜日). 'Zellerの公式を用いて曜日を表す値を得る'(_年,1,_日,_曜日を表す値) :- _前年 is _年 - 1, 'Zellerの公式を用いて曜日を表す値を得る'(_前年,13,_日,_曜日を表す値),!. 'Zellerの公式を用いて曜日を表す値を得る'(_年,2,_日,_曜日を表す値) :- _前年 is _年 - 1, 'Zellerの公式を用いて曜日を表す値を得る'(_前年,14,_日,_曜日を表す値),!. 'Zellerの公式を用いて曜日を表す値を得る'(_年,_月,_日,_曜日を表す値) :- _年=Y,_月=M,_日=D, 'Zellerの公式'(年 が Y であり 月 が M であり 日 が D ならば 曜日を表す値 は _Zellerの公式), _曜日を表す値 is _Zellerの公式,!. 曜日を表す値(0,日曜). 曜日を表す値(1,月曜). 曜日を表す値(2,火曜). 曜日を表す値(3,水曜). 曜日を表す値(4,木曜). 曜日を表す値(5,金曜). 曜日を表す値(6,土曜). % (3) カレンダー表示 カレンダー表示 :- 年月入力処理(_年,_月), 'Zellerの公式を用いて曜日を表す値を得る'(_年,_月,1,_曜日を表す整数値), カレンダー表示データ編集(_年,_月,_曜日を表す整数値,_カレンダー表示文字列ならび), 要素に空白を挿入して全行表示(_カレンダー表示文字列ならび). カレンダー表示データ編集(_年,_月,_各月1日の曜日を表す整数値,_カレンダー表示文字列ならび) :- 年月文字列編集処理(_年,_月,_年月文字列), 月日数(_年,_月,_月日数), findall(S,for(1,N,_月日数),ヘッドゼロサプレス(2,N,S)),_表示日ならび), Length is _月日数 + _各月1日の曜日を表す整数値, M is (7 - (Length mod 7)), '7個組ならび'(Length,M,_表示日ならび,_7個組ならび), 見出しならび(_年月文字列,_見出しならび), append(_見出しならび,_7個組ならび,_カレンダー表示文字列ならび). 見出しならび(_年月文字列,[[_年月文字列],[日,月,火,水,木,金,土]]). '7個組ならび'(Length,0,_表示日ならび,_7個組ならび) :- length(L0,Length), すべての要素が(L0,' '), append(L0,_表示日ならび,L), '7個組'(L,_7個組ならび),!. '7個組ならび'(Length,M,_表示日ならび,_7個組ならび) :- not(M=0), length(L0,Length), すべての要素が(L0,' '), length(L2,M), すべての要素が(L2,' '), append(L0,_表示日ならび,L2,L), '7個組'(L,_7個組ならび),!. うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100,!,fail. うるう年(_年) :- 0 is _年 mod 4,!. うるう年(_年) :- not(0 is _年 mod 4),fail. 月日数(_年,2,29) :- うるう年(_年),!. 月日数(_年,2,28) :- not(うるう年(_年)),!. 月日数(_,_月,30) :- member(_月,[4,6,9,11]). 月日数(_,_月,31) :- member(_月,[1,3,5,7,8,10,12]). % (4) 基礎述語の定義 年入力処理(_年) :- write('表示したいカレンダーは西暦何年 ? '), get_line(_行), 年入力処理の二(_行,_年), 年入力検査(_年),!. 年入力処理(_年) :- 年入力処理(_年). 年入力処理の二(_行,_年) :- atom_to_term(_行,_年), integer(_年),!. 年入力処理の二(_行,_年) :- write_formatted('この入力[ %t ]は整数ではありません\n',[_行]), fail. 年入力検査(_年) :- _年 >= 1583, _年 =< 3999,!. 年入力検査(_年) :- write_formatted('この年を表す整数%tは不正です\n',[_年]), fail. 月入力処理(_月) :- write('月は ? '), get_line(_行), 月入力処理の二(_行,_月), 月入力検査(_月),!. 月入力処理(_月) :- 月入力処理(_月). 月入力処理の二(_行,_月) :- atom_to_term(_行,_月,_), integer(_月),!. 月入力処理の二(_行,_月) :- write_formatted('この入力[ %t ]は整数ではありません\n',[_行]), fail. 月入力検査(_月) :- _月 >= 1, _月 =< 12,!. 月入力検査(_月) :- write_formatted('この月を表す整数%tは不正です\n',[_月]), fail. 日付文字列編集処理(_年,_月,_日,_日付文字列) :- ヘッドゼロサプライ(2,_年,_年文字列), ヘッドゼロサプライ(2,_月,_月文字列), ヘッドゼロサプライ(2,_日,_日文字列), concat_atom([_年文字列,_月文字列,_日文字列],_日付文字列). 年月文字列編集処理(_年,_月,_年月文字列) :- ヘッドゼロサプライ(2,_年,_年文字列), ヘッドゼロサプライ(2,_月,_月文字列), concat_atom([_年文字列,_月文字列],_年月文字列). ヘッドゼロサプライ(N桁,_整数,_ヘッドゼロ整数文字列) :- number_chars(_整数,_数字ならび), ヘッドゼロサプライ_1(N桁,_数字ならび,_ヘッドゼロ整数文字ならび), concat_atom(_ヘッドゼロ整数文字ならび,_ヘッドゼロ整数文字列),!. ヘッドゼロサプライ_1(N桁,L,L) :- length(L,N桁),!. ヘッドゼロサプライ_1(N桁,L,['0'|R]) :- M桁 is N桁 - 1, ヘッドゼロサプライ_1(M桁,L,R). ヘッドゼロサプレス(N桁,_整数,_ヘッド空白整数文字列) :- number_chars(_整数,_数字ならび), ヘッドゼロサプレス_1(N桁,_数字ならび,_ヘッド空白整数文字ならび), concat_atom(_ヘッド空白整数文字ならび,_ヘッド空白整数文字列),!. ヘッドゼロサプレス_1(N桁,L,L) :- length(L,N桁),!. ヘッドゼロサプレス_1(N桁,L,[' '|R]) :- M桁 is N桁 - 1, ヘッドゼロサプレス_1(M桁,L,R). 要素に空白を挿入して全行表示([]) :- !. 要素に空白を挿入して全行表示([L|R]) :- concat_atom(L,' ',_表示行), write_formatted('%t\n',[_表示行]), 要素に空白を挿入して全行表示(R). すべての要素が([],_). すべての要素が([V|R],V) :- すべての要素が(R,V). '7個組'([],[]) :- !. '7個組'([A,B,C,D,E,F,G|R1]),[[A,B,C,D,E,F,G]|R2]) :- '7個組'(R1,R2). n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. not(P) :- \+(P). append([],L1,L2,L) :- append(L1,L2,L) . append([A|R1],L1,L2,[A|R]) :- append(R1,L1,L2,R) . concat_atom([],'') :- !. concat_atom([A],A) :- !. concat_atom([A|R],S) :- concat_atom(R,S1), atom_concat(A,S1,S). concat_atom([],_,'') :- !. concat_atom([A],_,A) :- !. concat_atom([A|R],_区切り文字列,S) :- concat_atom(R,_区切り文字列,S1), atom_concat(A,_区切り文字列,S2), atom_concat(S2,S1,S). # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/157 # # [1] 授業単元: C++ # [2] 問題文(含コード&リンク): # http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9762.txt # # 正数による正方行列のうち、全ての行、列、斜め列の合計が同じであり、 # かつ2回以上使用される数字が存在しないものを魔方陣という。 # 下図に示すa,bに数値を設定したときに、1〜9の整数によって構成される魔方陣を # 出力するプログラムを作成せよ。 # 但し、魔方陣が作成不可能な(a,b)の組み合わせが設定された場合は、「Impossible」 # と出力するとする。 # # la_lb_l__l # l__l__l__l # l__l__l__l # 魔方陣(N枡,A,B,_行列) :- 魔方陣のための行列の生成(N枡,_行列), _行列 = [[A,B|_],_,_], 行の合計が全て一致する(_行列,S), 列の合計が全て一致する(_行列,S), 正方行列の斜め要素の合計が一致する(_行列,S). 魔方陣のための行列の生成(N枡,_行列) :- N2 is N枡 ^ 2, findall(M,for(1,M,N2),NL),!, 順列(NL,N2,_順列数字ならび), findall(_N個組,n個組(N枡,_順列数字ならび,_N個組),_行列). 行の合計が全て一致する([],S) :- !. 行の合計が全て一致する([_行|R],S) :- 魔方陣の加算(_行,0,S), 行の合計が全て一致する(R,S). 列の合計が全て一致する(_行列,S) :- 行列の転置(_行列,_転置行列), 列の合計が全て一致する(_転置行列,S),!. 正方行列の斜め要素の合計が一致する(_正方行列,S) :- length(_行列,Len), 左上から右下方向の合計(1,Len,_正方行列,0,S), 右上から左下方向の合計(1,Len,_正方行列,0,S),!. 左上から右下方向の合計(M,N,_,S,S) :- M > N,!. 左上から右下方向の合計(M,N,_行列,S1,S) :- list_nth(M,_行列,_行), list_nth(M,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 左上から右下方向の合計(M2,N,_行列,S2,S),!. 右上から左下方向の合計(M,N,_,S,S) :- M > N,!. 右上から左下方向の合計(M,N,_行列,S1,S) :- M1 is N - M + 1, list_nth(M1,_行列,_行), list_nth(M1,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 右上から左下方向の合計(M2,N,_行列,S2,S),!. n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. 魔方陣の加算([],X,X) :- !. 魔方陣の加算([A|R],Y,X) :- Z is A + Y, 魔方陣の加算(R,Z,X). # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/566 # # [1] 授業単元:プログラミング # [2] 問題文(含コード&リンク): # 番号と点数を配列に初期化して、それらを # 5段階にランク付けをして、受験番号・ランクを表示するプログラムを作成。 # ランク付けをする部分を関数Rankとして、番号と評価を表示する部分を関数Outputとすること。 # なお、ランクの評価は0〜19点をE、20〜39点をD、40〜59点をC、 # 60〜79点をB、80〜100点をAとする。 # ただし、受験者の数は、50人以下とする。 # 番号と点数は、以下の配列を使用すること。 # 番号 int no[NUMBER]={1,2,3,4,5,6,7,8,9,10}; # 点数 int tensu[NUMBER]={45,21,60,81,70,99,0,10,20,100}; # '問題文の5段階にランク付け'('ランクの評価は0〜19点をE、20〜39点をD、40〜59点をC、 60〜79点をB、80〜100点をAとする。 '). 番号の定義文('番号 int no[NUMBER]={1,2,3,4,5,6,7,8,9,10};'). 点数の定義文('点数 int tensu[NUMBER]={45,21,60,81,70,99,0,10,20,100};'). 'ランクならびの生成'(_ランクならび) :- '問題文の5段階にランク付け'(_ランク定義文), ランクの定義文解析(_ランク定義文,_ランクならび). 番号ならびの生成(_番号ならび) :- 番号の定義文(_番号の定義文), 番号の定義文解析(_番号の定義文,_番号ならび). 点数ならびの生成(_点数ならび) :- 点数の定義文(_点数の定義文), 点数の定義文解析(_点数の定義文,_点数ならび). '5段階にランク付けをして、受験番号・ランクを表示する' :- ランクならびの生成(_ランクならび), 番号ならびの生成(_番号ならび), 点数ならびの生成(_点数ならび), '5段階にランク付けをして、受験番号・ランクを表示する'(_番号ならび,_点数ならび,_ランクならび). '5段階にランク付けをして、受験番号・ランクを表示する'([],[],_). '5段階にランク付けをして、受験番号・ランクを表示する'([_番号|R1],[_点数|R2],_ランクならび) :- append(_,[[_点数下限,_点数上限,_ランク]|_],_ランクならび), _点数 >= _点数下限, _点数 =< _点数上限, writef('受験番号:%t ランク:%t\n',[_番号,_ランク]), '5段階にランク付けをして、受験番号・ランクを表示する'(R1,R2,_ランクならび). ランクの定義文解析(_ランク定義文,_ランクならび) :- 全角数字を半角数字に変換(_ランク定義文,_半角数字変換されたランク定義文), split(_半角数字変換されたランク定義文,[' ','。','、','〜','点を','とする'],L), n個組(3,L,_ランクならび). 全角数字を半角数字に変換(_ランク定義文,_半角数字変換されたランク定義文) :- atom_chars(_ランク定義文,Chars), findall(_文字_1, append(_,[_文字|_],Chars), 全角数字ならば半角数字に変換(_文字,_文字_1)), Chars2), atom_chars(_半角数字変換されたランク定義文,Chars2). 全角数字ならば半角数字に変換([_全角数字|R1],[_半角数字|R2]) :- 全角数字半角数字変換(_全角数字,_半角数字), 全角数字ならば半角数字に変換(R1,R2). 全角数字ならば半角数字に変換([_文字|R1],[_文字|R2]) :- \+(全角数字半角数字変換(_文字,_)), 全角数字ならば半角数字に変換(R1,R2). 全角数字半角数字変換(0,0). 全角数字半角数字変換(1,1). 全角数字半角数字変換(2,2). 全角数字半角数字変換(3,3). 全角数字半角数字変換(4,4). 全角数字半角数字変換(5,5). 全角数字半角数字変換(6,6). 全角数字半角数字変換(7,7). 全角数字半角数字変換(8,8). 全角数字半角数字変換(9,9). 番号の定義文解析(_番号の定義文,_番号ならび) :- split(_番号の定義文,['=',',',';'],[_|_番号ならび]). 点数の定義文解析(_点数の定義文,_点数ならび) :- split(_点数の定義文,['=',',',';'],[_|_点数ならび]). % 以下のサイトは 攪乱順列(_n,_撹乱順列) :- 完全順列(_n,_撹乱順列). 完全順列(_n,_完全順列) :- findall(_m,between(1,_n,_m),L), 完全順列(L,[_],_完全順列). 完全順列([],_,[]). 完全順列(L,Lm,[N|R]) :- select(N,L,L2), \+(length(Lm,N)), 完全順列(L2,[_|Lm],R). % 以下のサイトは 攪乱順列(L,_撹乱順列) :- 完全順列(L,_完全順列). 完全順列(L,_完全順列) :- 完全順列(L,[_],_完全順列). 完全順列([],_,[]). 完全順列(L,Lm,[A|R]) :- select(A,L,L2), \+(length(Lm,A)), 完全順列(L2,[_|Lm],R). % 以下のサイトは 完全順列(L,K,_順列) :- length(Ln,K), 完全順列(L,[_],Ln,_順列). 完全順列(_,_,[],[]). 完全順列(L,Lm,[_|Ln],[A|R]) :- select(A,L,L2), \+(length(Lm,A)), 完全順列(L2,[_|Lm],Ln,R). % 以下のサイトは 完全順列(L,K,_順列) :- 完全順列(L,K,K,_順列). 完全順列(_,_,0,[]). 完全順列(L,M,K,[A|R]) :- select(A,L,L2), \+(A =:= M - K + 1), succ(K_1,K), 完全順列(L2,M,K_1,R). % 以下のサイトは # # 出題場所 :: http://peace.2ch.net/test/read.cgi/tech/1402622093/688 # お題:四国の四つの県を三色で塗り分ける。 # '四国の四つの県を三色で塗り分ける。'(_色_1,_色_2,_色_3) :- forall(順列([_色_1,_色_2,_色_3],2,[A,B]),assertz(隣接(A,B))), 三色で塗り分ける(_香川,_徳島,_愛媛,_高知), writef('香川=%t,徳島=%t,愛媛=%t,高知=%t\n',[_香川,_徳島,_愛媛,_高知]). 三色で塗り分ける(_香川,_徳島,_愛媛,_高知) :- 香川県からの隣接(_香川,_徳島,_愛媛), 徳島県からの隣接(_徳島,_香川,_愛媛,_高知), 愛媛県からの隣接(_愛媛,_香川,_徳島,_高知), 高知県からの隣接(_高知,_徳島,_愛媛). 香川県からの隣接(_香川,_徳島,_愛媛) :- 隣接(_香川,_徳島), 隣接(_香川,_愛媛). 徳島県からの隣接(_徳島,_香川,_愛媛,_高知) :- 隣接(_徳島,_香川), 隣接(_徳島,_愛媛), 隣接(_徳島,_高知). 愛媛県からの隣接(_愛媛,_徳島,_愛媛,_高知) :- 隣接(_愛媛,_香川), 隣接(_愛媛,_徳島), 隣接(_愛媛,_高知). 高知県からの隣接(_高知,_徳島,_愛媛) :- 隣接(_高知,_徳島), 隣接(_高知,_愛媛). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # 出題場所 :: http://peace.2ch.net/test/read.cgi/tech/1402622093/688 # お題:九州の七つの県を三色で塗り分ける。 # '九州の七つの県を三色で塗り分ける。'(_色_1,_色_2,_色_3) :- forall(順列([_色_1,_色_2,_色_3],2,[A,B]),assertz(隣接(A,B))), 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島), writef('福岡=%t,佐賀=%t,長崎=%t,熊本=%t,大分=%t,宮崎=%t,鹿児島=%t\n',[_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島]). 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島) :- 福岡県からの隣接(_福岡,_佐賀,_熊本,_大分), 佐賀県からの隣接(_佐賀,_福岡,_長崎), 長崎県からの隣接(_長崎,_佐賀), 熊本県からの隣接(_熊本,_福岡,_大分,_宮崎,_鹿児島), 大分県からの隣接(_大分,_福岡,_熊本,_宮崎), 宮崎県からの隣接(_宮崎,_大分,_熊本,_鹿児島), 鹿児島県からの隣接(_鹿児島,_宮崎,_熊本). 福岡県からの隣接(_福岡,_佐賀,_熊本,_大分) :- 隣接(_福岡,_佐賀), 隣接(_福岡,_熊本), 隣接(_福岡,_大分). 佐賀県からの隣接(_佐賀,_福岡,_長崎) :- 隣接(_佐賀,_福岡), 隣接(_佐賀,_長崎). 長崎県からの隣接(_長崎,_佐賀) :- 隣接(_長崎,_佐賀). 熊本県からの隣接(_熊本,_福岡,_大分,_宮崎,_鹿児島) :- 隣接(_熊本,_福岡), 隣接(_熊本,_大分), 隣接(_熊本,_宮崎), 隣接(_熊本,_鹿児島). 大分県からの隣接(_大分,_福岡,_熊本,_宮崎) :- 隣接(_大分,_福岡), 隣接(_大分,_熊本), 隣接(_大分,_宮崎). 宮崎県からの隣接(_宮崎,_大分,_熊本,_鹿児島) :- 隣接(_宮崎,_大分), 隣接(_宮崎,_熊本), 隣接(_宮崎,_鹿児島). 鹿児島県からの隣接(_鹿児島,_熊本,_宮崎) :- 隣接(_鹿児島,_熊本), 隣接(_鹿児島,_宮崎). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # 出題場所 :: http://peace.2ch.net/test/read.cgi/tech/1402622093/688 # お題:九州の七つの県を三色で塗り分ける。 # '九州の七つの県を三色で塗り分ける。'(_色_1,_色_2,_色_3) :- forall(順列([_色_1,_色_2,_色_3],2,[A,B]),assertz(隣接(A,B))), 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島), writef('福岡=%t,佐賀=%t,長崎=%t,熊本=%t,大分=%t,宮崎=%t,鹿児島=%t\n',[_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島]). 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島) :- 福岡県からの隣接(_福岡,_佐賀,_熊本,_大分), 佐賀県からの隣接(_佐賀,_福岡,_長崎), 長崎県からの隣接(_長崎,_佐賀), 熊本県からの隣接(_熊本,_福岡,_大分,_宮崎,_鹿児島), 大分県からの隣接(_大分,_福岡,_熊本,_宮崎), 宮崎県からの隣接(_宮崎,_大分,_熊本,_鹿児島), 鹿児島県からの隣接(_鹿児島,_宮崎,_熊本). 福岡県からの隣接(_福岡,_佐賀,_熊本,_大分) :- 隣接(_福岡,_佐賀), 隣接(_福岡,_熊本), 隣接(_福岡,_大分). 佐賀県からの隣接(_佐賀,_福岡,_長崎) :- 隣接(_佐賀,_福岡), 隣接(_佐賀,_長崎). 長崎県からの隣接(_長崎,_佐賀) :- 隣接(_長崎,_佐賀). 熊本県からの隣接(_熊本,_福岡,_大分,_宮崎,_鹿児島) :- 隣接(_熊本,_福岡), 隣接(_熊本,_大分), 隣接(_熊本,_宮崎), 隣接(_熊本,_鹿児島). 大分県からの隣接(_大分,_福岡,_熊本,_宮崎) :- 隣接(_大分,_福岡), 隣接(_大分,_熊本), 隣接(_大分,_宮崎). 宮崎県からの隣接(_宮崎,_大分,_熊本,_鹿児島) :- 隣接(_宮崎,_大分), 隣接(_宮崎,_熊本), 隣接(_宮崎,_鹿児島). 鹿児島県からの隣接(_鹿児島,_熊本,_宮崎) :- 隣接(_鹿児島,_熊本), 隣接(_鹿児島,_宮崎). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # 出題場所 :: http://peace.2ch.net/test/read.cgi/tech/1402622093/688 # お題:九州の七つの県を三色で塗り分ける。 # '九州の七つの県を三色で塗り分ける。'(_色_1,_色_2,_色_3) :- forall(順列([_色_1,_色_2,_色_3],2,[A,B]),assertz(隣接(A,B))), 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島), writef('福岡=%t,佐賀=%t,長崎=%t,熊本=%t,大分=%t,宮崎=%t,鹿児島=%t\n',[_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島]). 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島) :- 隣接(_福岡,_佐賀), 隣接(_佐賀,_福岡), 隣接(_佐賀,_長崎), 隣接(_長崎,_佐賀), 隣接(_福岡,_熊本), 隣接(_熊本,_福岡), 隣接(_福岡,_大分), 隣接(_大分,_福岡), 隣接(_大分,_宮崎), 隣接(_大分,_熊本), 隣接(_熊本,_大分), 隣接(_宮崎,_大分), 隣接(_熊本,_宮崎), 隣接(_宮崎,_熊本), 隣接(_熊本,_鹿児島), 隣接(_鹿児島,_熊本), 隣接(_宮崎,_鹿児島), 隣接(_鹿児島,_宮崎). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # 出題場所 :: http://peace.2ch.net/test/read.cgi/tech/1402622093/688 # お題:九州の七つの県を三色で塗り分ける。 # '九州の七つの県を三色で塗り分ける。'(_色_1,_色_2,_色_3) :- forall(順列([_色_1,_色_2,_色_3],2,[A,B]),assertz(隣接(A,B))), 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島), writef('福岡=%t,佐賀=%t,長崎=%t,熊本=%t,大分=%t,宮崎=%t,鹿児島=%t\n',[_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島]). 三色で塗り分ける(_福岡,_佐賀,_長崎,_熊本,_大分,_宮崎,_鹿児島) :- 隣接(_福岡,_佐賀),隣接(_佐賀,_福岡),隣接(_佐賀,_長崎),隣接(_長崎,_佐賀), 隣接(_福岡,_熊本),隣接(_熊本,_福岡),隣接(_福岡,_大分),隣接(_大分,_福岡), 隣接(_大分,_宮崎),隣接(_大分,_熊本),隣接(_熊本,_大分),隣接(_宮崎,_大分), 隣接(_熊本,_宮崎),隣接(_宮崎,_熊本),隣接(_熊本,_鹿児島),隣接(_鹿児島,_熊本), 隣接(_宮崎,_鹿児島),隣接(_鹿児島,_宮崎). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは 色(赤). 色(青). 色(緑). 色(黄). 区画(a). 区画(b). 区画(c). 区画(d). 隣接(a,b). 隣接(b,d). 隣接(a,c). 隣接(c,d). 塗り絵(_区画の定義順に対応した区画色変数ならび) :- 色組合せならび(_色組合せならび), 区画変数組合せ(_区画の定義順に対応した区画色変数ならび,_区画変数組合せならび), 色合わせ(_色組合せならび,_区画変数組合せならび). 色組合せならび(_色組合せならび) :- findall(_色,色(_色),_色ならび), findall([_色_1,_色_2],( 色を双方向に順列で取る(_色_1,_色_2)), _色組合せならび). 色を順列で双方向に取る(_色_1,_色_2) :- 順列(_色ならび,2,[A,B]), 双方向に取る(A,B,_色_1,_色_2). 双方向に取る(A,B,A,B). 双方向に取る(A,B,B,A). 色合わせ(L1,L2) :- select([A,B],L2,R2), member([A,B],L1), 色合わせ(L1,R2). 区画変数組合せ(_区画変数ならび,_区画変数組合せならび) :- 区画名ならびと区画変数ならびを得る(_区画名ならび,_区画変数ならび), findall([_区画変数_1,_区画変数_2],( 順列(_区画名ならび,2,[_区画名_1,_区画名_2]), 区画変数に変換(_区画名_1,_区画名_2,_区画変数_1,_区画変数_2)), _区画変数組合せならび). 区画名ならびと区画変数ならびを得る(_区画名ならび,_区画変数ならび) :- findall(_区画名,区画(_区画名),_区画名ならび), length(_区画名ならび,_要素数), length(_区画変数ならび,_要素数),!. 区画変数に変換(_区画変数ならび,_区画名_1,_区画名_2,_区画変数_1,_区画変数_2) :- nth1(_nth1,_区画名ならび,_区画名_1), nth1(_nth2,_区画名ならび,_区画名_2), nth1(_nth1,_区画変数ならび,_区画変数_1_1), nth1(_nth2,_区画変数ならび,_区画変数_2_1), 双方向にに変換(_区画変数_1_1,_区画変数_2_1,_区画変数_1,_区画変数_2). 双方向に変換(_区画変数_1_1,_区画変数_2_1,_区画変数_1_1,_区画変数_2_1). 双方向に変換(_区画変数_1_1,_区画変数_2_1,_区画変数_2_1,_区画変数_1_1). % 以下のサイトは 色(赤). 色(青). 色(緑). 色(黄). 区画(a). 区画(b). 区画(c). 区画(d). 隣接(a,b). 隣接(b,d). 隣接(a,c). 隣接(c,d). 区画変数([_1,_2,_3,_4]). 塗り絵(_区画変数ならび) :- 色組合せならび(_色組合せならび), 区画変数組合せ(_区画変数組合せ), 色合わせ(_色組合せならび,_区画変数組合せ). 色組合せならび(_色組合せならび) :- findall(_色,色(_色),_色ならび), findall([_色_1,_色_2],( 色を双方向に順列で取る(_色_1,_色_2)), _色組合せならび). 色を順列で双方向に取る(_色_1,_色_2) :- 順列(_色ならび,2,[A,B]), 双方向に取る(A,B,_色_1,_色_2). 双方向に取る(A,B,A,B). 双方向に取る(A,B,B,A). 色合わせ(_,[]). 色合わせ(L1,L2) :- select([A,B],L2,R2), member([A,B],L1), 色合わせ(L1,R2). 区画変数組合せ(_区画変数ならび,_区画変数組合せならび) :- findall(_区画名,区画(_区画名),_区画名ならび), findall([_区画変数_1,_区画変数_2],( 順列(_区画名ならび,2,[_区画名_1,_区画名_2]), 区画変数に変換(_区画名_1,_区画名_2,_区画変数_1,_区画変数_2)), _区画変数組合せならび). 区画変数に変換(_区画名_1,_区画名_2,_区画変数_1,_区画変数_2) :- nth1(_nth1,_区画名ならび,_区画名_1), nth1(_nth2,_区画名ならび,_区画名_2), nth1(_nth1,_区画変数ならび,_区画変数_1_1), nth1(_nth2,_区画変数ならび,_区画変数_2_1), 双方向にに変換(_区画変数_1_1,_区画変数_2_1,_区画変数_1,_区画変数_2). 双方向に変換(_区画変数_1_1,_区画変数_2_1,_区画変数_1_1,_区画変数_2_1). 双方向に変換(_区画変数_1_1,_区画変数_2_1,_区画変数_2_1,_区画変数_1_1). % 以下のサイトは # 出典 :: 「受験全解算数」日能研発行 p460 灘中入試問題より # # ある工場では3種類の機械A,B,Cを使って、品物Pを生産しています。 # 1時間あたりの生産高はA,B,Cの順に、77個、56個、14個で、1日に # 8時間ずつ運転します。また、一日の生産高は、Cを使わないときは19544個、 # Bを使わないときは、13832個、Aを使わないときは14896個です。このとき、 # 次の問に答えなさい。 # (1) 3種類の機械はそれぞれ何台ありますか。 # (2) 全部の機械を使ったときの品物Pの総生産高を今の2倍にするために # は、Aを25台買い足して、さらにBとCをそれぞれ何台買いたせばよいで # すか。ただし、B,Cどちらも13台より多く買い入れるものとします。 'ある工場では3種類の機械A,B,Cを使って、品物Pを生産しています。 1時間あたりの生産高はA,B,Cの順に、77個、56個、14個で、1日に 8時間ずつ運転します。また、一日の生産高は、Cを使わないときは19544個、 Bを使わないときは、13832個、Aを使わないときは14896個です。このとき、 次の問に答えなさい。 (1) 3種類の機械はそれぞれ何台ありますか。'(Aの台数,Bの台数,Cの台数) :- '一日の生産高は、Cを使わないときは19544個、 Bを使わないときは、13832個、 Aを使わないときは14896個であるとして、 一日のABCの合計の生産高は'(_一日のABCの合計の生産高), Aの台数 is (_一日のABCの合計の生産高-14896) / (77 * 8), Bの台数 is (_一日のABCの合計の生産高-13832) / (56 * 8), Cの台数 is (_一日のABCの合計の生産高-19544) / (14 * 8). '一日の生産高は、Cを使わないときは19544個、 Bを使わないときは、13832個、 Aを使わないときは14896個であるとして、 一日のABCの合計の生産高は'(_一日のABCの合計の生産高) :- 'A,B,Cの合計はA,B,A,C,B,Cの合計の二分の一である', ABACBCの合計 is 19544 + 13832 + 14896, '一日のA,B,Cの合計の生産高A,B,CはA,B,A,C,B,Cの合計の二分の一となる'(ABACBCの合計,_一日のABCの合計の生産高). 'A,B,Cの合計はA,B,A,C,B,Cの合計の二分の一である' :- このならびから同一の要素の対を分解して2つの同一のならびを構成できる(['A','B','A','C','B','C'],L,L), 順列(L,3,['A','B','C']),!. '一日のA,B,Cの合計の生産高はA,B,CはA,B,A,C,B,Cの合計の二分の一となる'(ABACBCの合計,_一日のABCの合計の生産高) :- _一日のABCの合計の生産高 is ABACBCの合計 / 2. このならびから同一の要素の対を分解して2つの同一のならびを構成できる([],[],[]) :- !. このならびから同一の要素の対を分解して2つの同一のならびを構成できる([A|R1],[A|R2],[A|R2]) :- 共通の2つ組がある(A,R1,R1_2), このならびから同一の要素の対を分解して2つの同一のならびを構成できる(R1_2,R2,R2). 共通の2つ組がある(A,[B|R],R) :- A == B,!. 共通の2つ組がある(A,[B|R1],[B|R2]) :- 共通の2つ組がある(A,R1,R2). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # 出典 :: スレ立てるまでもない質問はここで135匹目 #794" # 100という整数があります # これを25から40の範囲の整数として3等分します # 例 # 30, 30, 40 # 35, 35, 30 # 25, 40, 35 '100という整数があります。これを25から40の範囲の整数として3分割します。'(N1,N2,N3) :- findall(N,between(25,40,N),L), 重複順列(L,3,[N1,N2,N3]), 100 is N1 + N2 + N3. 重複順列(L,0,[]). 重複順列(L,N,[A|R3]) :- N > 0, member(A,L), N_1 is N - 1, 重複順列(L,N_1,R3) . % 以下のサイトは # 出典 :: プログラミングのお題スレ3 #623 # お題:1のビットが3個ある二進表記文字列が与えられたとき、次に大きい # 1のビットが3個ある二進表記文字列を求める。 # 例 # 111 -> 1011 # 1110 -> 10011 # 101100 -> 110001 '1のビットが3個ある二進表記文字列が与えられたとき、次に大きい1のビットが3個ある二進表記文字列を求める。'(_1のビットが3個ある二進表記文字列,_次に大きい1のビットが3個ある二進表記文字列) :- 先頭に0を付加した二進表記文字列で探索する(_1のビットが3個ある二進表記文字列,_探索した数字ならび), '先頭が数字0の場合はそれを削除してから、数字1の場合はそのまま文字列に変換する'(_探索した数字ならび,_次に大きい1のビットが3個ある二進表記文字列),!. 先頭に0を付加した二進表記文字列で探索する(_1のビットが3個ある二進表記文字列,_生成された数字ならび) :- atom_concat('0',_1のビットが3個ある二進表記文字列,_先頭に0を付加した1のビットが3個ある二進表記文字列), atom_chars(_先頭に0を付加した1のビットが3個ある二進表記文字列,_先頭に0を付加した1のビットが3個ある二進表記文字ならび), 順列で数字ならびを生成する(_先頭に0を付加した1のビットが3個ある二進表記文字ならび,_生成された数字ならび), _生成された数字ならび @> _先頭に0を付加した1のビットが3個ある二進表記文字ならび. 順列で数字ならびを生成する(_先頭に0を付加した1のビットが3個ある二進表記文字ならび,_生成された数字ならび) :- length(_先頭に0を付加した1のビットが3個ある二進表記文字ならび,_要素数), '最後の3要素だけが数字1、それより前は数字0のならび'(_要素数,_最後の3要素だけ数字1それより前は数字0のならび), 順列(_最後の3要素だけ数字1それより前は数字0のならび,_要素数,_生成された数字ならび). '最後の3要素だけが数字1、それより前は数字0のならび'(_要素数,_最後の3要素だけ数字1それより前は数字0のならび) :- length(_最後の3要素だけ数字1それより前は数字0のならび,_要素数), append(_全ての要素が数字0のならび,['1','1','1'],_最後の3要素だけ数字1それより前は数字0のならび), 全ての要素が数字0のならび(_全ての要素が数字0のならび). '先頭が数字0の場合はそれを削除してから、数字1の場合はそのまま文字列に変換する'(['0'|L],_次に大きい1のビットが3個ある二進表記文字列) :- atomic_list_concat(L,_次に大きい1のビットが3個ある二進表記文字列). '先頭が数字0の場合はそれを削除してから、数字1の場合はそのまま文字列に変換する'(['1'|L],_次に大きい1のビットが3個ある二進表記文字列) :- atomic_list_concat(['1'|L],_次に大きい1のビットが3個ある二進表記文字列). 全ての要素が数字0のならび([]). 全ての要素が数字0のならび(['0'|_全ての要素が数字0のならび]) :- 全ての要素が数字0のならび(_全ての要素が数字0のならび). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは ぶどうの房パズル([[_1,_2,_3,_4,_5],[_6,_7,_8,_9],[_10,_11,_12],[_13,_14],[_15]]) :- flatten([[_1,_2,_3,_4,_5],[_6,_7,_8,_9],[_10,_11,_12],[_13,_14],[_15]],L), 三つ組候補([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],LL2), ぶどうの房パズル([[_6,_1,_2],[_7,_2,_3],[_8,_3,_4],[_9,_4,_5],[_10,_6,_7],[_11,_7,_8],[_12,_8,_9],[_13,_10,_11],[_14,_11,_12],[_15,_13,_14]],LL2,L). 三つ組候補(L,LL) :- findall([_1,_2,_3],( 順列(L,3,[_1,_2,_3]), _3 is abs(_1 - _2)), LL). ぶどうの房パズル([],_,[]). ぶどうの房パズル(LL1,LL2,[L|R]) :- select(L,LL1,RR1), select(L,LL2,RR2), ぶどうの房パズル(RR1,RR2,R). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # 中学生になるホンガツオ君はいつも学校の成績が悪く、父・海平に怒られます。 # 今回も中間テストでどれもひどい点数をとってしまい、海平の雷が落ちるのは間違いありません。 # # 全教科のテスト結果を同時にみせると、海平の怒りは最大級となり、1週間のおやつ抜きとなってしまいます。 # # おやつを毎日食べたいホンガツオ君は、海平の怒りを分散させるために、1日1教科ずつテスト結果をみせていくことを思いつきました。 # # ただ、テスト結果の報告が遅れることで、海平の怒りは日に日に上がっていきます。 # もしテスト結果を隠したりして報告しなかったことが後でバレたら最大級の怒りとなるため、すべての教科のテスト結果をみせた方がよさそうです。 # # 海平の怒りの度合いは教科といつみせるかによっても異ります。 # # たとえば、国語、数学、英語の3教科の点数が40点だった場合、1日1教科ずつみせるならば、3日必要です。 # 海平の怒りについては、ホンガツオ君は長年の経験から、スコア化できています。 # # 教科 点数 海平怒りのスコア初期値 1日目 2日目 3日目 # 国語(Ja) 40 10 1 2 3 # 数学(Ma) 40 10 1 4 6 # 英語(En) 40 10 1 6 9 # # # この例では、国語、数学、英語に対する海平怒りのスコアがすべて10です。 # あとは、何日目にみせるかによって、怒りが初期値に乗算されます。 # # 単純に怒りのスコアが小さい教科順にみせると、トータルの海平から被る怒りの量は以下のようになります。 # (10 * 1) + (10 * 4) + (10 * 9) = 140 # # しかし、3日目に被る怒りの量が大きい教科を先にみせることで、怒りの量は減ります。 # (10 * 1) + (10 * 4) + (10 * 3) = 80 # # # つまり、この場合は、1日目に英語→2日目に数学→3日目に国語(En->Ma->Ja)の順にみせることで、ホンガツオ君が海平から被る怒りの量は最も少ない80ですみます。 # # では、以下の7教科の場合、海平怒りのスコアが最も少なくてすむにはどの教科の順でテスト結果をみせればよいでしょうか? # # プログラミング言語はJavaScriptを使用してください。 # # 教科 点数 海平怒りのスコア初期値 1日目 2日目 3日目 4日目 5日目 6日目 7日目 # 国語(Ja) 15 35 1 1 2 3 5 8 13 # 数学(Ma) 35 15 1 5 9 13 17 21 25 # 英語(En) 30 20 1 5 8 12 15 19 22 # 社会(So) 20 30 1 3 5 7 9 11 13 # 理科(Sc) 25 25 1 2 4 6 8 10 12 # 音楽(Mu) 35 15 1 4 6 9 11 14 16 # 美術(Ar) 25 25 1 2 2 3 5 8 11 # # # 以下、問題のデータを用意しています。コピペして使ってください。 # また必ずしもこのデータを使う必要はありません。 # // 教科データ # var category=['Ja','Ma','En','So','Sc','Mu','Ar']; # // 海平怒りのスコア初期値 # var score=[35,15,20,30,25,15,25]; # // 海平怒りの倍数(7日分 # var multiplier=[ # [1,1,2,3,5,8,13], # [1,5,9,13,17,21,25], # [1,5,8,12,15,19,22], # [1,3,5,7,9,11,13], # [1,2,4,6,8,10,12], # [1,4,6,9,11,14,16], # [1,2,2,3,5,8,11], # ]; # # # ■資料 # answer_ikariscore_JavaScript.txt: # 解答用テキストファイルです。 # # ■解答方法 # 解答用テキストファイル(answer_ikariscore_JavaScript.txt)を完成させ、アップロードしてください。 # ※解答用テキストファイル以外のファイル形式(zipなど)をアップロードした場合は評価対象外となります。 # 毎日一教科ずつ示して怒りを最小にする表示順序(_表示順序) :- 毎日一教科ずつ示して怒りを(_表示順候補ならび), 最小にする表示順序(_表示順候補ならび,_表示順序). 毎日一教科ずつ示して怒りを(_表示順候補ならび) :- 教科と怒りの相関表から教科ならびを得て表示順候補ならびを得る(_表示順候補ならび). 教科と怒りの相関表から教科ならびを得て表示順候補ならびを得る(_表示順候補ならび) :- 教科と怒りの相関表から教科ならびを得て(_教科ならび), 表示順候補ならびを得る(_教科ならび,_表示順候補ならび). 教科と怒りの相関表から教科ならびを得て(_教科ならび) :- findall(_教科,教科と怒りの相関表(_教科,_,_,_),_教科ならび). 表示順候補ならびを得る(_教科ならび,_表示順候補ならび) :- findall([_怒り指数,_表示順序候補],( 表示順による怒り指数(_教科ならび,_表示順序候補,_怒り指数)), _表示順候補ならび). 表示順による怒り指数(_教科ならび,_表示順序候補,_怒り指数) :- 順列(_教科ならび,7,_表示順序候補), 怒り評価(_表示順序候補,_怒り指数). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). 怒り評価(_順序候補,_怒り指数) :- findsum(_怒りの点数,( 順序候補から教科を取り出し怒りの点数を計算する(_順序候補,_怒りの点数)),_怒り指数). 順序候補から教科を取り出し怒りの点数を計算する(_順序候補,_怒りの点数) :- 順序候補から教科を取り出し(_順序候補,_nth1,_教科), 怒りの点数を計算する(_nth1,_教科,_怒りの点数). 順序候補から教科を取り出し(_順序候補,_nth1,_教科) :- nth1(_nth1,_順序候補,_教科). 怒りの点数を計算する(_nth1,_教科,_怒りの点数) :- 教科と怒りの相関表(_教科,_,_初期値,L), nth1(_nth1,L,_怒りの倍数), _怒りの点数 is _初期値 * _怒りの倍数. findsum(A,P,Sum) :- findall(A,P,L), sum_list(L,Sum). 教科と怒りの相関表('国語(Ja)',15,35,[1,1,2,3,5,8,13]). 教科と怒りの相関表('数学(Ma)',35,15,[1,5,9,13,17,21,25]). 教科と怒りの相関表('英語(En)',30,20,[1,5,8,12,15,19,22]). 教科と怒りの相関表('社会(So)',20,30,[1,3,5,7,9,11,13]). 教科と怒りの相関表('理科(Sc)',25,25,[1,2,4,6,8,10,12]). 教科と怒りの相関表('音楽(Mu)',35,15,[1,4,6,9,11,14,16]). 教科と怒りの相関表('美術(Ar)',25,25,[1,2,2,3,5,8,11]). 最小にする表示順序(LL,_表示順序) :- once(最小の怒り指数(LL,_最小の怒り指数)), member([_最小の怒り指数,_表示順序],LL). 最小の怒り指数(LL,_最小の怒り指数) :- select([_最小の怒り指数|_],LL,R), 'Rの中に_最小の怒り指数より小さいものはない'(R,_最小の怒り指数). 'Rの中に_最小の怒り指数より小さいものはない'(R,_最小の怒り指数) :- forall(member([_怒り指数|_],R),_怒り指数 >= _最小の怒り指数). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/tech/1390525149/43 # お題 与えられた集合の要素を数珠順列に並べたもの全てを列挙せよ。 # # 例 # # {'a','b','c','d'} の数珠順列の全て # necklace=λ kfsAg:sum([[(kfsAg.sl[0],y)+x+(z,) for x in permutate(kfsAg-kfs([kfsAg.sl[0],y,z]))] for y,z in combinate(kfsAg.sl[1:],2)],[]); necklace(kfs("abcd")) # =============================== # [('a', 'b', 'd', 'c'), ('a', 'b', 'c', 'd'), ('a', 'c', 'b', 'd')] # # # # [1, 2, 3, 4, 5] の数珠順列の全て # necklace=λ kfsAg:sum([[(kfsAg.sl[0],y)+x+(z,) for x in permutate(kfsAg-kfs([kfsAg.sl[0],y,z]))] for y,z in combinate(kfsAg.sl[1:],2)],[]); necklace(kfs([1,2,3,4,5])) # =============================== # [(1, 2, 4, 5, 3), (1, 2, 5, 4, 3), (1, 2, 3, 5, 4), (1, 2, 5, 3, 4), (1, 2, 3, 4, 5), (1, 2, 4, 3, 5), # (1, 3, 2, 5, 4), (1, 3, 5, 2, 4), (1, 3, 2, 4, 5), (1, 3, 4, 2, 5), (1, 4, 2, 3, 5), (1, 4, 3, 2, 5)] # # 参考 URL;;http://ime.nu/www.geocities.jp/m_hiroi/light/pyalgo62.html # # '与えられた集合の要素を数珠順列に並べたもの全てを列挙せよ。'(_集合,_数珠順列) :- _集合 = [_首に掛ける要素|_残り集合], length(_残り集合,_残り集合の要素数), findall([_首に掛ける要素|L],( 順列(_残り集合,_残り集合の要素数,L)), _数珠順列). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # お題: # 例:数列[3,1,-7,1,5]について、 # ->[4,-3,-2,3] (累計) # ->12 (絶対値の合計) # のように計算する。 # 最初の数列の並び順を変えると、最後の合計計も変わる。 # 任意数列について、上記合計が最小になるように並び替える関数を作成 '例:数列[3,1,-7,1,5]について、 ->[4,-3,-2,3] (累計) ->12 (絶対値の合計) のように計算する。 任意数列について、上記合計が最小になるように並び替える'(_数列,_最小となる数列) :- 絶対値の合計が最小になるように並び替える(_数列,_,_最小となる数列). 絶対値の合計が最小になるように並び替える(_数列,_最小の絶対値,_絶対値の合計が最小となる数列) :- length(_数列,_要素数), setof([_絶対値の合計,_順列], [_数列,_要素数,_順列,_絶対値の合計] ^ 並べ替える(_数列,_要素数,_順列,_絶対値の合計),_絶対値_数列ならび), 絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_最小の絶対値,_絶対値の合計が最小となる数列). 並べ替える(_数列,_要素数,_順列,_絶対値の合計) :- 順列(_数列,_要素数,_順列), 絶対値の合計(_順列,_絶対値の合計). 絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_最小の絶対値,_絶対値の合計が最小となる数列) :- findmin(_絶対値,( member([_絶対値,_],_絶対値_数列ならび)), _最小の絶対値), member([_最小の絶対値,_絶対値の合計が最小となる数列],_絶対値_数列ならび). 絶対値の合計([_値],_絶対値の合計) :- _絶対値の合計 is abs(_値),!. 絶対値の合計(_値ならび,_絶対値の合計) :- 累計の途中経過を得る(_値ならび,_累計の途中経過ならび), 要素の絶対値の合計(_累計の途中経過ならび,_絶対値の合計). 累計の途中経過を得る([_],[]). 累計の途中経過を得る([_数_1,_数_2|R1],[_累計の途中経過|R2]) :- _累計の途中経過 is _数_1 + _数_2, 累計の途中経過を得る([_累計の途中経過|R1],R2). 要素の絶対値の合計(_累計の途中経過ならび,_絶対値の合計) :- findsum(_絶対値,( member(_値,_累計の途中経過ならび), _絶対値 is abs(_値)), _絶対値の合計). 順列(_,0,[]). 順列(L1,N,[A|R]) :- select(A,L1,R1), N_1 is N - 1, 順列(R1,N_1,R). findmin(V,P,Min) :- findall(V,P,L), min_list(L,Min). findsum(V,P,Sum) :- findall(V,P,L), sum_list(L,Sum). % 以下のサイトは # お題: # 例:数列[3,1,-7,-1,5]について、 # ->[4,-3,-2,3] (累計) # ->12 (絶対値の合計) # のように計算する。 # 最初の数列の並び順を変えると、最後の合計計も変わる。 # 任意数列について、上記合計が最小になるように並び替える関数を作成 '例:数列[3,1,-7,-1,5]について、 ->[4,-3,-2,3] (累計) ->12 (絶対値の合計) のように計算する。 任意数列について、上記合計が最小になるように並び替える'(_数列,_最小となる数列) :- 絶対値の合計が最小になるように並び替える(_数列,_最小となる数列). 絶対値の合計が最小になるように並び替える(_数列,_絶対値が最小となる数列) :- length(_数列,_要素数), findall([_絶対値の合計,_順列],( 順列(_数列,_要素数,_順列), 絶対値の合計(_順列,_絶対値の合計)), _絶対値_数列ならび), 絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_絶対値の合計が最小となる数列). 絶対値の合計(_数列,_絶対値の合計) :- 数列から累計を得る(_数列,_累計数列), 絶対値の合計を得る(_累計数列,_絶対値の合計). 数列から累計を得る([_数],_数) :- !. 数列から累計を得る([_数_1,_数_2|R1],[_数_3|R2]) :- _数_3 is _数_1 + _数_2, 数列から累計を得る([_数_3|R1],R2). 絶対値の合計を得る([],0). 絶対値の合計を得る([N|R1],_合計) :- 絶対値の合計を得る(R1,_合計_2), _合計 is abs(N) + _合計_2. 絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_絶対値の合計が最小となる数列) :- findmin(_絶対値,( member([_絶対値,_],_絶対値_数列ならび)), _最小の絶対値), member([_最小の絶対値,_絶対値の合計が最小となる数列],_絶対値_数列ならび). 順列(_,0,[]). 順列(L1,N,[A|R]) :- select(A,L1,R1), N_1 is N - 1, 順列(R1,N_1,R). findmin(V,P,Min) :- findall(V,P,L), min(L,Min). % 以下のサイトは # 【 課題 】 # 入力: int n # 出力: List list # n 列の長さを持つすべての順列を辞書式で出力するメソッドを作成せよ。 # n=3の時 # 結果は{123,132,213,231,312,321} # # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 GUI  】なし # 【 期限 】11/07/2013 # 【 Ver  】"1.7.0_11" # # よろしくお願いいたします。 '入力: int n 出力: List list n 列の長さを持つすべての順列を辞書式で出力するメソッドを作成せよ。 n=3の時 結果は{123,132,213,231,312,321}'(_n,_順列ならび) :- findall(N,between(1,_n,N),_数ならび), findall(_数値,( 順列(_数ならび,_n,_順列), 一桁の数値ならびから整数(_順列,_数値)), _順列ならび). 順列(_,0,[]). 順列(L,N,[A|R]) :- select(A,L,L2), N_1 is N - 1, 順列(L2,N_1,R). 一桁の数値ならびから整数(_一桁の数値ならび,_数値) :- 一桁の数値ならびから整数(_一桁の数値ならび,M,_数値). 一桁の数値ならびから整数([N],1,N). 一桁の数値ならびから整数([N|R],M,_整数) :- 一桁の数値ならびから整数(R,M_1,_整数_1), M is M_1 + 1, _整数 is 10 ^ M_1 * N + _整数_1. % 以下のサイトは # 【 課題 】 # 入力: int n # 出力: List list # n 列の長さを持つすべての順列を辞書式で出力するメソッドを作成せよ。 # n=3の時 # 結果は{123,132,213,231,312,321} # # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 GUI  】なし # 【 期限 】11/07/2013 # 【 Ver  】"1.7.0_11" # # よろしくお願いいたします。 '入力: int n 出力: List list n 列の長さを持つすべての順列を辞書式で出力するメソッドを作成せよ。 n=3の時 結果は{123,132,213,231,312,321}'(_n,_順列ならび) :- 数字列を生成する(_n,_数字ならび), findall(_数値,( 順列(_数字ならび,_n,_数字順列), number_chars(_数値,_数字順列)), _順列ならび). 数字列を生成する(_n,_数字ならび) :- findall(A,( between(1,_n,N), atom_number(A,N)), _数字ならび). 順列(_,0,[]). 順列(L,N,[A|R]) :- select(A,L,L2), N_1 is N - 1, 順列(L2,N_1,R). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1377511459/294 # # 縦横6マスのボックスがあります。 # 全てのマスを○×で埋めます。 # ○と×はそれぞれ連続2個まで繋がっててOK。 # 縦横の各列は○と×の数は同じにならなければいけない。 # ○と×の並び方が他の列と重複するのはNG。(縦と横を比較して同じなのはOK。縦と縦、横と横が同じ並びって言うのがNG) # これはどうやって解けばいいのか教えてください。 # # '縦横6マスのボックスがあります。 全てのマスを○×で埋めます。 ○と×はそれぞれ連続2個まで繋がっててOK。 縦横の各列は○と×の数は同じにならなければいけない。 ○と×の並び方が他の列と重複するのはNG。(縦と横を比較して同じなのはOK。縦と縦、横と横が同じ並びって言うのがNG) これはどうやって解けばいいのか教えてください。'(LL) :- 行候補ならびを得る(_行候補ならび), 面を規定する(LL), 転置(LL,_転置されたLL), 面候補を得る(_行候補ならび,LL), 転置診断(_転置されたLL,_行候補ならび). 行候補ならびを得る(_行候補ならび) :- findall(L,( 順列([○,○,○,×,×,×],6,L), \+(append(_,[A,A,A|_],L))), _重複があり得る行候補ならび), sort(_重複があり得る行候補ならび,_行候補ならび). 面を規定する(LL) :- length(LL,6), findall(L,( member(L,LL), length(L,6)), LL). 面候補を得る(_行候補ならび,[L1,L2,L3,L4,L5,L6]) :- member(L1,_行候補ならび), member(L2,_行候補ならび), member(L3,_行候補ならび), member(L4,_行候補ならび), member(L5,_行候補ならび), member(L6,_行候補ならび), sort([L1,L2,L3,L4,L5,L6],[_,_,_,_,_,_]). 転置診断(_転置されたLL,_行候補ならび) :- sort(_転置されたLL,[_,_,_,_,_,_]), findall(_,( member(L,_転置されたLL), member(L,_行候補ならび), \+(append(_,[A,A,A|_],L))), [_,_,_,_,_,_]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは 全順列(L,LL) :- length(L,Len), ダミー要素を付加する(Len,L,L_2), findall(L_4,( 順列(L_2,3,L_3), findall(A,(member(A,L_3),\+(var(A))),L_4)), LL_1), sort(LL_1,LL). 全組合せ(L,LL) :- length(L,Len), ダミー要素を付加する(Len,L,L_2), findall(L_4,( 組合せ(L_2,3,L_3), findall(A,(member(A,L_3),\+(var(A))),L_4)), LL_1), sort(LL_1,LL). ダミー要素を付加する(Len,L_1,L_2) :- length(L_v,Len), append(L_1,L_v,L_2),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1370255305/777 # # [1] 授業単元:標準入力から N を入力し、N 個のサイコロの出目の和の確率の一覧を作成せよ。 # [2] 問題文:確率は小数三位を四捨五入すること。 # N = 2 # 1 : 0.00% # 2 : 2.78% # 3 : 5.56% # 4 : 8.33% # 5 : 11.11% # 6 : 13.89% # 7 : 16.17% # 8 : 13.89% # 9 : 11.11% # 10 : 8.33% # 11 : 5.56% # 12 : 2.78% # [3.3] 言語:C # [4] 期限:2013-08-04 22:00 # # '標準入力から N を入力し、N 個のサイコロの出目の和の確率の一覧を作成せよ。 確率は小数三位を四捨五入すること。' :- '標準入力から N を入力し、'(_N), 'N 個のサイコロの出目の和の確率の一覧を作成せよ。確率は小数三位を四捨五入すること。'(_N). '標準入力から N を入力し、'(_N) :- 整数を得る('サイコロの個数を入力してください',_N > 0,_N). 'N 個のサイコロの出目の和の確率の一覧を作成せよ。確率は小数三位を四捨五入すること。'(_N) :- 'N 個のサイコロの出目の和'(_N,_N_6,_出目の和ならび), between(1,_N_6,_M), 'サイコロの出目の和の確率を表示する。確率は小数三位を四捨五入すること。'(_出目の和ならび,_M,_N_6,_確率), '表示する。確率は小数三位を四捨五入すること。'(_M,_確率), _M = _N. 'N 個のサイコロの出目の和'(_N,_N_6,_出目の和ならび) :- _N_6 is 6 * _N, findall(Sum,( 重複順列([1,2,3,4,5,6],_N,L), sum(L,Sum)), _出目の和ならび). 'サイコロの出目の和の確率。確率は小数三位を四捨五入すること。'(_出目の和ならび,_出目の和,_N_6,_確率) :- count(member(_出目の和,_出目の和ならび),Count), _確率 is ((Count / _N_6) * 1000 + 5) / 1000. '表示する。確率は小数三位を四捨五入すること。'(_M,_確率) :- writef('%t : ',[_M]), format('~2f%\n',[_確率]). % 以下のサイトは # @nishio # Prologで重複順列([t, f], 3, _重複順列)とかやったら_重複順列が[[t, t, t], [t, t, f], ..., [f, f, f]]になるような述語重複順列の作り方に悩んでいる # 'Prologで重複順列([t, f], 3, _重複順列)とかやったら_重複順列が[[t, t, t], [t, t, f], ..., [f, f, f]]になるような述語重複順列の作り方に悩んでいる'(_要素リスト,N,_重複順列) :- 重複順列(_要素リスト,N,_重複順列). 重複順列(_要素リスト,N,_重複順列) :- findall(L,重複順列_1(N,_要素リスト,L),_重複順列). 重複順列_1(0,_,[]). 重複順列_1(N,_要素リスト,[_要素|R]) :- N > 0, member(_要素,_要素リスト), N_1 is N - 1, 重複順列_1(N_1,_要素リスト,R). % 以下のサイトは # # 「キミならどう書く 2.0 ? 2007 ? その 1」より # # 斗桶 (a) に油が 1 斗 (10 升) ある。これを等分したい。7 升枡 (b) と 3 升枡 (c) しかない。この 2 つの枡だけで、5 升ずつ等分する方法を記述せよ。 # '斗桶 (a) に油が 1 斗 (10 升) ある。これを等分したい。7 升枡 (b) と 3 升枡 (c) しかない。この 2 つの枡だけで、5 升ずつ等分する方法を記述せよ。'(_履歴) :- 移動(10,0,0,[[10,0,0]],_履歴_1), reverse(_履歴_1,_履歴). 移動(5,5,0,_履歴,[[5,5,0]|_履歴]) :- !. 移動(A,B,C,_履歴_1,_履歴) :- 順列([a,b,c],2,[X,Y]), 移動(X,Y,A,B,C,A2,B2,C2), \+(member([A2,B2,C2],_履歴_1)), 移動(A2,B2,C2,[[A2,B2,C2]|_履歴_1],_履歴). 移動(a,b,A,B,C,0,B2,C) :- A =< (7 - B), B2 is A + B,!. 移動(a,b,A,B,C,A2,7,C) :- A > (7 - B), A2 is A - (7 - B),!. 移動(a,c,A,B,C,0,B,C2) :- A =< (3 - C), C2 is A + C,!. 移動(a,c,A,B,C,A2,B,3) :- A > (3 - C), A2 is A - (3 - C),!. 移動(b,a,A,B,C,A2,0,C) :- A2 is A + B,!. 移動(c,a,A,B,C,A2,B,0) :- A2 is A + C,!. 移動(b,c,A,B,C,A,0,C2) :- B =< (3 - C), C2 is B + C,!. 移動(b,c,A,B,C,A,B2,3) :- B > (3 - C), B2 is B - (3 - C),!. 移動(c,b,A,B,C,A,B2,0) :- C =< (7 - B), B2 is B + C,!. 移動(c,b,A,B,C,A,7,C2) :- C > (7 - B), C2 is C - (7 - B),!. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % (10-0-0)>(3-7-0)>(3-4-3)>(6-4-0)>(6-1-3)>(9-1-0)>(9-0-1)>(2-7-1)>(2-5-3)>(5-5-0) % 以下のサイトは # Prolog 21世紀における0〜3の数字を2個ずつ使ってできる年月日の個数 # # 【出典】https://twitter.com/c_oi/status/301346035094126593 # https://twitter.com/c_oi/status/301346039590436864 # 【引用】「0〜3の数字を2個ずつ使ってできる年月日は21世紀(2001/01/01〜2100/12/31)の間に何日間あるでしょう?」 # '21世紀における0〜3の数字を2個ずつ使ってできる年月日の個数'(_個数) :- setof(_年月日ならび,( 重複を許す年月日ならびの選択(_年月日ならび)), LL), length(LL,_個数). 重複を許す年月日ならびの選択(_年月日ならび) :- 順列([0,0,1,1,2,2,3,3],8,_年月日ならび), _年月日ならび @>= [2,0,0,1,0,1,0,1], _年月日ならび @=< [2,1,0,0,1,2,3,1], \+(禁則(_年月日ならび)). 禁則([_,_,_,_,0,2,3,_]) :- !. 禁則([_,_,_,_,2,_,_,_]) :- !. 禁則([_,_,_,_,3,_,_,_]) :- !. 禁則([_,_,_,_,1,3,_,_]) :- !. 禁則([_,_,_,_,_,_,3,3]) :- !. 禁則([_,_,_,_,_,_,3,2]) :- !. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # # 単位節から選択された引数リストの組合せ # # 単位節から選択された引数リストの順列 # 単位節組合せ(_単位節項,_射影項ならび,_条件,_組合せ数,X) :- 単位節からならびへの射影(_単位節項,_射影項ならび,_条件,LL), 組合せ(LL,_組合せ数,X). 単位節順列(_単位節項,_射影項ならび,_条件,_組合せ数,X) :- 単位節からならびへの射影(_単位節項,_射影項ならび,_条件,LL), 順列(LL,_組合せ数,X). 単位節からならびへの射影(_単位節項,_射影項ならび,_条件,LL) :- list(_射影項ならび), _単位節項=..[_|_引数ならび], findall(_射影項ならび,( call((_単位節項,_条件))), LL). 単位節からならびへの射影(_単位節項,_射影項,_条件,LL) :- \+(list(_射影項)), _単位節項=..[_|_引数ならび], findall(_射影項,( call((_単位節項,_条件))), LL). % % 単位節組合せ/4と単位節順列/4は高階述語である。 % 高階述語を使用する場合、引数変数の扱いに注意する必要がある。 % % 射影項ならび、乃ちリストである場合はその要素は必ず単位節項の引数に含まれる必要がある。 % リストでなく単体で射影項が指定された場合も同様である。 % 組合せ(L,1,[A]) :- member(A,L). 組合せ([A|R1],N,[A|R3]) :- N > 1, M is N - 1, 組合せ(R1,M,R3). 組合せ([_|R1],N,L) :- N > 1, 組合せ(R1,N,L). 順列(Y,0,_,[]). 順列(Y,N,EL,[A|X]) :- \+(member(A,EL)), del(Z = Y - A), M is N - 1, 順列(Z,M,EL,X) . 順列(Y,N,EL,[_|X]) :- member(A,EL), 順列(Z,M,EL,X). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- N > 0, del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1342966104/667 # # [1] 授業単元:C言語 # [2] 問題文: http://ime.nu/ideone.com/tRkzM # # 1. 10000から99999のランダムな自然数を1000コ生成し、小さい順にこれら数値を表示するプログラムを作成せよ。 #   ただし数値は何番目に生成した数値かも表示する。 # #   例)1番目に小さい数は475番目の数10049です。 # # 2. 10000から999999のランダムな自然数を1000コ生成し、各数値と平均値との差をもとめ、その差が小さい順にその数値を  表示するプログラムを作成せよ。また、各数値は何番目に生成したかも表示する。 # #   例)1番目に平均との差が小さい数は680番目の数69383です。 平均値との差は10.505です。 # # 3. n種類の文字{a1,a2,・・・,an}を考える。このn種類の文字を使って構成できるn文字列をすべて表示せよ。 #   ただし文字の重複はなし。nはプログラムの引数としてあたえ、1 < n < 15 は仮定する。 # #   例)program 5 # a,b,c,d,e # a,b,c,e,d # a,b,d,c,e # ・ #       ・ #     e,d,c,b,a 'n種類の文字{a1,a2,・・・,an}を考える。このn種類の文字を使って構成できるn文字列をすべて表示せよ。ただし文字の重複はなし。nはプログラムの引数としてあたえ、1 < n < 15 は仮定する。'(_n) :- length(L,_n), 重複しないn文字を得る(_n,L), このn種類の文字を使って構成できるn文字列をすべて表示せよ(_n,L). 重複しないn文字を得る(0,L,L) :- !. 重複しないn文字を得る(N,L1,L) :- 'L1に重複しない一文字を追加する'(L1,L2), N_1 is N - 1, 重複しないn文字を得る(N_1,L2,L),!. 重複しないn文字を得る(N,L1,L) :- 重複しないn文字を得る(N,L1,L). 'L1に重複しない一文字を追加する'(L1,L2) :- write('一文字入力してください : '), get_char(_文字), \+(member(_文字,L1)), append(L1,[_文字],L2). このn種類の文字を使って構成できるn文字列をすべて表示せよ(_n,L) :- このn種類の文字を使って構成できるn文字列を(_n,L,_文字列ならび), append(_,[_文字列|R],_文字列ならび), writef('%t\n',[_文字列]), R = []. このn種類の文字を使って構成できるn文字列を(_n,L,_文字列ならび) :- findall(_文字列,( 順列(L,_n,L1), atomic_list_concat(L1,',',_文字列)), _文字列ならび). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/559 # # [1] 授業単元: C言語 # [2] 問題文:文字列の全パターンを表示するプログラム # 実行結果例 # >abc # abc # acb # bca # … # 文字列の全パターンを表示する(_文字列) :- atom_chars(_文字列,_文字ならび), length(_文字ならび,_要素数), 全パターンを(_文字ならび,_要素数,N,L), 表示する(L), N = _要素数. 全パターンを(_文字ならぴ,_要素数,L) :- between(1,N,_要素数), 順列(_文字ならび,N,L). 表示する(L) :- atomic_list_concat(L,S), writef('%t\n',[S]). % 順列/3 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/93 # # [1] 授業単元: C言語 # [2] 問題文:正の整数m,n(m>n)があるとき、 #       順列mPnを計算するプログラムの作成。 # '正の整数m,n(m>n)があるとき、順列mPnを計算する'(_m,_n,_mPn) :- 階乗(_n,_m,_mPn). 階乗(M,N,1) :- M > N,!. 階乗(M,N,X) :- M2 is M + 1, 階乗(M2,N,Y), X is M * Y. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/93 # # [1] 授業単元: C言語 # [2] 問題文:正の整数m,n(m>n)があるとき、 #       順列mPnを計算するプログラムの作成。 # '正の整数m,n(m>n)があるとき、順列mPnを計算する'(_mPn) :- findall(N,between(1,_m,N),L), count(順列(L,_n,_),_mPn). count(P,N) :- findall(1,P,L), length(L,N). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # @TakaoOzaki 分数の問題と言っていたのはこれです。\ # “@utatakiyoshi: 友達がSkypeで # 「0~9を1回ずつ使い,?????/?????=1/9となるように?を埋めよ」って # 算数パズルを出してきたからC++でサクッと書いてドヤ顔してやった” # '0~9を1回ずつ使い,?????/?????=1/9となるように?を埋めよ'(X/Y) :- 順列([0,2,3,4,5,6,7,8],8,[B,C,D,E,G,H,I,J]), X is 1 * 10000 + B * 1000 + C * 100 + D * 10 + E, Y is 9 * 10000 + G * 1000 + H * 100 + I * 10 + J, 9 is Y // X, 0 is Y mod X. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # # @haroperiさんの20120420のツイートより # # 双方向性のあるQuicksortが書けないので寝るです。だめだもうだめだ。 *喪中* # 双方向性の昇順整列(L1,L2) :- length(L1,Len), length(L2,Len), length(Ln,Len),!, 順列(L2,Ln,L1), 昇順(L2). 順列(Y,[],[]). 順列(Y,[_|Ln],[A|X]) :- del(A,Y,Z), 順列(Z,Ln,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). 昇順([_]). 昇順([A,B|R]) :- A @=< B, 昇順([B|R]). % 以下のサイトは # I want to find all possible combinations of 3x3 matrix. But there is a rule that the digits occur just once and the sum on each line and column is the same. # # 私は3x3行列のすべての可能な組み合わせを見つけたい。しかし、数字は一度だけ発生し、各行の和と列が同じであるという規則があります。 # # 8 1 6 # 3 5 7 # 4 9 2 # '私は3x3行列のすべての可能な組み合わせを見つけたい。しかし、数字は一度だけ発生し、各行の和と列が同じであるという規則があります。'([[A,B,C],[D,E,F],[G,H,I]]) :- 順列([1,2,3,4,5,6,7,8,9],9,[A,B,C,D,E,F,G,H,I]), 各行の和と列が同じである(A,B,C,D,E,F,G,H,I). 各行の和と列が同じである(A,B,C,D,E,F,G,H,I) :- 各行の和(A,B,C,D,E,F,G,H,I,_各行の和でありしかも各列の和), 各列の和(A,B,C,D,E,F,G,H,I,_各行の和でありしかも各列の和). 各行の和(A,B,C,D,E,F,G,H,I,_各行の和でありしかも各列の和) :- _各行の和でありしかも各列の和 is A+B+C, _各行の和でありしかも各列の和 is D+E+F, _各行の和でありしかも各列の和 is G+H+I. 各列の和(A,B,C,D,E,F,G,H,I,_各行の和でありしかも各列の和) :- _各行の和でありしかも各列の和 is A+D+G, _各行の和でありしかも各列の和 is B+E+H, _各行の和でありしかも各列の和 is C+F+I. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # 年俸1000万の会社の試験問題 <発展問題> # 単体テストなどやっていると、全ての要素について全ての組み合わせを # 求めたいことが結構あります。 # '単体テストなどやっていると、全ての要素について全ての組み合わせを求めたいことが結構あります。'(_グループならび,_組合せの順列) :- length(_グループならび,Len), 全ての組合せ(_グループならび,_組合せ_1), 順列(_組合せ_1,Len,_組合せの順列). 全ての組合せ([],[]). 全ての組合せ([L|R1],[A|R2]) :- member(A,L), 全ての組合せ(R1,R2). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1325685876/26 # # 問題:4桁の数字が与えられたとき、その4個の数字で組み合わせって、作れる? # 1001 ならば 0011,0101,0110,1001,1010,1100 が出来るなど。 # 言語・コンパイラ:C gcc # '4桁の数字が与えられたとき、その4個の数字の組み合わせ'(_4桁の数字,_4個の数字の組み合わせ) :- atom_chars(_4桁の数字,Chars), setof(X,順列(Chars,4,X),_4個の数字の組合せ). % 以下のサイトは # # 1から10までの整数の順列をすべて表示するプログラムをお願いします。 # '1から10までの整数の順列をすべて表示する' :- findall(N,for(1,N,10),L), 順列(L,10,L1), writef('%t,%t,%t,%t,%t,%t,%t,%t,%t,%t\n',L1), fail. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/226 # # [1] 授業単元:アルゴリズム # [2] 問題文: # 重複順列についてです。 # A〜Gなどの7つ以上の要素から、6つ取り出して並べるときの、全ての組み合わせを出す。 # 例)AAAAAA, # AAAAAB, # AAAAAC,... # AAAABA,... # (実際に全て出さなくても、出すことができるコードが出来ていれば可) #                # 'A〜Gなどの7つ以上の要素から、6つ取り出して並べるときの、全ての組み合わせを出す。' :- 'A〜Gなどの7つ以上の要素の入力'(_7つ以上の要素ならび), 重複順列(_7つ以上の要素ならび,6,_重複順列), writef('%t%t%t%t%t%t\n',_重複順列), fail. 'A〜Gなどの7つ以上の要素から、6つ取り出して並べるときの、全ての組み合わせを出す。'. 'A〜Gなどの7つ以上の要素の入力'(_7つ以上の要素ならび) :- write('7つ以上の要素を空白区切りで一行で入力してください : '), readln(_7つ以上の要素ならび), length(_7つ以上の要素ならび,Len), len >= 7. 重複順列(L,0,[]). 重複順列(L,N,[A|R3]) :- N > 0, 重複せず要素を取り出す(L,A), N_1 is N - 1, 重複順列(L,N_1,R3). 重複せず要素を取り出す(L,E) :- append(L0,[E|_],L), \+(append(_,[E|_],L0)). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/126 # # どなたかお願いします。 # # [1] 授業単元:アルゴリズム # [2] 問題文(含コード&リンク): 与えられた任意の長さのアルファベットの文字列(ただし # 重複する文字は含まないとする)に対して、文字を任意の順番に入れ替えてできる # 文字列のパターンをすべて出力する関数permute()を作成せよ。 # # 例: # permute("ABC"); # ABC ACB BAC BCA CAB CBA # # '与えられた任意の長さのアルファベットの文字列(ただし重複する文字は含まないとする)に対して、文字を任意の順番に入れ替えてできる文字列のパターンをすべて空白区切りで横方向に出力する'(_文字列) :- fildall(_順番を入れ替えた文字列,( '与えられた任意の長さのアルファベットの文字列(ただし重複する文字は含まないとする)に対して、文字を任意の順番に入れ替えてできる文字列のパターンを'(_文字列,_順番を入れ替えた文字列)), _文字列パターンならび), 空白区切りで横方向に出力する(_文字列パターンならび,' ',_表示行). 空白区切りで横方向に出力する(_文字列パターンならび) :- concat_atom(_文字列パターン,' ',_表示行), writef('%t\n',[_表示行]). '与えられた任意の長さのアルファベットの文字列(ただし重複する文字は含まないとする)に対して、文字を任意の順番に入れ替えてできる文字列のパターンを'(_文字列,_順番を入れ替えた文字列) :- atom_chars(_文字列,Chars), length(Chars,Len), 順列(Chars,Len,Chars2), atom_chars(_順番を入れ替えた文字列,Chars2). % % 最初の課題述語名に「空白区切りで横方向に」を加えたのがポイント。 % このような実例付き課題では、多くの場合、仕様文の表現に実例の細部が % 反映されていないことが多い。 % この時は思い切って、課題文に手を入れて考える。 % 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/100 # # [1] 授業単元:c言語演習 # [2] 問題文 :9,2,8,1の数字四項の組み合わせをすべて表示しなさい。 # 同じ数字が使われてる組み合わせはNGで表示しなさい。 # '9,2,8,1の数字四項の組み合わせをすべて表示' :- 順列([9,2,8,1],4,L), concat_atom(L,' ',S), writef('%t\n',[S]), fail. '9,2,8,1の数字四項の組み合わせをすべて表示'. 順列(L,0,[]). 順列(L_1,N,[A|L]) :- del(A,L_1,L_2), N_1 is N - 1, 順列(L_2,N_1,L). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/33 # # [1] 授業単元: プログラミング # [2] 問題文(含コード&リンク):1から15の数字から5個の数字を取って同じ数字が # 使われない並びの通りをすべて表示させなさい。 # 例:1 2 3 4 5 # 1 3 2 4 5 # 11 12 10 9 8 # '1から15の数字から5個の数字を取って同じ数字が使われない並びの通りをすべて表示させる' :- 順列([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],5,L), concat_atom(L,' ',S), writef('%t\n',[S]), fail. '1から15の数字から5個の数字を取って同じ数字が使われない並びの通りをすべて表示させる'. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, 順列(Z,M,X). del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1311089619/731 # # ../test/read.cgi/tech/1311089619/726 # すみません。提出することが出来ました。 # 明日に行う課題を出されました。 # 出来れば教えていただけますか? # [1] 授業単元:C言語プログラミング # [2] 問題文:4つの数値をを入力して結果が20になる数式(+,-,*,/)を全て表示させる. # ()は考えない。 # 組み合わせがない場合はエラー表示とする。入力できる数値は一桁のみとする。 # '4つの数値を入力して結果が20になる数式(+,-,*,/)を全て表示させる' :- '4つの数値を入力して'(_数値1,_数値2,_数値3,_数値4), '結果が20になる数式(+,-,*,/)を全て'(_数値1,_数値2,_数値3,_数値4,_式ならび), 表示させる(_数値1,_数値2,_数値3,_数値4,_式ならび). '結果が20になる数式(+,-,*,/)を全て'(_数値1,_数値2,_数値3,_数値4,_式ならび) :- findall(_式,( 順列([_数値1,_数値2,_数値3,_数値4],4,L1), 順列(['+','-','*','/'],3,L2), 式を構成する(L1,L2,_式), 20 is truncate(_式))), _式ならび). '4つの数値を入力して'(_数値1,_数値2,_数値3,_数値4) :- 整数入力(_数値1), 整数入力(_数値2), 整数入力(_数値3), 整数入力(_数値4),!. 式を構成する(L1,L2,_式) :- 演算子を挿入する(L1,L2,L3), concat_atom(L3,S), atom_to_term(S,_式,_). 演算子を挿入する([A],_,[A]) :- !. 演算子を挿入する([_,0|R1],[/|R2],R3) :- !,fail. 演算子を挿入する([A|R1],[B|R2],[A,B|R3]) :- 演算子を挿入する(R1,R2,R3). 表示させる(_数値1,_数値2,_数値3,_数値4,[]) :- writef('この4つの数値 %t,%t,%t,%t からは解が得られません\n',[_数値1,_数値2,_数値3,_数値4]),!. 表示させる(_数値1,_数値2,_数値3,_数値4,_式ならび) :- append(_,[_式|R],_式ならび), writef('20 = %t.\n',[_式]), R = []. 整数入力(_整数) :- write('整数を入力してください : '), get_line(Line), 整数入力診断(Line,_整数),!. 整数入力(_整数) :- 整数入力(_整数). 整数入力診断(Line,_整数) :- atom_to_term(Line,_整数,_), integer(_整数),!. 整数入力診断(Line,_整数) :- writef('入力された %t からは整数が得られません。再入力をお願いします。\n',[Line]), fail. 順列(Y,0,_,[]). 順列(Y,N,EL,[A|X]) :- \+(member(A,EL)), del(Z = Y - A), M is N - 1, 順列(Z,M,EL,X). 順列(Y,N,EL,[_|X]) :- member(A,EL), 順列(Z,M,EL,X). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1311089619/715 # # [1] 授業単元:C言語 # [2] 問題文:1358をを並び替えた数字を24通り表示させるプログラムを完成させない。 # '1358を並び替えた数字を24通り表示させる' :- findall(L,順列([1,3,5,8],4,L),LL), length(LL,24), append(_,[L|R],LL), writef('%t %t %t %t\n',L), R = [],!. '1358を並び替えた数字を24通り表示させる' :- length(LL,24), findall(L,順列([1,3,5,8],4,L),LL1), append(LL,_,LL1), append(_,[L|R],LL), writef('%t %t %t %t\n',L), R = [],!. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1311089619/638 # # [1] 授業単元:C言語プログラミング # [2] 問題文(含コード&リンク): 4つの数字を入力して四則演算の組み合わせを考えて # 10になる数式を表示せよ。10になる数式がなければ"NG"と表示。 # 入力できる数値は1〜9までとする。 # 例) # 入:1 2 3 4 # 答え:2×3+1×4 # '4つの数字を入力して四則演算の組み合わせを考えて10になる数式を表示せよ。10になる数式がなければ"NG"と表示' :- '4つの数字を入力して'(N1,N2,N3,N4), 順列([+,-,*,/],3,L), 式文字列を構成する([N1,N2,N3,N4],L,_式文字列), atom_to_term(_式文字列,_式,_), 10 is truncate(_式), write('%t\n',[_式文字列]),!. '4つの数字を入力して四則演算の組み合わせを考えて10になる数式を表示せよ。10になる数式がなければ"NG"と表示' :- write('NG\n'). '4つの数字を入力して'(N1,N2,N3,N4) :- write('4つの整数を空白区切りで入力してください : '), readln([N1,N2,N3,N4]), すべて整数([N1,N2,N3,N4]). 式文字列を構成する(_値ならび,_符号ならび,_式文字列) :- 式を構成するならびを生成(_値ならび,_符号ならび,_式を構成するならび), concat_atom(_式を構成するならび,_式文字列). 式を構成するならびを生成([N4],[],[N4]) :- !. 式を構成するならびを生成([N1,0|R1],[/|R2],R3) :- !,fail. 式を構成するならびを生成([N|R1],[_符号|R2],[N,_符号|R3]) :- 式を構成するならびを生成(R1,R2,R3). すべて整数([]). すべて整数([N|R]) :- integer(N), すべて整数(R). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1311089619/70 # # [1] 授業単元:アルゴリズム # [2] 問題文(含コード&リンク): # 1〜N(N >= 1)までの、1ずつ増加する等差数列が与えられる、この時のNの階乗通り存在する組み合わせをすべて表示せよ # 例) # Nの値: 3 # 1 2 3 # 1 3 2 # 2 1 3 # 2 3 1 # 3 1 2 # 3 2 1 # なお、例のような表示順序で無くても良い、すべて表示されているならその表示順序は問わない。 # '1〜N(N >= 1)までの、1ずつ増加する等差数列が与えられる、この時のNの階乗通り存在する組み合わせをすべて表示する'(N) :- '1〜N(N >= 1)までの、1ずつ増加する等差数列が与えられる'(N,L), 'この時のNの階乗通り存在する組み合わせをすべて'(L,N,_順列ならび), 表示する(_順列ならび). '1〜N(N >= 1)までの、1ずつ増加する等差数列が与えられる'(N,L) :- findall(M,for(1,M,N),L). 'この時のNの階乗通り存在する組み合わせをすべて'(L,N,_順列ならび) :- findall(_順列,( 順列(L,N,_順列)), _順列ならび). 表示する(_順列ならび) :- append(_,[_順列|R],_順列ならび), concat_atom(_順列,' ',_行表示), writef('%t\n',[_行表示]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1308749241/526 # # [1] 授業単元:C言語 # # [2] 問題文(含コード&リンク): #  1円硬貨, 5円硬貨, 10円硬貨, 50円硬貨, 100円硬貨, 500円硬貨の内から種類不問で何枚か取り出し、 #  その重さの合計を小数点以下1桁まで入力させる。 #  その値から、取り出した硬貨の合計金額を推定し表示するプログラムを作れ。 #  ただし、推定される金額が複数存在する場合はその全てを表示する。 #  また、1円硬貨, 5円硬貨, 10円硬貨, 50円硬貨, 100円硬貨, 500円硬貨の1枚あたりの重さは #  それぞれ1g, 3.7g, 4.5g, 4g, 4.8g, 7gであるとする。 #  (入力例) #  8.0 #  (出力例) #  8円 #  54円 #  100円 #  501円 # '1円硬貨, 5円硬貨, 10円硬貨, 50円硬貨, 100円硬貨, 500円硬貨の内から種類不問で何枚か取り出し、その重さの合計を小数点以下1桁まで入力させる。その値から、取り出した硬貨の合計金額を推定し表示する' :- '重さの合計を小数点以下1桁まで入力'(_重さの合計), '取り出した硬貨の合計金額を推定し'(_重さの合計,_取り出した硬貨の合計金額), 表示する(_取り出した硬貨の合計金額), fail. '1円硬貨, 5円硬貨, 10円硬貨, 50円硬貨, 100円硬貨, 500円硬貨の内から種類不問で何枚か取り出し、その重さの合計を小数点以下1桁まで入力させる。その値から、取り出した硬貨の合計金額を推定し表示する'. '重さの合計を小数点以下1桁まで入力'(_重さの合計) :- write('重さの合計を小数点以下1桁まで入力してください : '), get_line(Line), 重さの合計入力診断(Line,_重さの合計),!. '重さの合計を小数点以下1桁まで入力'(_重さの合計) :- '重さの合計を小数点以下1桁まで入力'(_重さの合計). 重さの合計入力診断(Line,_重さの合計) :- atom_to_term(Line,_重さの合計の一,_), float(_重さの合計の一), _重さの合計 is floor(_重さの合計の一 * 10) / 10,!. 重さの合計入力診断(Line,_重さの合計) :- writef('入力された%tからは適切な実数値が得られませんでした。再入力をお願いします。\n',[Line]), fail. '取り出した硬貨の合計金額を推定し'(_重さの合計,_取り出した硬貨の合計金額) :- Max is truncate(_重さの合計), findall(N,for(Max,N,0),L1), 順列(L1,6,[F,E,D,C,B,A]), 重さの制限(_重さの合計,F,E,D,C,B,A), _重さの合計100mg is truncate(_重さの合計 * 10), _重さの合計100mg is 10 * A + 37 * B + 45 * C + 40 * D + 48 * E + 70 * F, _取り出した硬貨の合計金額 is 1 * A + 5 * B + 10 * C + 50 * D + 100 * E + 500 * F. 重さの制限(_重さの合計100mg,F,E,D,C,B,A) :- F =< _重さの合計100mg // 70, _重さの合計100mg_2 is _重さの合計100mg - F * 70, E =< _重さの合計100mg_2 // 48, _重さの合計100mg_3 is _重さの合計100mg_2 - E * 48, D =< _重さの合計100mg_3 // 40, _重さの合計100mg_4 is _重さの合計100mg_5 - D * 40, C =< _重さの合計100mg_4 // 45, _重さの合計100mg_5 is _重さの合計100mg_6 - C * 45, B =< _重さの合計100mg_5 // 37, _重さの合計100mg_6 is _重さの合計100mg_3 - B * 37, A =< _重さの合計100mg_6 // 10,!. 表示する(_取り出した硬貨の合計金額) :- writef('%t円\n',[_取り出した硬貨の合計金額]). % 以下のサイトは # 順列の積の定義 # 順列 L1 L2 の積を L3 とするとき、置換群 G(S) の積の定義 # 数学的な記法で [L1(1),L1(2), ... ,L1(n)] = L1 * [1,2, ... ,n]. # を述語 順列の積 として、再帰的に定義する。 順列の積(_,[],[]) :- !. 順列の積(L1,[I],[J]) :- arg_list(I,L1,J),!. 順列の積(L1,[I|R2],[J|R3]) :- arg_list(I,L1,J),!, 順列の積(L1,R2,R3). arg_list(K,Y,M) :- PY =.. [pred|Y], arg(K,PY,M). % 以下のサイトは # # 順列をリスト[a1,a2,・・・,an] で表すとき、その転倒数を計算しよう。 # 奇順列(_順列) :- 転倒数(_順列,_転倒数), 1 is _転倒数 is 2,!. 転倒数(_順列,_転倒数) :- findall(Count,( append(_,[N|R],_順列), count((append(_,[M|_],R),N > M),Count)), L), sum(L,_転倒数). % 以下のサイトは # # 順列をリスト[a1,a2,・・・,an] で表すとき、その転倒数を計算しよう。 # 偶順列(_順列) :- 転倒数(_順列,_転倒数), 0 is _転倒数 is 2,!. 転倒数(_順列,_転倒数) :- findall(Count,( append(_,[N|R],_順列), count((append(_,[M|_],R),N > M),Count)), L), sum(L,_転倒数). % 以下のサイトは # # 順列をリスト[a1,a2,・・・,an] で表すとき、その転倒数を計算しよう。 # 転倒数(_順列,_転倒数) :- findsum(_度数,度数(転倒(_順列,_,_),_度数),_転倒数). 転倒(_順列,_ある数より前方にありある数より大きい数,_ある数) :- ある順列要素の前にその数より大きい数がある時その二数は転倒しているという(_順列,_ある数より前方にありある数より大きい数,_ある数). ある順列要素の前にその数より大きい数がある時その二数は転倒しているという(_順列,_ある数より前方にありある数より大きい数,_ある数) :- append(L1,[_ある数|_],_順列), member(_ある数より前方にありある数より大きい数,L1), _ある数より前方にありある数より大きい数 > _ある数. 度数(_目標,_度数) :- findall(1,_目標,L), length(L,_度数). findsum(A,_目標,_合計) :- findall(A,_目標,L), sum_list(L,_合計). % 以下のサイトは # # permutation(Xs, Ys) : リストXsを並べ替えるとリストYsになる # リストXsを並べ替えるとリストYsになる(Xs,Ys) :- length(Xs,Len), 順列(Xs,Len,Ys). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, 順列(Z,M,X) . del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y) . /* del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A). */ % 以下のサイトは # 出典:: http://www.26dd.cn/go.php?q=nb2hi4b2f4xwiltimf2gk3tbfzxgkltkoaxwq33sovzw6lzsgaydombxga3s6mjrhaztqmrthezdc # # Baker, Cooper, Fletcher, MillerとSmithは五階建てアパートの異なる階に住んでいる。 # Bakerは最上階に住むのではない。Cooperは最下階に住むのではない。 Fletcherは最上階にも # 最下階にも住むのではない。MillerはCooperより上の階に住んでいる。SmithはFletcherの隣の階に # 住むのではない。 # FletcherはCooperの隣の階に住むのではない。それぞれはどの階に住んでいるか。 'Baker, Cooper, Fletcher, MillerとSmithは五階建てアパートの異なる階に住んでいる。' :- 順列([1,2,3,4,5],5,L), 'Bakerは最上階に住むのではない。'(L), 'Cooperは最下階に住むのではない。'(L), 'Fletcherは最上階にも最下階にも住むのではない。'(L), 'MillerはCooperより上の階に住んでいる。'(L), 'SmithはFletcherの隣の階に住むのではない。'(L), 'FletcherはCooperの隣の階に住むのではない。'(L), 住んでいる階を表示する(L). 'Bakerは最上階に住むのではない。'(L) :- 何階('Baker',L,Baker), \+(最上階(Baker)). 'Cooperは最下階に住むのではない。'(L) :- 何階('Cooper',L,Cooper), \+(最下階(Cooper)). 'Fletcherは最上階にも最下階にも住むのではない。'(L) :- 何階('Fletcher',L,Fletcher), \+(最上階(Fletcher)), \+(最下階(Fletcher)). 'MillerはCooperより上の階に住んでいる。'(L) :- 何階('Miller',L,Miller), 何階('Cooper',L,Cooper), Miller > Cooper. 'SmithはFletcherの隣の階に住むのではない。'(L) :- 'SmithはFletcherの上の階に住むのではない。'(L), 'SmithはFletcherの下の階に住むのではない。'(L). 'SmithはFletcherの下の階に住むのではない。'(L) :- 何階('Smith',L,Smith), 何階('Fletcher',L,Fletcher), \+(Smith is Fletcher + 1). 'SmithはFletcherの上の階に住むのではない。'(L) :- 何階('Smith',L,Smith), 何階('Fletcher',L,Fletcher), \+(Smith is Fletcher - 1). 'SmithはFletcherの下の階に住むのではない。'(L) :- 何階('Fletcher',L,Fletcher), 何階('Cooper',L,Cooper), \+(Fletcher is Cooper - 1). 'FletcherはCooperの隣の階に住むのではない。'(L) :- 'FlecherはCooperの上の階に住むのではない。'(L), 'FlecherはCooperの下の階に住むのではない。'(L). 'FletcherはCooperの上の階に住むのではない。'(L) :- 何階('Fletcher',L,Fletcher), 何階('Cooper',L,Cooper), \+(Fletcher is Cooper + 1).). 'FletcherはCooperの下の階に住むのではない。'(L) :- 何階('Fletcher',L,Fletcher), 何階('Cooper',L,Cooper), \+(Fletcher is Cooper - 1). 何階('Baker',[Baker,_,_,_,_],Baker). 何階('Cooper',[_,Cooper,_,_,_],Cooper). 何階('Fletcher',[_,_,Fletcher,_,_],Fletcher). 何階('Miller',[_,_,_,Miller,_],Miller). 何階('Baker',[_,_,_,_,Smith],Smith). 最上階(5). 最下階(1). 住んでいる階を表示する(L) :- write_formatted('Baker %t階,Cooper %t階,Fletcher %t階,Miller %t階,Smith %t階\n',L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1291471791/659 # # [1] 授業単元:アルゴリズムとデータ構造 # [2] 問題文(含コード&リンク): #   クイックソートにより異なる15個の要素を配列するとき、比較回数の最小値と最大値求め、 #   そのときに与えた要素をそれぞれ答えなさい。 #   たとえば1、2、3、、、、15を与えると、105回となる。といったかんじです。 #   #   プログラムの提出はないです。 #     # [4] 期限: 2010年12月17日13:00まで。 # 'クイックソートにより異なる15個の要素を配列するとき、比較回数の最小値と最大値求め、そのときに与えた要素をそれぞれ答えなさい。' :- findall([_比較回数,_15個の要素],( 15個の要素を生成(_15個の要素), クイックソートの比較回数の最小値と最大値求め(_15個の要素,_比較回数), L), max(L,[_最大比較回数,_最大比較回数の時の15個の要素]), min(L,[_最小比較回数,_最小比較回数の時の15個の要素]), write_formatted('最小比較回数は要素が%tの時で%t回\n',[_最小比較回数の時の15個の要素,_最小比較回数]), write_formatted('最大比較回数は要素が%tの時で%t回\n',[_最大比較回数の時の15個の要素,_最大比較回数]),!. 15個の要素を生成(_15個の要素) :- 順列([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],15,_15個の要素). 比較回数を記録したクイックソート([],0) :- !. 比較回数を記録したクイックソート([A|R1],_比較回数) :- 比較回数を記録した分割(A,R1,_Aより小さいならび,_Aと等しいか大きいならび,0,_比較回数0), 比較回数を記録したクイックソート(_Aより小さいならび,L3,_比較回数1), 比較回数を記録したクイックソート(_Aと等しいか大きいならび,L4,_比較回数2), append(L3,[A|L4],L2), _比較回数 is _比較回数0 + _比較回数1 + _比較回数2. 比較回数を記録した分割(A,[],[],[],_比較回数,_比較回数) :- !. 比較回数を記録した分割(A,[B|R1],R2,[B|R3],_比較回数1,_比較回数) :- B @>= A, _比較回数2 is _比較回数1 + 1, 比較回数を記録した分割(A,[B|R1],R2,[B|R3],_比較回数2,_比較回数). 比較回数を記録した分割(A,[B|R1],[B|R2],R3,_比較回数1,_比較回数) :- B @< A, _比較回数2 is _比較回数1 + 1, 比較回数を記録した分割(A,[B|R1],[B|R2],R3,_比較回数2,_比較回数). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1272006124/140 # # <問題> # A,B,Cの3人が100m競争をします。D,Eの2人が予想をしました。 # D : 「きっと1等はCで2等はBだ」 # E : 「ぼくは1等はAだと思う」 #  発表された順位を見て,2人はどちらも「まったくはずれた。」と # いいました。発表された順位はどうでしたか。 # # 中学受験用全解シリーズ 「受験全解・算数」日能研発行 の p424 から採りました。 # # 'A,B,Cの3人が100m競争をします。D,Eの2人が予想をしました。 D : 「きっと1等はCで2等はBだ」。 E : 「ぼくは1等はAだと思う」。 発表された順位を見て,2人はどちらも「まったくはずれた。」といいました。発表された順位はどうでしたか。' :- 発表された順位(L), write_formatted('発表された順位は 1等%t, 2等 %t, 3等 %t, です。\n',L). 発表された順位(L) :- 順列(['A','B','C'],3,L), '2人はどちらも「まったくはずれた。」'(L). '2人はどちらも「まったくはずれた。」'(L) :- \+('Dの予想'(L)), \+('Eの予想'(L)). 'Dの予想'(L) :- きっと1等はCで2等はBだ(L). きっと1等はCで2等はBだ(L) :- list_nth(1,L,'C'), list_nth(2,L,'B'). 'Eの予想'(L) :- ぼくは1等はAだと思う(L). ぼくは1等はAだと思う(L) :- list_nth(1,L,'A'). ぼくは1等はAだと思う(L) :- list_nth(Nth1,L,'A'), list_nth(Nth2,L,'B'), Nth1 < Nth2. ぼくは1等はAだと思う(L) :- list_nth(Nth1,L,'A'), list_nth(Nth3,L,'C'), Nth1 < Nth3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 順列(Y,0,_,[]). 順列(Y,N,EL,[A|X]) :- \+(member(A,EL)), del(Z = Y - A), M is N - 1, 順列(Z,M,EL,X). 順列(Y,N,EL,[_|X]) :- member(A,EL), 順列(Z,M,EL,X). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A). member(A,[A|_]). member(A,[_|R]) :- member(A,R). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1286978599/593 # # [1] 授業単元:プログラム実習 # [2] 問題文(含コード&リンク):nとrを入力して # 順列 nPr と組み合わせ nCr を表示するものを作成すること。 # 'nとrを入力して 順列 nPr と組み合わせ nCr を表示する' :- nとrを入力して(_n,_r), '順列 nPr と組み合わせ nCr を表示する'(_n,_r). nとrを入力して(_n,_r) :- nの入力(_n), rの入力(_r),!. nの入力(_n) :- write(n : ), get_line(Line), nの入力診断(Line,_n),!. nの入力(_n) :- nの入力(_n). nの入力診断(Line,_n) :- atom_to_term(Line,_n,_), integer(_n), _n > 0,!. nの入力診断(Line,_n) :- write_formatted('入力された %t からは適切な整数nが得られませんでした\n再入力をお願いします\n',[Line]), fail. rの入力(_r) :- write(r : ), get_lire(Line), rの入力診断(Line,_r),!. rの入力(_r) :- rの入力(_r). rの入力診断(Line,_r) :- atom_to_term(Line,_r,_), irteger(_r), _r > 0,!. rの入力診断(Line,_r) :- write_formatted('入力された %t からは適切な整数rが得られませんでした\r再入力をお願いします\r',[Line]), fail. '順列 nPr と組み合わせ nCr を表示する'(_n,_r) :- nPr(_n,_r,X), nCr(_n,_r,Y), write_formatted('n=%t,r=%tの時の nPr=%t\nn=%t,r=%tの時の nCr=%t\n',[_n,_r,X,_n,_r,Y]). nPr(N,R,X) :- M is N - R + 1, 階乗(M,N,X). nCr(N,R,X) :- U is N - R + 1, 階乗(U,N,K1), 階乗(R,K2), X is K1 // K2. % 以下のサイトは 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), succ(M,N), 順列(Z,M,X). % 以下のサイトは /* 順列(_,0,[]). 順列(_値ならび,_要素数,[_ある値|_順列]) :- select(_ある値,_値ならび,_残り値ならび), succ(_要素数_1,_要素数), 順列(_残り値ならび,_要素数_1,_順列). */ 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, 順列(Z,M,X). del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A). % del(A,[A|X],X). % del(A,[B|X],[B|Y]) :- % del(A,X,Y). % 以下のサイトは # c137 #534 # [1] 授業単元: Visual Studio 入門 # [2] 問題 半乱順列の関数作成 # :- op(300,xf,回). :- op(700,xf,切る). 半乱順列の作成(_置換指定,_対象ならび,_半乱順列ならび) :- 整列(_対象ならび,_整列したならび), 整列したならび乱す(_置換指定,_整列したならび,_半乱順列ならび). 整列したならび乱す(最初と最後の要素を入れ替える,L1,L2) :- '最初と最後の要素を入れ替えて、整列したならびを乱す'(L1,L2). 整列したならびを乱す(N 回 切る,L1,L2) :- 'N回切って、整列したならびを乱す'(N,L1,L2). 整列したならびを乱す([[N1,N2]|R],L1,L2) :- '入れ替え位置指定ならびから、整列したならびを乱す'([[N1,N2]|R],L1,L2). '最初と最後の要素を入れ替えて、整列したならびを乱す'(L1,L2) :- [A|R]=L3, append(L4,[B],R), append([B|L4],[A],L2),!. 'N回切って、整列したならびを乱す'(0,L,L) :- !. 'N回切って、整列したならびを乱す'(N,L1,L2) :- 入れ替え位置を得る(L1,N1,N2), ならびの交換(N1,N2,L1,L3), succ(N1,N), 'N回切って、整列したならびを乱す'(N1,L1,L2). 入れ替え位置を得る(L1,N1,N2) :- length(L1,Len), N1 is random mod Len, N2 is random mod Len. '入れ替え位置指定ならびから、整列したならびを乱す'([],L,L) :- !. '入れ替え位置指定ならびから、整列したならびを乱す'([[N1,N2]|R],L1,L2) :- ならびの交換(N1,N2,L1,L3), '入れ替え位置指定ならびから、整列したならびを乱す'(R,L3,L2). ならびの交換(M,N,_対象ならび,_交換したならび) :- 'M番目の要素と前後'(M,L1,A,R1), 'N番目の要素と前後'(N,L2,B,R2), 要素を入れ替えながらならびの再構成(L1,A,R1,L2,B,R2). 'M番目の要素と前後'(M,L1,A,R1) :- M1 is M - 1, append(L1,[A|R1],_対象ならび), length(L1,M1),!. 'N番目の要素と前後'(N,L2,B,R2) :- N1 is N - 1, append(L2,[B|R2],_対象ならび), length(L2,N1),!. 要素を入れ替えながらならびの再構成(L1,A,R1,L2,B,R2) :- append(L1,[B|R1],L3), append(L4,[_|R3],L3), length(L4,N1), append(L4,[A|R3],_交換したならび),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1269438098/312 # # [1] 授業単元: Introduction to C++ # [2] 問題文: ユーザーにサイズN(最大で100000)を入力させ、そのサイズのArrayを1〜100までのランダムな数字で埋めた後、N個のランダムな数字を数字1、数字2、数字3・・・という具合にカウントするプログラムを書きなさい # (元の文が英文なのですが、約した際に何かしら抜け落ちている点が在るかもしれないので一応原文も記載しておきます) # Write a program that asks user to enter a size, N. (The maximum is 100000). Write a # function that generates random numbers in range of 1 ~ 100 and fill an array of size N. # You also need to count how many 1’s, 2’s, 3’s, # 4’s, 5’s, …, 100’s. If the random number function does it job perfectly, the distribution to # each number should be equal. But they might be slightly off. # ライン([A,B,C,2],[2,E,F,G],[G,H,B,1],[1,C,E,3]). '空いている○の中に4~12の数字を入れ、5つある線上の合計が等しくなるようにした場合、あまる数字は何と何か?なお、同じ数字は使えません。'(_あまる数字ならび) :- ライン(L1,L2,L3,L4), flat([L1,L2,L3,L4],L), 未知数はいくつあるか(L,[],_重複しない変数ならび,_未知数の数), findall(M,for(4,M,12),_候補数値ならび), 順列(_候補数値ならび,_未知数の数,_重複しない変数ならび), 加算(L1,X),加算(L2,X),加算(L3,X),加算(L4,X), 差集合(_候補数値ならび,VL,_あまる数字ならび). 未知数はいくつあるか([],L,L,N) :- length(L,N),!. 未知数はいくつあるか([V|R],L,VL,X) :- var(V), \+memberV(V,L), 未知数はいくつあるか(R,[V|L],VL,X),!. 未知数はいくつあるか([V|R],L,VL,X) :- var(V), memberV(V,L), 未知数はいくつあるか(R,L,VL,X),!. 未知数はいくつあるか([_|R],L,VL,X) :- 未知数はいくつあるか(R,L,VL,X),!. memberV(V1,[V2|R]) :- V1==V2,!. memberV(V,[_|R]) :- memberV(V,R). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1263824755/200 # # [1] 授業単元: プログラミング # [2] 問題文(含コード&リンク): # A組、B組、C組にそれぞれn人の生徒がいて、 # A組の生徒が一列に並んでいる。 # このとき、B組の生徒をA組の生徒の隣に並ばせたいが # なるべく隣同士で身長に差がないようにしたい。 # どうやって計算すればいいでしょう? # 加えて、C組の生徒もB組の隣に並ばせたい場合はどうすれば? # (身長の配列) double height_a[n], height_b[n], height_c[n]; なるべく隣同士で身長に差のない並び方(La,Lb,N,LbX) :- findmin([S,L],ならび候補(La,Lb,N,L,S),Min), Min = [_,LbX],!. ならび候補(La,Lb,N,L,S) :- 順列(Lb,N,L), findsum(U,(for(1,M,N),list_nth(M,La,A),list_nth(M,L,B),U is (B-A) ^ 2),S). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1222224721/610 # # # 鶴と亀の頭の数の合計と足の数の合計を入力して, 鶴が何羽,亀が何匹いるか # を表示する。(ヒント:頭の数と足の数を変数として,鶴の数と亀の数について # 連立方程式を作り,解を与える式の値を表示させればよい) # %%%%%%%%%%%%%%%%%%% 第一案 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 鶴と亀の頭の数の合計と足の数の合計を入力して, 鶴が何羽,亀が何匹いるか :- 催促付き整数入力('鶴と亀の頭の数合計 : ',_鶴と亀の頭の数の合計), 催促付き整数入力('鶴と亀の足の数の合計 : ',_鶴と亀の足の数の合計), findall(N,for(0,N,_鶴と亀の頭の数の合計),L), 重複順列(L,2,[A,B]), _鶴と亀の頭の数の合計 is A + B, _鶴と亀の足の数の合計 is 2 * A + 4 * B, writef('鶴が%t羽、亀が%t匹。\n',[A,B]). %%%%%%%%%%%%%%%%%%% 第二案 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 鶴と亀の頭の数の合計と足の数の合計を入力して, 鶴が何羽,亀が何匹いるか :- 催促付き整数入力('鶴と亀の頭の数合計 : ',_鶴と亀の頭の数の合計), 催促付き整数入力('鶴と亀の足の数の合計 : ',_鶴と亀の足の数の合計), 既約ガウス行列に変形([[1,1,_鶴と亀の頭の数の合計],[2,4,_鶴と亀の足の数の合計]],[[_,_,_鶴何羽],[_,_,_亀何匹]]), write_formatted('鶴が%t羽、亀が%t匹\n',[_鶴何羽,_亀何匹]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 鶴亀算(_鶴と亀の頭の数の合計,_鶴と亀の足の数の合計,_鶴が何羽,_亀が何匹) :- 既約ガウス行列に変形([[1,1,_鶴と亀の頭の数の合計],[2,4,_鶴と亀の足の数の合計]],[[_,_,_鶴が何羽],[_,_,_亀が何匹]]),!. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 本来の鶴亀算 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 一羽の鶴の足の数(2). 一匹の亀の足の数(4). 鶴亀算(_鶴と亀の頭の数の合計,_鶴と亀の足の数の合計,_鶴が何羽,_亀が何匹) :- 仮に全部鶴だったらどうなるか考えよう(_鶴と亀の頭の数の合計,_仮の鶴と亀の足の数の合計), 実際の鶴と亀の足の数の合計は仮の鶴と亀の足の数の合計より多いことを確認しよう(_仮の鶴と亀の足の数の合計,_鶴と亀の足の数の合計), 実際の鶴と亀の足の数の合計との差は(_仮の鶴と亀の足の数の合計,_鶴と亀の足の数の合計,_実際の鶴と亀の足の合計との差), この差が生じたのは亀が鶴に混じるとその分足の数も多くなるからであり, 亀の数の分だけ一匹の亀の足が一羽の鶴よりも多い分だけの差が生じている考えられる, ということは, 亀の数は(_実際の鶴と亀の足の合計との差,_亀が何匹), 鶴の数は頭の合計から亀の数を引けばよい(_鶴と亀の頭の数の合計,_亀が何匹,_鶴が何羽). 仮に全部鶴だったらどうなるか考えよう(_鶴と亀の頭の数の合計,_仮に全部鶴だとした場合の足の数の合計) :- 一羽の鶴の足の数(_一羽の鶴の足の数), _仮に全部鶴だとした場合の足の数の合計 is _一羽の鶴の足の数 * _鶴と亀の頭の数の合計. 実際の鶴と亀の足の数の合計は仮の鶴と亀の足の数の合計より多いことを確認しよう(_仮の鶴と亀の足の数の合計,_鶴と亀の足の数の合計) :- _鶴と亀の足の数の合計 > _仮の鶴と亀の足の数の合計. 実際の鶴と亀の足の数の合計との差は(_仮に全部鶴だとした場合の足の数の合計,_鶴と亀の足の数の合計,_実際の鶴と亀の足の合計との差) :- _実際の鶴と亀の足の合計との差 is _鶴と亀の足の数の合計 - _仮に全部鶴だとした場合の足の数の合計. 亀の数は(_実際の鶴と亀の足の合計との差,_亀が何匹) :- 一羽の鶴の足の数(_一羽の鶴の足の数), 一匹の亀の足の数(_一匹の亀の足の数), _亀が何匹 is _実際の鶴と亀の足の合計との差 // (_一匹の亀の足の数 - _一羽の鶴の足の数). 鶴の数は頭の合計から亀の数を引けばよい(_鶴と亀の頭の数の合計,_亀が何匹,_鶴が何羽) :- _鶴が何羽 is _鶴と亀の頭の数の合計 - _亀が何匹. この差が生じたのは亀が鶴に混じるとその分足の数も多くなるからであり. 亀の数の分だけ一匹の亀の足が一羽の鶴よりも多い分だけの差が生じている考えられる. ということは. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % 鶴亀算でどうしても課題として残ることは、最初に鶴に着目して考え始めるか % そうではなくて亀なのか。ここら辺りの曖昧さ、恣意性をどう表現するかだろう。 % /* 最初に、鶴か亀に着眼する(鶴) :- 0 is random mod 2,!. 最初に、鶴か亀に着眼する(亀). 鶴と亀とどちらが足が多いか(亀) :- 一羽の鶴の足の数(_鶴の足の数), 一匹の亀の足の数(_亀の足の数), _亀の足の数 > _鶴の足の数,!. 鶴と亀とどちらが足が多いか(鶴). */ % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1258158172/432 # # [1] 授業単元:暇なヤシ集まれ # [2] 問題文(含コード&リンク): #  最大10桁の数字列sと 10000 以下の正整数dが #  与えられたとき、sの各数字を並べ替えて出来る全 #  ての数の中で、dで割り切れる数の総数を求める。 # #  計算例) s, d => 解 #  ・ 000, 1 => 1 #  ・ 1234567890, 1 => 3628800 #  ・ 123434, 2 => 90 # '最大10桁の数字列sと 10000 以下の正整数dが与えられたとき、sの各数字を並べ替えて出来る全ての数の中で、dで割り切れる数の総数を求める'(_数字ならび,D,X) :- length(_数字ならび,Len), Len =< 10, D < 10000, findall(Y,(数字ならびから順列整数(_数字ならび,Len,Y),0 is Y mod D),L), sort(L,L2), length(L2,X). 数字ならびから順列整数(Y,0,0). 数字ならびから順列整数(Y,N,X) :- del(Z = Y - A), M is N - 1, 数字ならびから順列整数(Z,M,X2), X is truncate(10^M*A+X2). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1258158172/283 # # [1] 授業単元: C言語演習 # [2] 問題文(含コード&リンク): 以下の掛け算の表示プログラムを作成しなさい。 #     1 2 3  4  5  6  7  8  9 10 #     2 4 6  8 10 12 14 16 18 20 #     3 6 9 12 15 18 21 24 27 30 #     ・ #     ・ #     ・ #    10・・・                    100 九九表示 :- 重複順列([1,2,3,4,5,6,7,8,9,10],2,[M,N]), S is M * N, write_formatted('%3d',[S]), N = 10, nl, fail. 九九表示. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1258158172/212 # # [1] 授業単元:プログラミング演習 # [2] 問題文: # 3行3列の実数行列A=[a_ij]とB[b_ij]の積ABを計算せよ。 # ただし、乗算結果の行列を[c_ij]として次の計算を行うものとする。 # 行列の要素への入力は、代入文あるいは初期化子をもちいること。 # c_ij=Σa_ik×b_kj (Σはk=0で、2までです) # 行列の掛け算(_行列a,_行列b,_行列c) :- findall(L1,(for(1,N,3),length(L1,3)),_行列c), findall(W,重複順列([1,2,3],2,W),_重複順列), 行列の掛け算(_重複順列,_行列a,_行列b,_行列c),!. 行列の掛け算([],_,_,_) :- !. 行列の掛け算([[I,J]|R1],_行列a,_行列b,_行列c) :- findsum(U,( for(1,K,3), 行列要素(_行列a,I,K,N1), 行列要素(_行列b,K,J,N2), U is N1 * N2),S), 行列要素(_行列c,I,J,S), 行列の掛け算(R1,_行列a,_行列b,_行列c). 行列要素(_行列,_行,_列,_値) :- list_nth(_行,_行列,_行の値ならび), list_nth(_列,_行の値ならび,_値). 重複順列(L,N,X) :- length(X,N),重複順列(L,X). 重複順列(L,[]). 重複順列(L,[A|R]) :- member(A,L),重複順列(L,R). % 以下のサイトは # 出典 :: C/C++の宿題片付けます 132代目 #72 # [1]授業単元:プログラミング演習 # [2] 1から100000までの数を列挙する。 # nまで書き終わった時点でそれぞれの数字dがtimes[d] (0<=d<=9)回使われていたとする。 # times[d]が小さい順にdを並べて順列を作る。(同じ回数の場合dが大きいほうが後)この順列が最初からそれまでに累積何回変わったか # nが1000の倍数毎に表にして出力(100000まで) # 回数と順位を要素とする構造体配列を使うこと # 整数の文字表現が増えると累計順位が変化する(_n個まで,_順位交代回数) :- 整数の文字表現が増えると累計順位が変化する(1,100000,[[0,'0'],[1,'1'],[0,'2'],[0,'3'],[0,'4'],[0,'5'],[0,'6'],[0,'7'],[0,'8'],[0,'9']],['0','2','3','4','5','6','7','8','9','1'],0,_n個まで,_順位交代回数). 整数の文字表現が増えると累計順位が変化する(Max,Max,_,_,_順位交代回数,Max,_順位交代回数) :- !. 整数の文字表現が増えると累計順位が変化する(N,Max,_,_,_順位交代回数,N,_順位交代回数) :- 0 is N mod 1000. 整数の文字表現が増えると累計順位が変化する(N,Max,LL1,_順位ならび_1,_順位交代回数_1,_n個まで,_順位交代回数) :- 整数の文字表現が増えると累計順位が変化して行く(N,Max,LL1,_順位ならび_1,_順位交代回数_1,_n個まで,_順位交代回数). 整数の文字表現が増えると累計順位が変化して行く(N,Max,LL1,_順位ならび_1,_順位交代回数_1,_n個まで,_順位交代回数) :- 整数の文字表現が増えると(N,N_2,_次の数字ならび), 最新の順位ならび(_次の数字ならび,LL1,LL2,_順位ならび_2), 累計順位が変化して行く(N_2,Max,LL2,_順位ならび_1,_順位ならび_2,_順位交代回数_1,_n個まで,_順位交代回数). 整数の文字表現が増えると(N,N_2,_次の数字ならび) :- succ(N,N_2), number_chars(N_2,_次の数字ならび). 最新の順位ならび(_次の数字ならび,LL1,LL2,_順位ならび_2) :- 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'(_次の数字ならび,LL1,LL2), 順位ならび(LL2,_順位ならび_2). 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'([],LL,LL). 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'(_標本値ならび,LL1,LL) :- 'select/4で鍵管理して標本値の出現度数を加算して行く(但し、[_度数,_標本値]の順に管理される)'(_標本値ならび,LL1,LL). 'select/4で鍵管理して標本値の出現度数を加算して行く(但し、[_度数,_標本値]の順に管理される)'([_標本値|R],LL1,LL) :- 'select/4で鍵管理して標本値の出現度数を加算(但し、[_度数,_標本値]の順に管理される)'(_標本値,LL1,LL2), 'select/4を使った標本値の出現度数加算(但し、[_度数,_標本値]の順に管理される)'(R,LL2,LL). 'select/4で鍵管理して標本値の出現度数を加算(但し、[_度数,_標本値]の順に管理される)'(_標本値,LL1,LL2) :- select([_度数_1,_標本値],LL1,[_度数_2,_標本値],LL2), succ(_度数_1,_度数_2). 順位ならび(_度数標本値ならび,_順位ならび) :- '度数・標本値順に整列する'(_度数標本値ならび,_整列した度数標本値ならび), 整列された度数標本値ならびから標本値の順位を取り出す(_整列した度数標本値ならび,_順位ならび). '度数・標本値順に整列する'(_度数標本値ならび,_整列した度数標本ならび) :- sort(_度数標本値ならび,_整列した度数標本ならび). 整列された度数標本値ならびから標本値の順位を取り出す(_整列した度数標本値ならび,_順位ならび) :- findall(_標本値,member([_,_標本値],_整列した度数標本値ならび),_順位ならび). 累計順位が変化して行く(N_2,Max,LL2,_順位ならび_1,_順位ならび_2,_順位交代回数_1,_n個まで,_順位交代回数) :- 順位に変化があった場合だけ順位交代回数を更新する(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2), 整数の文字表現が増えると累計順位が変化する(N_2,Max,LL2,_順位ならび_2,_順位交代回数_2,_n個まで,_順位交代回数). 順位に変化があった場合だけ順位交代回数を更新する(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2) :- '順位に変化があった場合、交代回数が更新される'(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2),!. 順位に変化があった場合だけ順位交代回数を更新する(_,_,_順位交代回数,_順位交代回数). '順位に変化があった場合、交代回数が更新される'(_順位ならび_1,_順位ならび_2,_順位交代回数_1,_順位交代回数_2) :- '順位に変化があった場合、'(_順位ならび_1,_順位ならび_2), 交代回数が変化する(_順位交代回数_1,_順位交代回数_2). '順位に変化があった場合、'(_順位ならび_1,_順位ならび_2) :- \+(sort(_順位ならび_1,_順位ならび_2)). 交代回数が変化する(_順位交代回数_1,_順位交代回数_2) :- succ(_順位交代回数_1,_順位交代回数_2). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1255709298/725 # # [1] 授業単元: アルゴリズム[I] # [2] 問題文(含コード&リンク):a,b,c,d,eの5文字をアルファベットとして #  重複なく4文字をで構成される全てのwordのなかで部分文字列として、 #  ad,bd,deを含まないものを表示せよ 'a,b,c,d,eの5文字をアルファベットとして重複なく4文字で構成される全てのwordのなかで部分文字列として、ad,bd,deを含まないものを表示' :- 順列([a,b,c,d,e],4,L), \+(append(_,[a,d|_],L)), \+(append(_,[b,d|_],L)), \+(append(_,[d,e|_],L)), atom_chars(_語,L), write_formatted('%t\n',[_語]), fail. 'a,b,c,d,eの5文字をアルファベットとして重複なく4文字で構成される全てのwordのなかで部分文字列として、ad,bd,deを含まないものを表示'. % *** user: '順列' / 3 *** 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). % *** user: del / 3 *** del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1250204272/420 # # [1] 授業単元:プログラミング基礎 # [2] 問題文(含コード&リンク): # 車のナンバーや電車の切符の裏などにある4桁の数字。その数字を四則演算し10にするというクイズを解くプログラムをお願いします。 # 1 2 3 4 と言う4つの数字であれば、すべて足せば10になりますし # 2 3 5 7 は{(3+7)/2+5}で10になります。 # # 数字の順番は変えてもOK(上のように2357を3725と並び替えている) # 二つの数字をくっつけて1つにしてもOK(0 0 1 2を20-10) # # 数字を4つ入力し、全パターンを出力するプログラムをお願いします。 % 四則演算 と 置換([A,B|R],[C|R]) :- C is 10 * A + B t687(L,_式) :- 順列(L,4,L1), t687_1(L1,_式,10). t687_1([A],A,A). t687_1([A,B|R1],C,X) :- C is 10 * A + B, t687_1(R1,_式_2,Y). t687_1([A,B|R1],_式,X) :- \+(R1=[]), C is 10 * A + B, t687_1(R1,_式_2,Y), t687_2(C,_関数,Y,X), _式 =.. [_関数,C,_式_2]. t687_1([A|R1],_式,X) :- t687_1(R1,_式_2,Y), t687_2(A,_関数,Y,X), _式 =.. [_関数,A,_式_2]. t687_2(A,+,B,X) :- X is A + B. t687_2(A,-,B,X) :- X is A - B. t687_2(A,*,B,X) :- X is A * B. t687_2(A,//,B,X) :- 0 is A mod B, X is A // B. % *** user: 順列 / 4 *** 順列(Y,0,_,[]). 順列(Y,N,EL,[A|X]) :- \+(member(A,EL)), del(Z = Y - A), M is N - 1, 順列(Z,M,EL,X). 順列(Y,N,EL,[_|X]) :- member(A,EL), 順列(Z,M,EL,X). % *** user: 順列 / 3 *** 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, 順列(Z,M,X). % *** user: del / 3 *** del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % *** user: del / 1 *** del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A). % *** user: 重複順列 / 3 *** 重複順列(L,N,X) :- length(X,N),重複順列(L,X). 重複順列(L,[]). 重複順列(L,[A|R]) :- member(A,L),重複順列(L,R). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/811 # # [1] 授業単元:プログラミング演習 # [2] 問題文(含コード&リンク): # 入力として与えられた文字列のアナグラム(anagram)を出力するプログラムanagram.c # を作成せよ。 # # % ./a.out # String: abc # abc acb bac bca cab cba # % # # 入力する文字数が増えると計算時間はどのように変化していくかを考えよ。 # プログラムの実行時間は、「time」コマンドを使用して計測せよ。 # timeコマンドの結果のうち、ユ ーザ時間がプログラムの実行時間になります。 # # % time ./a.out # String: abc # abc acb bac bca cab cba # # real 0m0.002s # user 0m0.000s # sys 0m0.001s root# time prologuexxx -query0 't617(abc)' real 0m0.111s user 0m0.072s sys 0m0.040s root# time prologuexxx -query0 't617(abcdef)' real 0m0.116s user 0m0.072s sys 0m0.044s root# time prologuexxx -query0 't617(abcdefghi)' real 0m3.298s user 0m2.880s sys 0m0.416s %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% t617(Atom) :- anagram(Atom,Anagram), halt,!. anagram(Atom,Anagram) :- atom_chars(Atom,Chars), length(Chars,Len), findall(S,(順列(Chars,Len,L),concat_atom(L,S)),X), concat_atom(X,' ',Anagram). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1153585095/918 # # 所謂覆面算で # 英字一文字が一桁の数字(0-9)で表されるとき # one # + nine # + twenty # + fifty # = eighty # となる組み合わせを検索してください # 各行の先頭の文字は0以外です # % 'one + nine + twenty + fifty = eighty' 覆面算(S,LX) :- 覆面算(S,_文字数,_先頭文字ならび,_左項式,_右項式), 順列([0,1,2,3,4,5,6,7,8,9],_文字数,LX2), 変数を対応させる(_先頭文字ならび,LX2,LX), A is _右項式, B is _左項式, A = B. 覆面算(S,_文字数,_先頭文字ならび,_左項式,_右項式) :- split(S,['+',' '],L), 各項の先頭文字(L,_先頭文字ならび), append(L1,LX,L), concat_atom(L,S1), atom_chars(S1,L2), 各文字に変数を割り当てる(L2,[],LV), length(LV,_文字数), 式を構成する(L1,LV,_左項式), 式を構成する(L2,LV,_右項式). 各文字に変数を割り当てる([],X,X). 各文字に変数を割り当てる([A|R1],Y,X) :- member(A,[A=_,Y]), 各文字に変数を割り当てる(R1,Y,X). 各文字に変数を割り当てる([A|R1],Y,X) :- not(member([A=_,Y])), 各文字に変数を割り当てる(R1,[A=_|Y],X). 式を構成する([],_,0). 式を構成する([A|R1],LV,_式 + Y) :- atom_chars(A,Chars), length(Chars,Len), 覆面数値式(Len,LV,Chars,_式), 式を構成する(R1,LV,Y). 覆面数値式(0,_,_,0) :- !. 覆面数値式(N,LV,[A|R1],B + C) :- member(A=V,LV), B = ((10 ^ (N-1)) * V), N2 is N - 1, 覆面数値式(N2,LV,R1,C). 変数を対応させる(_,[],[]) :- !. 変数を対応させる(_先頭文字ならび,[A|R1],[B=A|R2]) :- member(B,_先頭文字ならび),!, not(A=0), 変数を対応させる(_先頭文字ならび,R1,R2). 変数を対応させる(_先頭文字ならび,[A|R1],[B=A|R2]) :- not(member(B,_先頭文字ならび)), 変数を対応させる(_先頭文字ならび,R1,R2). 各項の先頭文字(L,_先頭文字ならび) :- findall(C,(member(A,L),sub_atom(A,0,1,_,C)),_先頭文字ならび). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/157 # # [1] 授業単元: C++ # [2] 問題文(含コード&リンク): # http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9762.txt # # 正数による正方行列のうち、全ての行、列、斜め列の合計が同じであり、 # かつ2回以上使用される数字が存在しないものを魔方陣という。 # 下図に示すa,bに数値を設定したときに、1〜9の整数によって構成される魔方陣を # 出力するプログラムを作成せよ。 # 但し、魔方陣が作成不可能な(a,b)の組み合わせが設定された場合は、「Impossible」 # と出力するとする。 # # la_lb_l__l # l__l__l__l # l__l__l__l # 魔方陣(N枡,A,B,_行列) :- 魔方陣のための行列の生成(N枡,_行列), _行列 = [[A,B|_],_,_], 行の合計が全て一致する(_行列,S), 列の合計が全て一致する(_行列,S), 正方行列の斜め要素の合計が一致する(_行列,S). 魔方陣のための行列の生成(N枡,_行列) :- N2 is N枡 ^ 2, findall(M,for(1,M,N2),NL),!, 順列(NL,N2,_順列数字ならび), findall(_N個組,n個組(N枡,_順列数字ならび,_N個組),_行列). 行の合計が全て一致する([],S) :- !. 行の合計が全て一致する([_行|R],S) :- 魔方陣の加算(_行,0,S), 行の合計が全て一致する(R,S). 列の合計が全て一致する(_行列,S) :- 行列の転置(_行列,_転置行列), 列の合計が全て一致する(_転置行列,S),!. 正方行列の斜め要素の合計が一致する(_正方行列,S) :- length(_行列,Len), 左上から右下方向の合計(1,Len,_正方行列,0,S), 右上から左下方向の合計(1,Len,_正方行列,0,S),!. 左上から右下方向の合計(M,N,_,S,S) :- M > N,!. 左上から右下方向の合計(M,N,_行列,S1,S) :- list_nth(M,_行列,_行), list_nth(M,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 左上から右下方向の合計(M2,N,_行列,S2,S),!. 右上から左下方向の合計(M,N,_,S,S) :- M > N,!. 右上から左下方向の合計(M,N,_行列,S1,S) :- M1 is N - M + 1, list_nth(M1,_行列,_行), list_nth(M1,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 右上から左下方向の合計(M2,N,_行列,S2,S),!. n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. 魔方陣の加算([],X,X) :- !. 魔方陣の加算([A|R],Y,X) :- Z is A + Y, 魔方陣の加算(R,Z,X). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1244449887/842 # # [1] C言語 # [2]1〜5の数字の組み合わせをを2次元配列index[][]に格納し、表示しなさい。 t268(X) :- 組合せ([1,2,3,4,5],2,X). 組合せ(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). % *** user: '重複組合せ' / 3 *** '重複組合せ'(X,1,[A]) :- member(A,X) . '重複組合せ'([A|Y],N,[A|X]) :- N > 1, M is N - 1, '重複組合せ'([A|Y],M,X) . '重複組合せ'([_|Y],N,A) :- N > 1, '重複組合せ'(Y,N,A) . % *** user: '順列' / 3 *** '順列'(Y,0,[]). '順列'(Y,N,[A|X]) :- del(Z = Y - A), M is N - 1, '順列'(Z,M,X) . % *** user: del / 3 *** del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y) . % *** user: del / 1 *** del(X = [A|X] - A). del([B|Y] = [B|X] - A) :- del(Y = X - A) . % *** user: '重複順列' / 3 *** '重複順列'(L,N,X) :- length(X,N), '重複順列'(L,X) . % *** user: '重複順列' / 2 *** '重複順列'(L,[]). '重複順列'(L,[A|R]) :- member(A,L), '重複順列'(L,R) . % 以下のサイトは % <<問題2>>「論理少女1」つじ要作 というマンガの中に出てくる問題です。 % 4箇所の隠し場所と4つのアイテム(お金)は>>62と同じですが、 % 隠す場所は一度ご破算にします。以下のヒントを読んで、 % できるだけ問題文に忠実な表現になるようにプログラミングしてください。 % 1) 髪の中かスカートのポケットのどちらか一万円札が入っている % 2) 胸のポケットに入っているお金はスカートに入ってるお金の10倍 % 3) 百円玉は千円札より上の位置にある % 4) 靴の中のお金は髪の中のお金の100倍 % そして、1)..4)のうちどれかが嘘。 % それでは、 % 靴の中のお金は? % :- op(800,xfx,は). :- op(650,xfx,の). :- op(250,xf,円). 隠した物([一万円札,千円札,百円玉,十円玉]). 隠した場所([髪の中,胸のポケット,スカートのポケット,靴の中]). 髪の中 は 胸のポケット の 直ぐ上にある. 胸のポケット は スカートのポケット の 直ぐ上にある. スカートのポケット は 靴の中 の 直ぐ上にある. A は B の 上にある :- A は B の 直ぐ上にある. A は B の 上にある :- A は C の 直ぐ上にある,C は B の 上にある. お金(一万円札,10000 円). お金(千円札,1000 円). お金(百円玉,100 円). お金(十円玉,10 円). '靴の中のお金は?'(_靴の中のお金) :- 解候補の生成(_解), 靴の中のお金は?(_解,_靴の中のお金). '靴の中のお金は?'(_解,_靴の中のお金) :- member([靴の中,_靴の中のお金],_解), not(ヒント(1,_解)), ヒント(2,_解), ヒント(3,_解), ヒント(4,_解). '靴の中のお金は?'(_解,_靴の中のお金) :- member([靴の中,_靴の中のお金],_解), ヒント(1,_解), not(ヒント(2,_解)), ヒント(3,_解), ヒント(4,_解). '靴の中のお金は?'(_解,_靴の中のお金) :- member([靴の中,_靴の中のお金],_解), ヒント(1,_解), ヒント(2,_解), not(ヒント(3,_解)), ヒント(4,_解). '靴の中のお金は?'(_解,_靴の中のお金) :- member([靴の中,_靴の中のお金],_解), ヒント(1,_解), ヒント(2,_解), ヒント(3,_解), not(ヒント(4,_解)). 解候補の生成(_解) :- 隠した物(_隠した物リスト), 隠した場所(_隠した場所リスト), length(_隠した物リスト,_要素数), 順列(_隠した物リスト,_要素数,_物候補), 解候補の生成(_隠した場所リスト,_物候補,_解). 解候補の生成([],_,[]). 解候補の生成([A|R1],[B|R2],[[A,B]|R]) :- 解候補の生成(R1,R2,R). ヒント(1,_解) :- member([髪の中,一万円札],_解). ヒント(1,_解) :- member([スカートのポケット,一万円札],_解). ヒント(2,_解) :- member([_千円札の場所,千円札],_解), member([_百円玉場所,百円玉],_解), _十円玉の場所 は _千円札の場所 の 上にある. ヒント(3,_解) :- member([スカートのポケット,_物1],_解), member([胸のポケット,_物2],_解), お金(_物1,_円1 円), お金(_物2,_円2 円), _円1 is _円2 * 10. ヒント(4,_解) :- member([靴の中,_物1],_解), member([髪の中,_物2],_解), お金(_物1,_円1 円), お金(_物2,_円2 円), _円1 is _円2 * 100. 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # <<問題>> この問題は他の言語の宿題スレの問題ではありません。 # 「論理少女1」つじ要作 というマンガの中に出てくる問題です。 # できるだけ、問題文に忠実な表現になるようにこの問題を解いてください。 # <<問題は3問ありますが、手始めに第一問>> # # ちょうど一万円札・千円札・百円玉・十円玉があるわ。今からこのお金を・・・ # 髪の中、胸のポケット、スカートのポケット、靴の中に・・・それぞれ一つずつ隠します # # ヒントをもとにどこに何を隠したかを当てていくのよ では第一問 ヒントは、 # ・ 一万円札は髪の中 # ・ 千円札は十円玉より上の位置 # ・ スカートには胸の10倍のお金が入っている # それでは、全てのお金の位置は? :- op(800,xfx,は). :- op(650,xfx,の). :- op(250,xf,円). 隠した物([一万円札,千円札,百円玉,十円玉]). 隠した場所([髪の中,胸のポケット,スカートのポケット,靴の中]). 髪の中 は 胸のポケット の 直ぐ上にある. 胸のポケット は スカートのポケット の 直ぐ上にある. スカートのポケット は 靴の中 の 直ぐ上にある. A は B の 上にある :- A は B の 直ぐ上にある. A は B の 上にある :- A は C の 直ぐ上にある,C は B の 上にある. お金(一万円札,10000 円). お金(千円札,1000 円). お金(百円玉,100 円). お金(十円玉,10 円). ヒント(1,_解). member([髪の中,一万円札],_解). ヒント(2,_解) :- member([_千円札の場所,千円札],_解), member([_十円玉場所,十円玉],_解), _千円札の場所 は _十円玉の場所 の 上にある. ヒント(3,_解) :- member([スカートのポケット,_物1],_解), member([胸のポケット,_物2],_解), お金(_物1,_円1 円), お金(_物2,_円2 円), _円1 is _円2 * 10. 全てのお金の位置は?(_解) :- 解候補の作成(_解), ヒント(1,_解), ヒント(2,_解), ヒント(3,_解). 解候補の生成(_解) :- 隠した物(_隠した物リスト), 隠した場所(_隠した場所リスト), length(_隠した物リスト,_要素数), 順列(_隠した物リスト,_要素数,_物候補), 解候補の生成(_隠した場所リスト,_物候補,_解). 解候補の生成([],_,[]). 解候補の生成([A|R1],[B|R2],[[A,B]|R]) :- 解候補の生成(R1,R2,R). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X).