このディレクトリの索引

% 以下のサイトは 女王様(_女王様の数,_女王様縦変位順列) :- '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(_別のある女王様の縦変位 - _女王様の縦変位) =\= _横変位. % 以下のサイトは '鍵とselect/4を使った累計表'([],LL,LL). '鍵とselect/4を使った累計表'(_鍵_加算値ならび,LL1,LL) :- '鍵ごとに累計して行く'(_鍵_加算値ならび,LL1,LL). 鍵ごとに累計して行く(_鍵_加算値ならび,LL1,LL) :- 鍵がLL1に存在するときは累計して行く(_鍵_加算値ならび,LL1,LL),!. 鍵ごとに累計して行く(_鍵_加算値ならび,LL1,LL) :- 鍵がLL1に存在しないときはその鍵は無視する(_鍵_加算値ならび,LL1,LL). 鍵がLL1に存在するときは累計して行く([_鍵_加算値|R],LL1,LL) :- 累計値の更新(_鍵_加算値,LL1,LL2), '鍵とselect/4を使った累計表'(R,LL2,LL),!. 累計値の更新([_鍵,_加算値],LL1,LL2) :- select([_鍵,_累計値_1],LL1,[_鍵,_累計値_2],LL2), _累計値_2 is _累計値_1 + _加算値. 鍵がLL1に存在しないときはその鍵は無視する([_|R],LL1,LL) :- '鍵とselect/4を使った累計表'(R,LL1,LL). % 以下のサイトは '鍵とselect/4を使った度数加算'([],LL,LL). '鍵とselect/4を使った度数加算'(_鍵ならび,LL1,LL) :- '鍵ごとに度数加算して行く'(_鍵ならび,LL1,LL). 鍵ごとに度数加算して行く(_鍵ならび,LL1,LL) :- 鍵がLL1に存在する時は度数を更新する(_鍵ならび,LL1,LL),!. 鍵ごとに度数加算して行く(_鍵ならび,LL1,LL) :- 鍵がLL1に存在しない場合はその鍵は無視する(_鍵ならび,LL1,LL). 鍵がLL1に存在する時は度数を更新する([_鍵|R],LL1,LL) :- 度数の更新(_鍵,LL1,LL2), '鍵とselect/4を使った度数加算'(R,LL2,LL). 度数の更新(_鍵,LL1,LL2) :- select([_鍵,_度数_1],LL1,[_鍵,_度数_2],LL2), succ(_度数_1,_度数_2). 鍵がLL1に存在しない場合はその鍵は無視する([_|R],LL1,LL) :- '鍵とselect/4を使った度数加算'(R,LL1,LL). % 以下のサイトは # 出典 :: C/C++の宿題片付けます 152代目 #954 # [1] 授業単元:計算機アルゴリズム # [2] 問題文(含コード&リンク): # 設問1-1 # プログラム例7.2.1を、最小値の要素番号idx(x[idx]が最小値となるようなidx)を求めるように変更した後、 # その最小値x[idx]と先頭要素x[0]の2つの要素を入れ替え、配列の全要素を表示するようにしなさい。 # この実行の結果、x[0]はx[0],x[1],・・・,x[9]の最小値となります。 ならびの最小値要素を求め先頭要素と入れ替える([_先頭要素|R],[_最小値要素|L]) :- select(_最小値要素,[_先頭要素|R],_先頭要素,[A|L]), forall(member(_要素,[A|L]),_要素 >= _最小値要素). % 以下のサイトは # # ■Python # print map(lambda x: x*2, filter(lambda x: x>2 and x<5, [1,2,3,4,5])) # # ■Ruby # puts [1,2,3,4,5].select{|i| i > 2 and i < 5}.map{|i| i*2} # # ■C# # new{}{ 1,2,3,4,5 }.Where(x => 2 < x && x < 5).Select(x => x*2); # # ■Haskell # print [x*2| x <-[1,2,3,4,5], x > 2, x < 5] '集合[1,2,3,4,5]の2より大きく5より小さい要素を2倍したものの集合を表示する' :- findall(_2より大きく5より小さい要素を2倍したもの, '集合[1,2,3,4,5]の2より大きく5より小さい要素を2倍したもの'(_2より大きく5より小さい要素を2倍したもの),_2より大きく5より小さい要素を2倍したものの集合), '集合[1,2,3,4,5]の2より大きく5より小さい要素を2倍したものの集合を表示する'(_2より大きく5より小さい要素を2倍したものの集合). '集合[1,2,3,4,5]の2より大きく5より小さい要素を2倍したもの'(_2より大きく5より小さい要素を2倍したもの) :- '集合[1,2,3,4,5]の'(_2より大きく5より小さい要素), 2より大きく5より小さい要素を2倍したもの'(_2より大きく5より小さい要素,_2より大きく5より小さい要素を2倍したもの). '集合[1,2,3,4,5]の'(_2より大きく5より小さい要素) :- member(_2より大きく5より小さい要素,[1,2,3,4,5]). '2より大きく5より小さい要素を2倍したもの'(_2より大きく5より小さい要素,_2より大きく5より小さい要素を2倍したもの) :- '2より大きく5より小さい'(_2より大きく5より小さい要素), _2より大きく5より小さい要素を2倍したもの is _2より大きく5より小さい要素 * 2. '2より大きく5より小さい'(_2より大きく5より小さい要素) :- _2より大きく5より小さい要素 > 2, _2より大きく5より小さい要素 < 5. '集合[1,2,3,4,5]の2より大きく5より小さい要素を2倍したものの集合を表示する'(_2より大きく5より小さい要素を2倍したものの集合) :- writef('%w\n',[_2より大きく5より小さい要素を2倍したものの集合]). % 以下のサイトは # 出典 :: CodeIQ q1565 # 【問題】 # できるだけ多くの人数で、肩車をしようと思います。 #      # # 肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。 # # # 【例】 # 一行ごとに、身長と体重のセットが与えられます。次の例は、5人の身長と体重を表しています。 # 166 71 # 178 84 # 176 94 # 174 85 # 174 65 # # # この中から肩車をする人間を選ぶと、身長と体重が # (166, 71) # (174, 85) # (176, 94) # の3人が最大人数になります。 # # ※身長と体重共に、上の人が下の人“より小さい”場合に肩車が許されるとしていますので、 #  (174, 85)の上に(174, 65)が乗ることはできません。 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。 【例】 一行ごとに、身長と体重のセットが与えられます。次の例は、5人の身長と体重を表しています。 166 71 178 84 176 94 174 85 174 65 この中から肩車をする人間を選ぶと、身長と体重が (166, 71) (174, 85) (176, 94) の3人が最大人数になります。 ※身長と体重共に、上の人が下の人“より小さい”場合に肩車が許されるとしていますので、  (174, 85)の上に(174, 65)が乗ることはできません。'(_最大人数) :- 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_最大人数). 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_最大人数) :- 身長と体重のセットを得る(_身長と体重のセット), 'できるだけ多くの人数で、肩車をしようと思います。'(_身長と体重のセット,_最大人数). 身長と体重のセットを得る(_身長と体重のセット) :- findall(_身長と体重ならび,( '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび)),_身長と体重のセット). '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび) :- readln(_身長と体重ならび_または空行), '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび_または空行,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだす(終了は空行)'([],_) :- !,fail. '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび_1,_身長と体重ならび) :- '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_身長と体重ならび_1,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_身長と体重ならび,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_,_身長と体重ならび) :- '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび). 'できるだけ多くの人数で、肩車をしようと思います。'(_人間ならび,_最大人数) :- findall(_肩車人数,( 肩車人数(_人間ならび,_肩車人数)),_肩車人数ならび), max_list(_肩車人数ならび,_最大人数). 肩車人数(_人間ならび,_肩車人数) :- select(_取りだされた人間,_人間ならび,_残りの人間ならび), 肩車を重ねる(_取りだされた人間,_残りの人間ならび,_肩車重ね), length(_肩車重ね,_肩車人数). 肩車を重ねる(_自分,_人間ならび,[_自分|_肩車重ね]) :- 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね). 肩車を重ねる(_一番上の人間,_,[_一番上の人間]). 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね) :- select(_上の人間,_人間ならび,_残りの人間ならび), '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_上の人間,_自分), 肩車を重ねる(_上の人間,_残りの人間ならび,_肩車重ね). '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'([_上の人間の身長,_上の人間の体重],[_自分の身長,_自分の体重]) :- _上の人間の身長 @< _自分の身長, _上の人間の体重 @< _自分の体重. % 以下のサイトは # 出典 :: 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). % 以下のサイトは '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). % 以下のサイトは 'select/4を使った標本値の出現度数加算'([],LL,LL). 'select/4を使った標本値の出現度数加算'(_標本値ならび,LL1,LL) :- 'select/4で鍵管理して標本値の出現度数を加算して行く'(_標本値ならび,LL1,LL). 'select/4で鍵管理して標本値の出現度数を加算して行く'([_標本値|R],LL1,LL) :- select([_標本値,_度数_1],LL1,[_標本値,_度数_2],LL2), succ(_度数_1,_度数_2), 'select/4を使った標本値の出現度数加算'(R,LL2,LL). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/tech/1390525149/282 # お題:1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。 # のこりの数からとりのぞいた2個の数を求める。 # 例 # 3,1,2,6 -> 4,5 # # '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。 のこりの数からとりのぞいた2個の数を求める。'(_n,_とりのぞいた数_1,_とりのぞいた数_2) :- '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。'(_n,_1からnのn個の連続した整数,_2個をとりのぞいたのこりの数), 'のこりの数からとりのぞいた2個の数を求める。'(_1からnのn個の連続した整数,_2個をとりのぞいたのこりの数,[_とりのぞいた数_1,_とりのぞいた数_2]). '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。'(_n,_1からnのn個の連続した整数,_2個をとりのぞいたのこりの数) :- '1からnのn個の連続した整数を'(_n,_1からnのn個の連続した整数), シャッフルして(_n,_1からnのn個の連続した整数,_シャッフルした1からnのn個の連続した整数), '適当に選んだ2個をとりのぞく。'(_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数). '1からnのn個の連続した整数を'(_n,_1からnのn個の連続した整数) :- findall(M,between(1,_n,M),_1からnのn個の連続した整数). シャッフルして(_n,L1,L2) :- シャッフルして(1000,_n,L1,L2),!. シャッフルして(0,_,L,L). シャッフルして(M,_n,L1,L) :- R is random(_n) + 1, select(R,L1,L2), M_1 is M - 1, シャッフルして(M_1,_n,[R|L2],L). '適当に選んだ2個をとりのぞく。'(_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数) :- _シャッフルした1からnのn個の連続した整数=[_,_|_2個をとりのぞいたのこりの数]. 'のこりの数からとりのぞいた2個の数を求める。'(_1からnのn個の連続した整数,_2個をとりのぞいたのこりの数,X) :- sort(_2個をとりのぞいたのこりの数,_整列した2個をとりのぞいたのこりの数), 欠番を2個求める(_1からnのn個の連続した整数,_整列した2個をとりのぞいたのこりの数,[],X). 欠番を2個求める(_,_,[X1,X2],[X1,X2]) :- !. 欠番を2個求める(L1,L2,Y,X) :- 欠番を2個見つけるまで探索する(L1,L2,Y,X). 欠番を2個見つけるまで探索する([A|R1],[A|R2],Y,X) :- 欠番を2個求める(R1,R2,Y,X). 欠番を2個見つけるまで探索する([A|R1],[B|R2],Y,X) :- A\==B, 欠番を2個求める(R1,[B|R2],[A|Y],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),_怒り指数 >= _最小の怒り指数). % 以下のサイトは '乱数によってズンかドコを表示して、その表示した文字列にズンズンズンズンドコという副文字列が現れたらキ・ヨ・シ!を表示して終了します。' :- 'ズンズンズンズンドコキ・ヨ・シ!'. 'ズンズンズンズンドコキ・ヨ・シ!' :- 'ズンズンズンズンドコキ・ヨ・シ!'(''),!. 'ズンズンズンズンドコキ・ヨ・シ!'(_文字列) :- 'ズンズンズンズンドコが現れたらキ・ヨ・シ!を表示して終了する'(_文字列). 'ズンズンズンズンドコキ・ヨ・シ!'(_文字列) :- ズンズンズンズンドコが現れるまでズンかドコを付加して行く(_文字列). 'ズンズンズンズンドコが現れたらキ・ヨ・シ!を表示して終了する'(_文字列) :- ズンズンズンズンドコが現れたら(_文字列), 'キ・ヨ・シ!を表示して終了する'. ズンズンズンズンドコが現れたら(_文字列) :- sub_atom(_文字列,_,_,0,ズンズンズンズンドコ). 'キ・ヨ・シ!を表示して終了する' :- format('~w\n',['キ・ヨ・シ!']). ズンズンズンズンドコが現れるまでズンかドコを付加して行く(_文字列) :- 乱数によってズンかドコを選択して表示し文字列の末尾に付加する(_文字列,_ズンかドコを付加された文字列), 'ズンズンズンズンドコキ・ヨ・シ!'(_ズンかドコを付加された文字列). 乱数によってズンかドコを選択して表示し文字列の末尾に付加する(_文字列,_ズンかドコを付加された文字列) :- 乱数によってズンかドコを選択して表示し(_ズンかドコ), 文字列の末尾に付加する(_文字列,_ズンかドコ,_ズンかドコを付加された文字列). 乱数によってズンかドコを選択して表示し(_ズンかドコ) :- 乱数によってズンかドコを選択して(_ズンかドコ), 表示し(_ズンかドコ). 乱数によってズンかドコを選択して(_ズンかドコ) :- random_select(_ズンかドコ,[ズン,ドコ],_). 表示し(_ズンかドコ) :- format('~w',[_ズンかドコ]). 文字列の末尾に付加する(_文字列,_ズンかドコ,_ズンかドコを付加された文字列) :- atom_concat(_文字列,_ズンかドコ,_ズンかドコを付加された文字列). % 以下のサイトは 'ズンズンズンズンドコキ・ヨ・シ!' :- 'ズンズンズンズンドコキ・ヨ・シ!'(''). 'ズンズンズンズンドコキ・ヨ・シ!'(_文字列) :- 末尾がズンズンズンズンドコになったらキヨシを付加して終了する(_文字列),!. 'ズンズンズンズンドコキ・ヨ・シ!'(_文字列) :- 末尾にズンズンズンズンドコが現れるまでズンかドコを付加して行く(_文字列). '末尾がズンズンズンズンドコになったらキ・ヨ・シ!を表示して終了する'(_文字列) :- 末尾がズンズンズンズンドコになったら(_文字列), 'キ・ヨ・シ!を表示して'(_文字列). 末尾がズンズンズンズンドコになったら(_文字列) :- sub_atom(_文字列,_,_,0,ズンズンズンズンドコ). 'キ・ヨ・シ!を表示して'(_文字列) :- write('キ・ヨ・シ!\n'). 末尾にズンズンズンズンドコが現れるまでズンかドコを付加して行く(_文字列) :- 乱数によってズンかドコを選択して文字列の末尾に付加する(_文字列,_ズンかドコを付加された文字列), 'ズンズンズンズンドコキ・ヨ・シ!'(_ズンかドコを付加された文字列). 乱数によってズンかドコを選択してそれを表示し文字列の末尾に付加する(_文字列,_ズンかドコを付加された文字列) :- 乱数によってズンかドコを選択してそれを表示し(_ズンかドコ), 文字列の末尾に付加する(_文字列,_ズンかドコを付加された文字列). 乱数によってズンかドコを選択してそれを表示し(_ズンかドコ) :- 乱数によってズンかドコを選択して(_ズンかドコ), それを表示し(_ズンかドコ). 乱数によってズンかドコを選択して(_ズンかドコ) :- random_select(_ズンかドコ,[ズン,ドコ],_). それを表示し(_ズンかドコ) :- wrtitef('%w\n',[_ズンかドコ]). 文字列の末尾に付加する(_文字列,_ズンかドコ,_ズンかドコを付加された文字列) :- atom_concat(_文字列,_ズンかドコ,_ズンかドコを付加された文字列). % 以下のサイトは 'ズンズンズンズンドコキ・ヨ・シ!'(_ズンズンズンズンドコキヨシ) :- 'ズンズンズンズンドコキ・ヨ・シ!'('',_ズンズンズンズンドコキヨシ),!. 'ズンズンズンズンドコキ・ヨ・シ!'(_文字列,_ズンズンズンズンドコキヨシ) :- '末尾がズンズンズンズンドコになったらキ・ヨ・シ!を付加して終了する'(_文字列,_ズンズンズンズンドコキヨシ). 'ズンズンズンズンドコキ・ヨ・シ!'(_文字列,_ズンズンズンズンドコキヨシ) :- 末尾にズンズンズンズンドコが現れるまでズンかドコを付加して行く(_文字列,_ズンズンズンズンドコキヨシ). '末尾がズンズンズンズンドコになったらキ・ヨ・シ!を付加して終了する'(_文字列,_ズンズンズンズンドコキヨシ) :- sub_atom(_文字列,_,_,0,ズンズンズンズンドコ), atom_concat(_文字列,'キ・ヨ・シ!',_ズンズンズンズンドコキヨシ). 末尾にズンズンズンズンドコが現れるまでズンかドコを付加して行く(_文字列,_ズンズンズンズンドコキヨシ) :- 乱数によってズンかドコを選択して文字列の末尾に付加する(_文字列,_ズンかドコを付加された文字列), 'ズンズンズンズンドコキ・ヨ・シ!'(_ズンかドコを付加された文字列,_ズンズンズンズンドコキヨシ). 乱数によってズンかドコを選択して文字列の末尾に付加する(_文字列,_ズンかドコを付加された文字列) :- random_select(_ズンかドコ,[ズン,ドコ],_), atom_concat(_文字列,_ズンかドコ,_ズンかドコを付加された文字列). % 以下のサイトは 小さい順に取り出す(L,X) :- 一番小さいもの(L,R,Y), 小さい順に取り出す(R,Y,X). 一番小さいもの(L,R,Y) :- select(Y,L,R), 'Rの中にYより小さいものはない'(R,Y),!. 'Rの中にYより小さいものはない'(R,Y) :- \+('Rの中にYより小さいものがある'(R,Y)). 'Rの中にYより小さいものがある'(R,Y) :- 'Rの中に'(R,_Rの要素), 'Yより小さいものがある'(_Rの要素,Y). 'Rの中に'(R,_Rの要素) :- member(_Rの要素,R). 'Yより小さいものがある'(_Rの要素,Y) :- _Rの要素 @< Y. 小さい順に取り出す(_,X,X). 小さい順に取り出す(R,_,X) :- 小さい順に取り出す(R,X). % 以下のサイトは % 非決定性 シャッフルして一枚取り出す/4 シャッフルして一枚取り出す(_札,_既に取り出した札,_取り出す札,_残り札) :- シャッフル(_札,_シャッフルした札), append(_既に取り出した札,[_取り出す札|_残り札],_シャッフルした札). % 決定性 シャッフル/2 シャッフル([],[]) :- !. シャッフル(L,[A|R2]) :- 位置を示す乱数を使い一個ずつ取り出して行くことによりシャッフルする(L,A,R2). 位置を示す乱数を使い一個ずつ取り出して行くことによりシャッフルする(L,A,R2) :- 位置を示す乱数を使い(L,_乱数), 一個ずつ取り出して行く(L,_乱数,A,R2). 位置を示す乱数を使い(L,_乱数) :- length(L,Len), _乱数 is random(Len). 一個ずつ取り出して行く(L,_乱数,A,R2) :- 取り出して行く(L,_乱数,A,R1), シャッフル(R1,R2). 取り出して行く(L,_乱数,A,R1) :- nth0(_乱数,L,A), select(A,L,R1). % 以下のサイトは # 出典 :: C/C++の宿題片付けます 134代目 #154 # [1] 授業単元: プログラミング演習 # [2] 問題文(含コード&リンク):http://ime.nu/www.acm-japan.org/past-icpc/domestic2008/problems/all_ja.html # 等しい合計点 # # 太郎と花子はそれぞれカードを何枚か持っている. # 各カードには点数が書かれている.太郎のカードと花子のカードを 1 枚ずつ交換して, # それぞれの持つカードの合計点数が等しくなるようにしたい. # どのカードとどのカードを交換したらよいか. # # ただし,カードを交換しなくても合計点数が等しい場合でも,必ずカードの交換を行うものとする. # Input # 入力は,いくつかのデータセットからなる.各データセットは次の形式で与えられ # # n m # s1 # s2 # ... # 各データセットの最初の行は空白ひとつで区切られたふたつの数 n と m を含み, # n は太郎のカードの枚数,m は花子のカードの枚数を表す.続く n+m 行には, # 各カードの点数が 1 行にひとつずつ並ぶ. # 最初の n 個の点数 (s1 から sn まで) は太郎のカードの点数, # 残りの m 個の点数 (sn+1 から sn+m まで) は花子のカードの点数を表す. # n および m は 100 以下の正の整数とし,カードの点数は 0 以上 100 以下の整数値とする. # # 入力の終わりは,空白ひとつで区切られたふたつの 0 を含む 1 行で示される. '太郎の手札と花子の手札を 1 枚ずつ交換して,それぞれの持つ手札の合計点数が等しくなるようにしたい' :- 太郎と花子の手札を読み込む(_太郎の手札ならび,_花子の手札ならび), '太郎の手札と花子の手札を 1 枚ずつ交換して,それぞれの持つ手札の合計点数が等しくする'(_太郎の手札ならび,_花子の手札ならび,_太郎の手札から抜いた手札,_花子の手札から抜いた手札). 太郎と花子の手札を読み込む(_太郎の手札ならび,_花子の手札ならび) :- '行を入力し、空白を区切りに太郎の手札の枚数と花子の手札の枚数を得る'(_太郎の手札の枚数,_花子の手札の枚数), '点数を入力し、太郎と花子に分配する'(_太郎の手札の枚数,_花子の手札の枚数,_太郎の手札ならび,_花子の手札ならび). '行を入力し、空白を区切りに太郎の手札の枚数と花子の手札の枚数を得る'(_太郎の手札の枚数,_花子の手札の枚数) :- 行を文字コードとして読み取る(_文字コードならび), '空白のコードを区切りに、文字コードならびを太郎の手札の枚数と花子の手札の枚数に変換する'(_文字コードならび,_太郎の手札の枚数,_花子の手札の枚数). '空白を区切りに太郎の手札の枚数と花子の手札の枚数を得る'(_太郎の手札の枚数,_花子の手札の枚数) :- 行を文字コードとして読み取る(_文字コードならび), '空白のコードを区切りに、文字コードならびを太郎の手札の枚数と花子の手札の枚数に変換する'(_文字コードならび,_太郎の手札の枚数,_花子の手札の枚数). 行を文字コードとして読み取る(_文字コード) :- get_line_to_codes(user_input,_文字コード). 整数を得る(_整数) :- 行を得る(_行), 行を整数に変換する(_行,_整数). 行を整数に変換する(_行,_整数) :- read_term_from_atom(_行,_整数,[]), integer(_整数). 行を得る(_行) :- get_line_to_codes(user_input,_文字コードならび), atom_codes(_行,文字コードならび). '空白のコードを区切りに、文字コードならびを太郎の手札の枚数と花子の手札の枚数に変換する'(_文字コードならび,_太郎の手札の枚数,_花子の手札の枚数) :- '空白のコードを区切りに、'(_文字コードならび,L1,L2), '文字コードならびを太郎の手札の枚数と花子の手札の枚数に変換する'(L1,L2,_太郎の手札の枚数,_花子の手札の枚数). '空白のコードを区切りに、'(_文字コードならび,L1,L2) :- append(L1,[32|L2],_文字コードならび). '文字コードならびを太郎の手札の枚数と花子の手札の枚数に変換する'(L1,L2,_太郎の手札の枚数,_花子の手札の枚数) :- number_codes(_太郎の手札の枚数,L1), number_codes(_花子の手札の枚数,L2). '点数を入力し、太郎と花子に分配する'(_太郎の手札の枚数,_花子の手札の枚数,_太郎の手札,_花子の手札) :- 太郎と花子の手札を読み込む(_太郎の手札の枚数,_花子の手札の枚数,_太郎の手札,_花子の手札). 太郎と花子の手札を読み込む(_太郎の手札の枚数,_花子の手札の枚数,_太郎の手札,_花子の手札) :- 太郎の手札を読み込む(_太郎の手札の枚数,_太郎の手札), 花子の手札を読み込む(_花子の手札の枚数,_花子の手札),!. 太郎の手札を読み込む(_太郎の手札の枚数,_太郎の手札) :- findnsols(_整数,_太郎の手札の枚数,( 連続して整数を読み込む(_整数)),_太郎の手札). 花子の手札を読み込む(_花子の手札の枚数,_花子の手札) :- findnsols(_整数,_花子の手札の枚数,( 連続して整数を読み込む(_整数)),_花子の手札). 連続して整数を読み込む(_整数) :- repeat, 整数を得る(_整数). '太郎の手札と花子の手札を 1 枚ずつ交換して,それぞれの持つ手札の合計点数が等しくする'(_太郎の手札,_差し替える太郎の手札,_花子の手札,_差し替える花子の手札,_等しい合計) :- '太郎の手札と花子の手札を 1 枚ずつ交換して'(_太郎の手札,_花子の手札,_差し替える太郎の手札,_差し替える花子の手札,_差し替えた太郎の手札,_差し替えた花子の手札), 合計点数が等しい(_差し替えた太郎の手札,_差し替えた花子の手札,_等しい合計). '太郎の手札と花子の手札を 1 枚ずつ交換して'(_太郎の手札,_花子の手札,_太郎の手札から抜いた手札,_花子の手札から抜いた手札,_差し替えた太郎の手札,_差し替えた花子の手札) :- select(_太郎の手札から抜いた手札,_太郎の手札ならび,_花子の手札から抜いた手札,_差し替えた太郎の手札ならび), select(_花子の手札から抜いた手札,_花子の手札,_太郎の手札から抜いた手札,_差し替えた花子の手札). 合計点数が等しい(_差し替えた太郎の手札,_差し替えた花子の手札,_等しい合計) :- sum_list(_差し替えた太郎の手札,_等しい合計), sum_list(_差し替えた花子の手札,_等しい合計). % 以下のサイトは 大きい順に取り出す(_ならび,_取り出すもの) :- 一番大きいもの(_ならび,_一番大きいもの,_残りならび), 大きい順に取り出す(_一番大きいもの,_残りならび,_取り出すもの). 一番大きいもの(_ならび,_一番大きいもの,_残りならび) :- select(_一番大きいもの,_ならび,_残りならび), 全ての残りならびの中のものは一番大きいものと等しいか小さい(_一番大きいもの,_残りならび),!. 全ての残りならびの中のものは一番大きいものと等しいか小さい(_一番大きいもの,_残りならび) :- forall(全ての残りならびの中のものは(_残りならび,_残りならびの中のもの),一番大きいものと等しいか小さい(_残りならびの中のもの,_一番大きいもの)). 全ての残りならびの中のものは(_残りならび,_残りならびの中のもの) :- member(_残りならびの中のもの,_残りならび). 一番大きいものと等しいか小さい(_残りならびの中のもの,_一番大きいもの) :- _残りならびの中のもの @=< _一番大きいもの. 大きい順に取り出す(_取り出すもの,_,_取り出すもの). 大きい順に取り出す(_,_残りならび,_取り出すもの) :- 大きい順に取り出す(_残りならび,_取り出すもの). % 以下のサイトは '100000以下のどの桁にも0を含まない削除可能素数の度数'(_度数) :- 度数('100000以下のどの桁にも0を含まない削除可能素数'(_削除可能素数),_度数). '100000以下のどの桁にも0を含まない削除可能素数'(_削除可能素数) :- まず素数候補を100000以下に絞りましょう(_素数ならび), どの桁にも0を含まない削除可能素数を選別する(_素数ならび,_削除可能数). どの桁にも0を含まない削除可能素数を選別する(_素数ならび,_削除可能数) :- どの桁にも0を含まない削除可能素数の数字ならび(_素数ならび,_削除可能素数の数字ならび), 削除可能素数であるか検査して数値に戻す(_素数ならび,_削除可能素数の数字ならび,_削除可能素数). まず素数候補を100000以下に絞りましょう(_素数ならび) :- '2から100000までの数ならび'(_2から100000までの数ならび), エラトステネスの篩(_2から100000までの数ならび,_素数ならび). '2から100000までの数ならび'(_2から100000までの数ならび) :- findall(N,between(2,100000,N),_2から100000までの数ならび). どの桁にも0を含まない削除可能素数の数字ならび(_素数ならび,_削除可能素数の数字ならび) :- どの桁にも0を含まない削除可能素数候補を数字ならびで受け取る(_素数ならび,_削除可能素数の数字ならび). どの桁にも0を含まない削除可能素数候補を数字ならびで受け取る(_素数ならび,_削除可能素数の数字ならび) :- 素数をひとつ選択し削除可能素数の数字ならびに分解する(_素数ならび,_削除可能素数の数字ならび), どの桁にも0を含まない(_削除可能素数の数字ならび). 素数をひとつ選択し削除可能素数の数字ならびに分解する(_素数ならび,_削除可能素数の数字ならび) :- member(_素数,_素数ならび), number_chars(_素数,_削除可能素数の数字ならび). どの桁にも0を含まない(_削除可能素数の数字ならび) :- \+(member('0',_削除可能素数の数字ならび)). 削除可能素数であるか検査して数値に戻す(_素数ならび,_削除可能素数の数字ならび,_削除可能素数) :- once(削除可能素数であるか検査する(_素数ならび,_削除可能素数の数字ならび)), number_chars(_削除可能素数,_削除可能素数の数字ならび). 削除可能素数であるか検査する(_素数ならび,[]) :- !. 削除可能素数であるか検査する(_素数ならび,L) :- ひと桁ずつ減らしていってどれも素数である(_素数ならび,L). ひと桁ずつ減らしていってどれも素数である(_素数ならび,_素数を構成する数字ならび) :- 素数を構成する数字ならび(_素数ならび,_素数を構成する数字ならび), select(_,_素数を構成する数字ならび,R), 削除可能素数であるか検査する(_素数ならび,R). 素数を構成する数字ならび(_素数ならび,_素数を構成する数字ならび) :- number_chars(_素数,_素数を構成する数字ならび), 素数(_素数ならび,_素数). 素数(_素数ならび,_素数) :- member(_素数,_素数ならび). エラトステネスの篩([],[]) :- !. エラトステネスの篩([_確定した素数|R1],[_確定した素数|R2]) :- 'R1の中の_確定した素数で割り切れないものだけを残し篩に掛ける'(_確定した素数,R1,R2). 'R1の中の_確定した素数で割り切れないものだけを残し篩に掛ける'(_確定した素数,R1,R2) :- 'R1の中の_確定した素数で割り切れないものだけを残す'(_確定した素数,R1,_残ったならび), エラトステネスの篩(_残ったならび,R2). 'R1の中の_確定した素数で割り切れないものだけを残す'(_確定した素数,R1,_残ったならび) :- findall(_確定した素数で割り切れないもの,( 'R1の中で_確定した素数で割り切れないもの'(R1,_確定した素数,_確定した素数で割り切れないもの)),_残ったならび). 'R1の中で_確定した素数で割り切れないもの'(R1,_確定した素数,_確定した素数で割り切れないもの) :- member(_確定した素数で割り切れないもの,R1), \+(0 is _確定した素数で割り切れないもの mod _確定した素数). 度数(_目標,_度数) :- findall(1,_目標,L), length(L,_度数). % 以下のサイトは # 【 課題 】マス取りゲーム # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 期限 】11/27 24:00 # 【 Ver  】"1.7.0_45" # 【 補足 】3×3のマスに『○』と『×』を交互に入力して9マス埋まったら終了です。 # 勝ち負けはいりません 戦略なしマス取りゲーム(_手順) :- 戦略なしマス取りゲーム(○,[a1,a2,a3,b1,b2,b3,c1,c2,c3],_手順). 戦略なしマス取りゲーム(_手番,[],[]). 戦略なしマス取りゲーム(_手番,_残りマスならび,_手順) :- 空いたマスがあれば戦略なしマス取りゲームを続ける(_手番,_残りマスならび,_手順). 空いたマスがあれば戦略なしマス取りゲームを続ける(_手番,_残りマスならび,[[_手番,_マス]|_手順]) :- 空いたマスがあれば(_残りマスならび), 手番がマスをひとつ取る(_手番,_残りマスならび,_次の手番,_マス,_ひとつマスを取られた残りマスならび), 戦略なしマス取りゲーム(_次の手番,_ひとつマスを取られた残りマスならび,_手順). 空いたマスがあれば(_残りマスならび) :- \+(_残りマスならび = []). 手番がマスをひとつ取る(_手番,_残りマスならび,_次の手番,_マス,_ひとつマスを取られた残りマスならび) :- マスをひとつ取る(_残りマスならび,_マス), ひとつマスを取られた残りマスならび(_マス,_残りマスならび,_ひとつマスを取られた残りマスならび), 次の手番(_手番,_次の手番). マスをひとつ取る(_残りマスならび,_マス) :- length(_残りマスならび,_残りマス数), _乱順数 is random(_残りマス数), nth0(_乱順数,_残りマスならび,_マス). ひとつマスを取られた残りマスならび(_マス,_残りマスならび,_ひとつマスを取られた残りマスならび) :- select(_マス,_残りマスならび,_ひとつマスを取られた残りマスならび). 次の手番(○,×). 次の手番(×,○). % 以下のサイトは 切ったトランプを用意する(_切ったトランプ) :- '52枚の整列したカード'(_52枚の整列したカード), シャッフル(_52枚の整列したカード,_切ったトランプ). '52枚の整列したカード'(_52枚の整列したカード) :- findall([_数,_スート], 'カードを数・スート順に生成する'(_数,_スート),_52枚の整列したカード). 'カードを数・スート順に生成する'(_数,_スート) :- between(1,13,_数), member(_スート,[スペード,ハート,ダイヤ,クラブ]). シャッフル([],[]) :- !. シャッフル(L,[A|R2]) :- 位置を示す乱数を使い一枚ずつ取り出して行くことによりシャッフルする(L,A,R2). 位置を示す乱数を使い一枚ずつ取り出して行くことによりシャッフルする(L,A,R2) :- 位置を示す乱数を使い一枚ずつ取り出して行く(L,A,R2), select(A,L,R1), シャッフル(R1,R2). 位置を示す乱数を使い一枚ずつ取り出して行く(L1,A,R2):- length(L1,Len), _乱数 is random(Len), nth0(_乱数,L1,A). % 以下のサイトは # お題: # 例:数列[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). % 以下のサイトは # 出典 :: SQL質疑応答スレ 13問目 # SQLに関して質問です。MySQL5.1.41です。 # # 【チームテーブル(team)】 # -------------------- # チームID  チーム名 # -------------------- # 1      巨人 # 2      阪神 # 3      中日 # # 【選手テーブル(player)】 # -------------------------------------- # 選手ID  チームID  選手名  背番号 # -------------------------------------- # 1     1      阿部   10 # 2     1      杉内   18 # 3     2      金本   6 # 4     2      鳥谷   1 # 5     3      岩瀬   13 # 6     3      谷繁   27 # # この条件で、各チームから背番号最少の選手を抽出するのが目的です。 # 結果イメージは、 # # ---------------------------- # チーム名  選手名  背番号 # ---------------------------- # 巨人    阿部    10 # 阪神    鳥谷    1 # 中日    岩瀬    13 # # です。SQLで # SELECT チーム名, 選手名, 背番号 FROM team LEFT JOIN player USING (チームID) WHERE MIN(背番号); # ではエラーになってしまいました。 # # ご教示宜しくお願いいたします。 # # チーム(1,巨人). チーム(2,阪神). チーム(3,中日). 選手(1,1,阿部,10). 選手(2,1,杉内,18). 選手(3,2,金本,6). 選手(4,2,鳥谷,1). 選手(5,3,岩瀬,13). 選手(6,3,谷繁,27). 各チームから背番号最少の選手を抽出する(_チーム,_選手名,_チーム最小背番号) :- チーム(_チームID,_チーム), 背番号最少の選手を抽出する(_チームID,_選手名,_チーム最小背番号). 背番号最少の選手を抽出する(_チームID,_選手名,_チーム最小背番号) :- 選手を抽出する(_チームID,_選手名,_チーム最小背番号,_残りならび), 背番号最少の(_残りならび,_チーム最小背番号). 選手を抽出する(_チームID,_選手名,_チーム最小背番号,_残りならび) :- findall([_背番号,_選手名],選手(_,_チームID,_選手名,_背番号),_背番号_選手名ならび), select([_チーム最小背番号,_選手名],_背番号_選手名ならび,_残りならび). 背番号最少の(_残りならび,_チーム最小背番号) :- forall(member([_背番号,_],_残りならび),_背番号 @>= _チーム最小背番号). % 以下のサイトは 軸要素の選定([_最初の位置の値|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). % 以下のサイトは 軸要素の選定(_対象ならび,_軸要素) :- '最初の位置の値、中間位置の値、最終位置の値、三値の中央値を取る'(_対象ならび,_軸要素),!. '最初の位置の値、中間位置の値、最終位置の値、三値の中央値を取る'([_最初の位置の値|R],_軸要素) :- 中間位置の値([_最初の位置の値|R],_中間位置の値), last([_最初の位置の値|R],_最終位置の値), 三値の中央値(_最初の位置の値,_中間位置の値,_最終位置の値,_軸要素). 中間位置の値(_値ならび,_中間位置の値) :- '_前ならびを作り'(_値ならび,_前ならび), append(_前ならび,[_中間位置の値|_],_値ならび),!. '_前ならびを作り'(_値ならび,_前ならび) :- length(_値ならび,_ならびの要素数), _前ならびの要素数 is _ならびの要素数 // 2, length(_前ならび,_前ならびの要素数). 三値の中央値(_1,_2,_3,_三値の中央値) :- select(_三値の中央値,[_1,_2,_3],_残り値ならび), '残り値ならびの値の全てが三値の中央値より小さいことはなく、残り値ならびの値の全てが三値の中央値より大きいこともない'(_残り値ならび,_三値の中央値),!. '残り値ならびの値の全てが三値の中央値より小さいことはなく、残り値ならびの値の全てが三値の中央値より大きいこともない'(_残り値ならび,_三値の中央値) :- 残り値ならびの値の全てが三値の中央値より小さいことはなく(_残り値ならび,_三値の中央値), 残り値ならびの値の全てが三値の中央値より大きいこともない(_残り値ならび,_三値の中央値). 残り値ならびの値の全てが三値の中央値より小さいことはなく(_残り値ならび,_三値の中央値) :- \+(残り値ならびの値の全てが三値の中央値より小さい(_残り値ならび,_三値の中央値)). 残り値ならびの値の全てが三値の中央値より小さい(_残り値ならび,_三値の中央値) :- forall(member(_値,_残り値ならび),_値 @< _三値の中央値)). 残り値ならびの値の全てが三値の中央値より大きいこともない(_残り値ならび,_三値の中央値) :- \+(残り値ならびの値の全てが三値の中央値より大きい(_残り値ならび,_三値の中央値)). 残り値ならびの値の全てが三値の中央値より大きい(_残り値ならび,_三値の中央値) :- forall(member(_値,_残り値ならび),_値 @> _三値の中央値)). % 以下のサイトは 軸要素の選定(_対象ならび,_軸要素) :- '最初の位置の値、中間位置の値、最終位置の値、三値の中央値を取る'(_対象ならび,_軸要素),!. '最初の位置の値、中間位置の値、最終位置の値、三値の中央値を取る'([_最初の位置の値|R],_軸要素) :- 中間位置の値([_最初の位置の値|R],_中間位置の値), last([_最初の位置の値|R],_最終位置の値), 三値の中央値(_最初の位置の値,_中間位置の値,_最終位置の値,_軸要素). 中間位置の値(_値ならび,_中間位置の値) :- '_前ならびを作り'(_値ならび,_前ならび), append(_前ならび,[_中間位置の値|_],_値ならび),!. '_前ならびを作り'(_値ならび,_前ならび) :- length(_値ならび,_ならびの要素数), _前ならびの要素数 is _ならびの要素数 // 2, length(_前ならび,_前ならびの要素数). 三値の中央値(_1,_2,_3,_三値の中央値) :- select(_三値の中央値,[_1,_2,_3],_残り値ならび), '残り値ならびの値の全てが中央値より小さいことはなく、残り値ならびの値の全てが中央値より大きいこともない'(_残り値ならび,_三値の中央値),!. '残り値ならびの値の全てが中央値より小さいことはなく、残り値ならびの値の全てが中央値より大きいこともない'(_残り値ならび,_三値の中央値) :- 残り値ならびの値の全てが中央値より小さいことはなく(_残り値ならび,_三値の中央値), 残り値ならびの値の全てが中央値より大きいこともない(_残り値ならび,_三値の中央値). 残り値ならびの値の全てが中央値より小さいことはなく(_残り値ならび,_三値の中央値) :- \+(forall(member(A,_残り値ならび),A @< _三値の中央値)). 残り値ならびの値の全てが中央値より大きいこともない(_残り値ならび,_三値の中央値) :- \+(forall(member(A,_残り値ならび),A @> _三値の中央値)). % 以下のサイトは 小さい順に取り出す(L,X) :- 一番小さいもの(L,R,Y), 小さい順に取り出す(R,Y,X). 一番小さいもの(L,R,Y) :- select(Y,L,R), 'Rの中にYより小さいものはない'(R,Y),!. 'Rの中にYより小さいものはない'(R,Y) :- forall(member(Z,R),\+(Z @< Y)). 小さい順に取り出す(_,X,X). 小さい順に取り出す(R,_,X) :- 小さい順に取り出す(R,X). % 以下のサイトは 小さい順に取り出す(_ならび,_取り出すもの) :- 一番小さいもの(_ならび,_一番小さいもの,_残りならび), 小さい順に取り出す(_一番小さいもの,_残りならび,_取り出すもの). 一番小さいもの(_ならび,_一番小さいもの,_残りならび) :- select(_一番小さいもの,_ならび,_残りならび), 全ての残りならびの中のものは一番小さいものと等しいか大きい(_一番小さいもの,_残りならび),!. 全ての残りならびの中のものは一番小さいものと等しいか大きい(_一番小さいもの,_残りならび) :- forall(member(_残りならびの中のもの,_残りならび),_残りならびの中のもの @>= _一番小さいもの). 小さい順に取り出す(_取り出すもの,_,_取り出すもの). 小さい順に取り出す(_,_残りならび,_取り出すもの) :- 小さい順に取り出す(_残りならび,_取り出すもの). % 以下のサイトは # 出典 :: 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). % 以下のサイトは # 出典 :: 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,_同じ数字が使われない並び) すべて 表示させる(_同じ数字が使われない並び). 同じ数字が使われない並びの通りを(_,0,[]). 同じ数字が使われない並びの通りを(L1,N,[_数字|L2]) :- select(_数字,L1,R), succ(M,N), 同じ数字が使われない並びの通りを(R,M,L2). 表示させる(_同じ数字が使われない並び) :- atomic_list_concat(_同じ数字が使われない並び,' ',_表示文字列), writef('%w\n',[_表示文字列]). P すべて Q :- forall(P,Q). % 以下のサイトは # 出典:: 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',[_表示文字列]). % 以下のサイトは 最長しりとりならび(_語彙ならび,_最長しりとりならび) :- 全しりとりならびを得てその中から最長しりとりを得る(_語彙ならび,_最長しりとりならび). 全しりとりならびを得てその中から最長しりとりを得る(_語彙ならび,_最長しりとりならび) :- 全しりとりならびを得て(_語彙ならび,_全しりとりならび), その中から最長しりとりならびを得る(_全しりとりならび,_最長しりとりならび). 全しりとりならびを得て(_語彙ならび,_全しりとりならび) :- findall(_しりとりならび,( select(_語彙,_語彙ならび,_残り語彙ならび), しりとり(_語彙,_残り語彙ならび,_しりとりならび)),_全しりとりならび). その中から最長しりとりならびを得る(_全しりとりならび,_最長しりとりならび) :- 最長しりとり要素数を得る(_全しりとりならび,_最長しりとり要素数), 最長しりとりならびは(_最長しりとり要素数,_全しりとりならび,_最長しりとりならび). 最長しりとり要素数を得る(_全しりとりならび,_最長しりとり要素数) :- findmax(_要素数,( member(_しりとりならび,_全しりとりならび), length(_しりとりならび,_要素数)),_最長しりとり要素数). 最長しりとりならびは(_最長しりとり要素数,_全しりとりならび,_最長しりとりならび) :- member(_最長しりとりならび,_全しりとりならび), length(_最長しりとりならび,_最長しりとり要素数). しりとり(_前の語彙,_語彙ならび,_しりとりならび) :- 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびになければしりとりを終了する(_前の語彙,_語彙ならび,_しりとりならび). しりとり(_前の語彙,_語彙ならび,_しりとりならび) :- 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびにあればしりとりを続ける(_前の語彙,_語彙ならび,_しりとりならび). 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびになければしりとりを終了する(_前の語彙,_語彙ならび,[_前の語彙]) :- 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字), 語彙が語彙ならびになければ(_語彙の先頭文字,_語彙ならび). 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字) :- sub_atom(_前の語彙,_,1,0,_語彙の先頭文字). 語彙が語彙ならびになければ(_語彙の先頭文字,_語彙ならび) :- forall(select(_語彙,_語彙ならび,_),\+(sub_atom(_語彙,0,1,_,_語彙の先頭文字))). 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびにあればしりとりを続ける(_前の語彙,_語彙ならび,[_前の語彙|R]) :- 前の語彙の末尾文字を先頭文字とする語彙を得る(_前の語彙,_語彙ならび,_語彙,_残り語彙ならび), しりとり(_語彙,_残り語彙ならび,R). 前の語彙の末尾文字を先頭文字とする語彙を得る(_前の語彙,_語彙ならび,_語彙,_残り語彙ならび) :- 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字), 語彙を得る(_語彙の先頭文字,_語彙ならび,_語彙,_残り語彙ならび). 語彙を得る(_語彙の先頭文字,_語彙ならび,_語彙,_残り語彙ならび) :- select(_語彙,_語彙ならび,_残り語彙ならび), sub_atom(_語彙,0,1,_,_語彙の先頭文字). findmax(A,B,Max) :- findall(A,B,L), max_list(L,Max). % 以下のサイトは しりとり(_前の語彙,_語彙ならび,_しりとりならび) :- 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびになければしりとりを終了する(_前の語彙,_語彙ならび,_しりとりならび). しりとり(_前の語彙,_語彙ならび,_しりとりならび) :- 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびにあればしりとりを続ける(_前の語彙,_語彙ならび,_しりとりならび). 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびになければしりとりを終了する(_前の語彙,_語彙ならび,[]) :- 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字), 語彙が語彙ならびになければ(_語彙の先頭文字,_語彙ならび). 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字) :- atom_chars(_前の語彙,Chars), last(Chars,_語彙の先頭文字). 語彙が語彙ならびになければ(_語彙の先頭文字,_語彙ならび) :- forall(select(_語彙,_語彙ならび,_),\+(atom_chars(_語彙,[_語彙の先頭文字|_]))). 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびにあればしりとりを続ける(_前の語彙,_語彙ならび,[_語彙|R]) :- 前の語彙の末尾文字を先頭文字とする語彙を得る(_前の語彙,_語彙ならび,_語彙,_残り語彙ならび), しりとり(_語彙,_残り語彙ならび,R). 前の語彙の末尾文字を先頭文字とする語彙を得る(_前の語彙,_語彙ならび,_語彙,_残り語彙ならび) :- 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字), 語彙を得る(_語彙の先頭文字,_語彙ならび,_語彙,_残り語彙ならび). 語彙を得る(_語彙の先頭文字,_語彙ならび,_語彙,_残り語彙ならび) :- select(_語彙,_語彙ならび,_残り語彙ならび), atom_chars(_語彙,[_語彙の先頭文字|_]). % 以下のサイトは しりとり(_前の語彙,_語彙ならび,_しりとりならび) :- 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびにあればしりとりを続ける(_前の語彙,_語彙ならび,_しりとりならび). しりとり(_,_,[]). 前の語彙の末尾文字を先頭文字とする語彙が語彙ならびにあればしりとりを続ける(_前の語彙,_語彙ならび,[_語彙|R]) :- 前の語彙の末尾文字を先頭文字とする語彙を得る(_前の語彙,_語彙ならび,_語彙,_残り語彙ならび), しりとり(_語彙,_残り語彙ならび,R). 前の語彙の末尾文字を先頭文字とする語彙を得る(_前の語彙,_語彙ならび,_語彙,_残り語彙ならび) :- 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字), 語彙を得る(_語彙の先頭文字,_語彙ならび,_語彙,_残り語彙ならび). 前の語彙の末尾文字を先頭文字とする(_前の語彙,_語彙の先頭文字) :- atom_chars(_前の語彙,Chars), last(Chars,_語彙の先頭文字). 語彙を得る(_語彙の先頭文字,_語彙ならび,_語彙,_残り語彙ならび) :- select(_語彙,_語彙ならび,_残り語彙ならび), atom_chars(_語彙,[_語彙の先頭文字|_]). % 以下のサイトは 'コールユーブンゲン 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,_度数). % 以下のサイトは シャッフル([],[]) :- !. シャッフル(L,[A|R2]) :- 位置を示す乱数を使い一個ずつ取り出して行くことによりシャッフルする(L,A,R2). 位置を示す乱数を使い一個ずつ取り出して行くことによりシャッフルする(L,A,R2) :- 位置を示す乱数を使い一個ずつ取り出して行く(L,A,R2), select(A,L,R1), シャッフル(R1,R2). 位置を示す乱数を使い一個ずつ取り出して行く(L1,A,R2) :- length(L1,Len), _乱数 is random(Len), nth0(_乱数,L1,A). % 以下のサイトは シャッフル(L1,L2) :- length(L1,Len), findall(N,between(1,Len,N),L), シャッフル(Len,L,L1,L2). シャッフル(0,_,_,[]) :- !. シャッフル(Len,L,L1,[_値|R]) :- 'L1からランダムに取り出して新たなリストを構成する'(Len,L,L1,_値,R). 'L1からランダムに取り出して新たなリストを構成する'(Len,L,L1,_値,R) :- 得られた乱数の位置にあるL1の値を取り出す(Len,L,L1,L_1,_値), succ(Len_1,Len), シャッフル(Len_1,L_1,L1,R). 得られた乱数の位置にあるL1の値を取り出す(Len,L,L1,L_1,_値) :- 得られた乱数の位置にある(Len,L,M), 'L1の値を取り出す'(L,L1,M,L_1,_値). 得られた乱数の位置にある(Len,L,M) :- N is random(Len) + 1, nth1(N,L,M). 'L1の値を取り出す'(L,L1,M,L_1,_値) :- nth1(M,L1,_値), select(M,L,L_1). % 以下のサイトは # 出典 :: CodeIQ q1565 # 【問題】 # できるだけ多くの人数で、肩車をしようと思います。 #      # # 肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。 # # # 【例】 # 一行ごとに、身長と体重のセットが与えられます。次の例は、5人の身長と体重を表しています。 # 166 71 # 178 84 # 176 94 # 174 85 # 174 65 # # # この中から肩車をする人間を選ぶと、身長と体重が # (166, 71) # (174, 85) # (176, 94) # の3人が最大人数になります。 # # ※身長と体重共に、上の人が下の人“より小さい”場合に肩車が許されるとしていますので、 #  (174, 85)の上に(174, 65)が乗ることはできません。 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。 【例】 一行ごとに、身長と体重のセットが与えられます。次の例は、5人の身長と体重を表しています。 166 71 178 84 176 94 174 85 174 65 この中から肩車をする人間を選ぶと、身長と体重が (166, 71) (174, 85) (176, 94) の3人が最大人数になります。 ※身長と体重共に、上の人が下の人“より小さい”場合に肩車が許されるとしていますので、  (174, 85)の上に(174, 65)が乗ることはできません。'(_最大人数) :- 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_最大人数). 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_最大人数) :- 身長と体重のセットを得る(_身長と体重のセット), 'できるだけ多くの人数で、肩車をしようと思います。'(_身長と体重のセット,_最大人数). 身長と体重のセットを得る(_身長と体重のセット) :- findall(_身長と体重ならび,( '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび)),_身長と体重のセット). '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび) :- readln(_身長と体重ならび_または空行), '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび_または空行,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだす(終了は空行)'([],_) :- !,fail. '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび_1,_身長と体重ならび) :- '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_身長と体重ならび_1,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_身長と体重ならび,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_,_身長と体重ならび) :- '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび). 'できるだけ多くの人数で、肩車をしようと思います。'(_人間ならび,_最大人数) :- findall(_肩車人数,( 肩車人数(_人間ならび,_肩車人数)),_肩車人数ならび), max_list(_肩車人数ならび,_最大人数). 肩車人数(_人間ならび,_肩車人数) :- select(_取りだされた人間,_人間ならび,_残りの人間ならび), 肩車を重ねる(_取りだされた人間,_残りの人間ならび,_肩車重ね), length(_肩車重ね,_肩車人数). 肩車を重ねる(_自分,_人間ならび,[_自分|_肩車重ね]) :- 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね). 肩車を重ねる(_一番上の人間,_,[_一番上の人間]). 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね) :- select(_上の人間,_人間ならび,_残りの人間ならび), '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_上の人間,_自分), 肩車を重ねる(_上の人間,_残りの人間ならび,_肩車重ね). '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'([_上の人間の身長,_上の人間の体重],[_自分の身長,_自分の体重]) :- _上の人間の身長 @< _自分の身長, _上の人間の体重 @< _自分の体重. % 以下のサイトは # 出典 :: CodeIQ q1565 # 【問題】 # できるだけ多くの人数で、肩車をしようと思います。 #      # # 肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。 # # # 【例】 # 一行ごとに、身長と体重のセットが与えられます。次の例は、5人の身長と体重を表しています。 # 166 71 # 178 84 # 176 94 # 174 85 # 174 65 # # # この中から肩車をする人間を選ぶと、身長と体重が # (166, 71) # (174, 85) # (176, 94) # の3人が最大人数になります。 # # ※身長と体重共に、上の人が下の人“より小さい”場合に肩車が許されるとしていますので、 #  (174, 85)の上に(174, 65)が乗ることはできません。 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。 【例】 一行ごとに、身長と体重のセットが与えられます。次の例は、5人の身長と体重を表しています。 166 71 178 84 176 94 174 85 174 65 この中から肩車をする人間を選ぶと、身長と体重が (166, 71) (174, 85) (176, 94) の3人が最大人数になります。 ※身長と体重共に、上の人が下の人“より小さい”場合に肩車が許されるとしていますので、  (174, 85)の上に(174, 65)が乗ることはできません。'(_最大人数) :- 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_最大人数). 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_最大人数) :- 身長と体重のセットを得る(_身長と体重のセット), 'できるだけ多くの人数で、肩車をしようと思います。'(_身長と体重のセット,_最大人数). 身長と体重のセットを得る(_身長と体重のセット) :- findall(_身長と体重ならび,( '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび)),_身長と体重のセット). '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび) :- readln(_身長と体重ならび_または空行), '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび_または空行,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだす(終了は空行)'([],_) :- !,fail. '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび_1,_身長と体重ならび) :- '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_身長と体重ならび_1,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_身長と体重ならび,_身長と体重ならび). '入力行から身長と体重を空白区切りで読みだして行く(終了は空行)'(_,_身長と体重ならび) :- '入力行から身長と体重を空白区切りで読みだす(終了は空行)'(_身長と体重ならび). 'できるだけ多くの人数で、肩車をしようと思います。'(_人間ならび,_最大人数) :- findall(_肩車人数,( 肩車人数(_人間ならび,_肩車人数)),_肩車人数ならび), max_list(_肩車人数ならび,_最大人数). 肩車人数(_人間ならび,_肩車人数) :- select(_取りだされた人間,_人間ならび,_残りの人間ならび), 肩車を重ねる(_取りだされた人間,_残りの人間ならび,_肩車重ね), length(_肩車重ね,_肩車人数). 肩車を重ねる(_自分,_人間ならび,[_自分|_肩車重ね]) :- 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね). 肩車を重ねる(_一番上の人間,_,[_一番上の人間]). 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね) :- select(_上の人間,_人間ならび,_残りの人間ならび), '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_上の人間,_自分), 肩車を重ねる(_上の人間,_残りの人間ならび,_肩車重ね). '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'([_上の人間の身長,_上の人間の体重],[_自分の身長,_自分の体重]) :- _上の人間の身長 @< _自分の身長, _上の人間の体重 @< _自分の体重. % 以下のサイトは ワンペア(_手札,_ペア数字,_残りの手札) :- 'ワンペアとは、手札に二枚の同位な数字があり、かつ、ツーペア、スリーカード、フォーカード、フルハウスの可能性がないものである。'(_手札,_ペア数字,_残りの手札). 'ワンペアとは、手札に二枚の同位な数字があり、かつ、ツーペア、スリーカード、フォーカード、フルハウスの可能性がないものである。'(_手札,_ペア数字,_残りの手札) :- 手札に二枚の同位な数字があり(_手札,_ペア数字,_ペア数字,_残りの手札), 'ツーペア、スリーカード、フォーカード、フルハウスの可能性がない'(_ペア数字,_残りの手札). 手札に二枚の同位な数字があり(_手札,_数字,_数字,_残りの手札) :- 二枚の札を選択(_手札,(_数字,_),(_数字,_),_残りの手札). 二枚の札を選択(_手札,(_数字_1,_スート_1),(_数字_2,_スート_2),_残りの手札) :- select((_数字_1,_スート_1),_手札,_残りの手札_1), select((_数字_2,_スート_2),_残りの手札_1,_残りの手札). 'ツーペア、スリーカード、フォーカード、フルハウスの可能性がない'(_ペア数字,_残りの手札) :- 'スリーカード、フォーカードの可能性がない'(_ペア数字,_残りの手札), 'ツーペア、フルハウスの可能性がない'(_ペア数字,_残りの手札). 'スリーカード、フォーカードの可能性がない'(_ペア数字,_残りの手札) :- ペア数字は残りの手札の中にはない(_ペア数字,_残りの手札). ペア数字は残りの手札の中にはない(_ペア数字,_残りの手札) :- \+(member((_ペア数字,_),_残りの手札)). 'ツーペア、フルハウスの可能性がない'(_ペア数字,_残りの手札) :- ペア数字は残りの手札の中にはない(_ペア数字,_残りの手札), 残りの手札の中に同位数字がない(_残りの手札). 残りの手札の中に同位数字がない(_残りの手札) :- \+(同位数字がある(_残りの手札)). 同位数字がある(_残りの手札) :- select((_同位数字,_),_残りの手札,_残りの手札_1), select((_同位数字,_),_残りの手札_1,_). % 以下のサイトは # # 横書文書を縦書文書に変形する # # 事例として、あぜといへかの万葉仮名表記部分の生成 # :- op(700,xfx,は). 横書文書を縦書文書に変形する(_横書文書,_縦書文書) :- 横書文書を縦書文書に変形する(_横書文書,0,_縦書文書). 横書文書を縦書文書に変形する(_横書文書,_列間隔文字数,_縦書文書) :- 改行を区切りに行ならびに変形する(_横書文書,_行ならび), 行ならびを縦書文書に変形する(_行ならび,_列間隔文字数,_縦書文書). 行ならびを縦書文書に変形する(_行ならび,_列間隔文字数,_縦書文書) :- 最大文字列長を調べその長さに揃えて文書を矩形にする(_行ならび,_矩形ならび), 行ならびを転置する(_矩形ならび,_転置した矩形ならび), 矩形ならびの各要素行の内容を反転して縦書文書にする(_転置した矩形ならび,_列間隔文字数,_縦書文書). 矩形ならびの各要素行の内容を反転して縦書文書にする(_転置した矩形ならび,_列間隔文字数,_縦書文書) :- 矩形ならびの各要素行の内容を反転する(_転置した矩形ならび,_要素が反転した転置した矩形ならび), 縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書). 改行を区切りに行ならびに変形する(_横書文書,[_前文字列|R]) :- 改行を区切りに(_横書文書,_前文字列,_後文字列), 改行を区切りに行ならびに変形する(_後文字列,R). 改行を区切りに行ならびに変形する(_文字列,R) :- 改行が存在しない場合停止する(_文字列,R). 改行が存在しない場合停止する('',[]) :- !. 改行が存在しない場合停止する(_文書,[_文書]). 改行を区切りに(_横書文書,_前文字列,_後文字列) :- 副文字列(_横書文書,_先頭からの変位,1,_末尾からの変位,'\n'), 副文字列(_横書文書,0,_先頭からの変位,_,_前文字列), 副文字列(_横書文書,_,_末尾からの変位,0,_後文字列),!. 最大文字列長を調べその長さに揃えて文書を矩形にする(_行ならび,_矩形ならび) :- 最大文字列長を調べ(_行ならび,_最大文字列長), その長さに揃えて文書を矩形にする(_行ならび,_最大文字列長,_矩形ならび). 最大文字列長を調べ(_行ならび,_最大文字列長) :- 解の最大値(_文字数,( 行ならびから行を取り出す(_行,_行ならび), 文字列長(_行,_文字数)),_最大文字列長). その長さに揃えて文書を矩形にする(_行ならび,_最大文字列長,_矩形ならび) :- 解を集める(_空白を付加した文字列,( 行ならびから行を取り出す(_行,_行ならび), 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_空白を付加した文字列)),_矩形ならび). 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_空白を付加した文字列) :- 文字列長(_行,_文字列長), 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_文字列長,_空白を付加した文字列). 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_文字列長,_空白を付加した文字列) :- 達しない文字数の空白(_最大文字列長,_文字列長,_空白文字列), 二つの文字列を結合する(_行,_空白文字列,_空白を付加した文字列). 達しない文字数の空白(_最大文字列長,_文字列長,_空白文字列) :- _最大文字列長と文字列長の差 は _最大文字列長 - _文字列長, 解を集める(' ',( 整数を順に生成する(1,_最大文字列長と文字列長の差,_)),_空白文字ならび), 文字ならびを文字列に変換する(_空白文字列,_空白文字ならび). 行ならびを転置する(_矩形ならび,_転置された矩形ならび) :- 矩形文字ならびに変換する(_矩形ならび,_矩形文字ならび), 転置(_矩形文字ならび,_転置された矩形文字ならび), 転置された矩形文字ならびを行ならびに変換(_転置された矩形文字ならび,_転置された矩形ならび). 矩形文字ならびに変換する(_矩形ならび,_矩形文字ならび) :- 解を集める(_文字ならび,( 矩形ならびから行を取り出す(_行,_矩形ならび), 文字列を文字ならびに変換する(_行,_文字ならび)),_矩形文字ならび). 転置された矩形文字ならびを行ならびに変換(_転置された矩形文字ならび,_転置された矩形ならび) :- 解を集める(_文字列,( 矩形文字ならびから文字ならびを取り出す(_文字ならび,_転置された矩形文字ならび), 文字ならびを文字列に変換する(_文字列,_文字ならび)),_転置された矩形ならび). 転置した矩形ならびの各行文字列を反転する(_転置した矩形ならび,_反転した行文字列) :- 要素の取り出し(_行文字列,_転置した矩形ならび), 文字列の反転(_行文字列,_反転した行文字列). 矩形ならびの各要素行の内容を反転する(_転置した矩形ならび,_要素が反転した転置した矩形ならび) :- 解を集める(_反転した行文字列,( 矩形ならびから行を取り出す(_行文字列,_転置した矩形ならび), 文字列の反転(_行文字列,_反転した行文字列)),_要素が反転した転置した矩形ならび). 縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書) :- 列間隔文字を挟んで縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書). 列間隔文字を挟んで縦書文書に変形する(_矩形ならび,_列間隔文字数,_縦書文書) :- 列間隔文字を挟んで(_矩形ならび,_列間隔文字数,_矩形ならび_1), 縦書文書に変形する(_矩形ならび_1,_縦書文書). 列間隔文字を挟んで(_矩形ならび_1,_列間隔文字数,_矩形ならび_2) :- 列間隔文字(_列間隔文字数,_列間隔文字), 解を集める(_行,( 行文字の間に列間隔文字を挿入する(_矩形ならび_1,_列間隔文字,_行)),_矩形ならび_2). 列間隔文字(_列間隔文字数,_列間隔文字) :- 解を集める(' ',( 整数を順に生成する(1,_列間隔文字数,_)),_列間隔文字ならび), 文字列を結合する(_列間隔文字ならび,_列間隔文字). 行文字の間に列間隔文字を挿入する(_矩形ならび_1,_列間隔文字,_行) :- 矩形ならびから行を取り出す(_行_1,_矩形ならび_1), 文字列を文字ならびに変換する(_行_1,_文字ならび), 文字列を結合する(_文字ならび,_列間隔文字,_行). 縦書文書に変形する(_矩形ならび_1,_縦書文書) :- 文字列を結合する(_矩形ならび_1,'\n',_縦書文書). 文字列の反転(_文字列,_反転した文字列) :- 文字列を文字ならびに変換する(_文字列,_文字ならび), 文字ならびを反転する(_文字ならび,_反転した文字ならび), 文字ならびを文字列に変換する(_反転した文字列,_反転した文字ならび). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 副文字列(_文字列,_開始位置,_長さ,_残り文字数,_副文字列) :- sub_atom(_文字列,_開始位置,_長さ,_残り文字数,_副文字列). 矩形ならびから行を取り出す(_行,_矩形ならび) :- member(_行,_矩形ならび). 矩形文字ならびから文字ならびを取り出す(_文字ならび,_転置された矩形文字ならび) :- member(_文字ならび,_転置された矩形文字ならび). 行ならびから行を取り出す(_行,_行ならび) :- member(_行,_行ならび). 二つの文字列を結合する(_文字列_1,_文字列_2,_結合した文字列) :- atom_concat(_文字列_1,_文字列_2,_結合した文字列). 文字列を結合する(_文字列ならび,_挿入文字,_結合した文字列) :- atomic_list_concat(_文字列ならび,_挿入文字,_結合した文字列). 文字列を結合する(_文字列ならび,_結合した文字列) :- atomic_list_concat(_文字列ならび,_結合した文字列). 文字列を文字ならびに変換する(_文字列,_文字ならび) :- atom_chars(_文字列,_文字ならび). 文字ならびを反転する(_文字ならび,_反転した文字ならび) :- reverse(_文字ならび,_反転した文字ならび). 文字ならびを文字列に変換する(_反転した文字列,_反転した文字ならび) :- atom_chars(_反転した文字列,_反転した文字ならび). 文字列長(_文字列,_文字列長) :- atom_length(_文字列,_文字列長). 整数を順に生成する(1,_列間隔文字数,_) :- between(1,_列間隔文字数,_). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 解を集める(_候補項,_目標,_解ならび) :- findall(_候補項,_目標,_解ならび). 解の最大値(_候補項,_目標,_解の最大値) :- findall(_候補項,_目標,_解ならび), 最大値(_解ならび,_解の最大値). 最大値(_ならび,_最大値) :- select(_最大値,_ならび,_残りならび), forall(member(_値,_残りならび),_最大値 @>= _値). 解の最小値(_候補項,_目標,_解の最小値) :- findall(_候補項,_目標,_解ならび), 最小値(_解ならび,_解の最小値). 最小値(_ならび,_最小値) :- select(_最小値,_ならび,_残りならび), forall(member(_値,_残りならび),_最小値 @=< _値). _値 は _式 :- _値 is _式. % 以下のサイトは # 出典 :: CodeIQ q1347 # # 3人の几帳面な男たちがいました。 # ジェシー「みかんをたくさん頂いたんだ。みんなで分けようYO!」 # ダニエル「イイネ!…ええと、みかんは全部で30個あるみたいだから、ひとり10個ずつならきちんと分けられるNE!」 # ジョゼフ「それだけじゃダメだYO!みかんは一つひとつ大きさが違うんだから、その辺も考えてきっちり分けNIGHT!」 # # # 【問題】 # # 30個のみかんがあります。3人で10個ずつ分けようと思いますが、不公平にならないよう、みかんの重さの合計が均一になるように分けてください。たとえば、次のような重さのみかん6個 # 101g # 103g # 110g # 105g # 114g # 112g # # を、3人で2つずつ分ける場合、重さの合計が等しくなるように分けると # (101g, 114g) # (103g, 112g) # (105g, 110g) # # のように、合計が215グラムになるように分けることができます。 # # みかんの重さのデータを標準入力から読み込み、それを重さの合計・個数ともに3等分するプログラムを書いてください。 # # # 【入力】 # # 入力はテキストファイルで用意されています。これを標準入力から読み込んでください。 # 入力ファイルの1行目には、みかんの個数Nが与えられます。 # 2行目以降のN行分が、みかんの重さ(正の整数)です。 # # # 【出力】 # # 標準出力に、3等分したみかんのグループを出力してください。 # 1行につき1グループ、計3行を出力します。それ以外は出力しないでください。 # 分け方が複数ある場合、その中の1種類だけを出力してください。 # # # 【入出力例】 # # - sample1.in.txt # 6 # 101 # 103 # 110 # 105 # 114 # 112 # # - sample1.out.txt # (101, 114) # (103, 112) # (105, 110) # # # # - sample2.in.txt # 12 # 147 # 105 # 99 # 116 # 105 # 119 # 93 # 132 # 123 # 95 # 101 # 82 # # - sample2.out.txt # (82, 105, 105, 147) # (93, 95, 119, 132) # (99, 101, 116, 123) '入力ファイルからみかんの重さならびを得て、三人とも同量の重さで、配分した候補を得て、重複を取り除いて出力する'(_入力ファイル,_出力ファイル) :- '入力ファイルからみかんの重さならびを得て、三人とも同量の重さで'(_入力ファイル,_みかんの重さならび,_一人あたりの重さ合計), 配分した候補を得て(_みかんの重さならび,_一人あたりの重さ合計,_重複を許す配分した候補), 重複を取り除いて出力する(_出力ファイル,_重複を許す配分した候補). '入力ファイルからみかんの重さならびを得て、三人とも同量の重さで'(_入力ファイル,_みかんの重さならび,_一人あたりの重さ合計) :- 入力ファイルからみかんの重さならびを得て(_入力ファイル,_みかんの重さならび), sum_list(_みかんの重さならび,_みかんの重さの合計), _一人あたりの重さ合計 is _みかんの重さの合計 // 3. 入力ファイルからみかんの重さならびを得て(_入力ファイル,_みかんの重さならび) :- see(_入力ファイル), 先頭行から行数を得る(_みかんの個数), 残り行からみかんの重さならびを得る(_みかんの個数,_みかんの重さならび), seen. 先頭行から行数を得る(_行数) :- 整数入力(_行数). 残り行からみかんの重さならびを得る(_みかんの個数,_みかんの重さならび) :- findall(_みかんの重さ,( between(1,_みかんの個数,_), 整数入力(_みかんの重さ)),_みかんの重さならび). 配分した候補を得て(_みかんの重さならび,_合計目標,_重複を許す配分した候補) :- findall(LL,同量に配分する(_みかんの重さならび,_合計目標,[],LL),_重複を許す配分した候補). 同量に配分する([],_,LL,LL). 同量に配分する(_みかんの重さならび,_合計目標,LL1,LL) :- 組み合計を得る(_みかんの重さならび,_合計目標,[],L,_残りみかんの重さならび), forall(member(L1,LL1),L1 @>= L), 同量に配分する(_残りみかんの重さならび,_合計目標,[L|LL1],LL). 組み合計を得る(_残りみかんの重さならび,_合計目標,L,L,_残りみかんの重さならび) :- sum_list(L,_合計目標). 組み合計を得る(_みかんの重さならび_1,_合計目標,L1,L,_残りみかんの重さならび) :- select(_一個,_みかんの重さならび_1,_残りみかんの重さならび_2), forall(member(A,L1),A @>= _一個), 組み合計を得る(_残りみかんの重さならび_2,_合計目標,[_一個|L1],L,_残りみかんの重さならび). 重複を取り除いて出力する(_出力ファイル,_重複を許す配分した候補) :- 重複なく昇順に整列する(_重複を許す配分した候補,_候補リスト), 一行ずつ出力する(_出力ファイル,_候補リスト). 重複なく昇順に整列する(L1,L2) :- 重複なく昇順に整列する(L1,[],L2). 重複なく昇順に整列する([],L,L). 重複なく昇順に整列する([_軸要素|L1],L2,L3) :- 重複のない昇順分割(_軸要素,L1,LS,LB), 重複なく昇順に整列する(LS,[_軸要素|L3_2],L3), 重複なく昇順に整列する(LB,L2,L3_2). 重複のない昇順分割(_,[],[],[]). 重複のない昇順分割(_軸要素,[A|R1],[A|R2],R3) :- A @< _軸要素, 重複のない昇順分割(_軸要素,R1,R2,R3). 重複のない昇順分割(_軸要素,[A|R1],R2,[A|R3]) :- A @> _軸要素, 重複のない昇順分割(_軸要素,R1,R2,R3). 重複のない昇順分割(_軸要素,[_軸要素|R1],R2,R3) :- 重複のない昇順分割(_軸要素,R1,R2,R3). 一行ずつ出力する(_出力ファイル,_候補リスト) :- tell(_出力ファイル), forall(member(_三人分のみかんの重さならび,_候補リスト),配分候補ならびを三行で出力する(_三人分のみかんの重さならび)), told. 配分候補ならびを三行で出力する(_三人分のみかんの重さならび) :- forall(member(_みかんの重さならび,_三人分のみかんの重さならび),( 表示パターンのつくり(_みかんの重さならび,_表示パターン), writef(_表示パターン,_みかんの重さならび))). 表示パターンのつくり(_みかんの重さならび,_表示パターン) :- length(_みかんの重さならび,_要素数), findall('%t',between(1,_要素数,_),_表示パターンならび), atomic_list_concat(_表示パターンならび,',',_表示パターン_1), atomic_list_concat(['(',_表示パターン_1,')\n'],_表示パターン). 整数入力(_整数) :- 行入力(_行), read_term_from_atom(_行,_整数,[]). 行入力(_行) :- get_char(_文字), 行の文字ならび(_文字,_行の文字ならび), atom_chars(_行,_行の文字ならび). 行の文字ならび(end_of_file,[]) :- !. 行の文字ならび('\n',[]) :- !. 行の文字ならび(_文字,[_文字|R]) :- get_char(_次の文字), 行の文字ならび(_次の文字,R). ユーザパラメータならび(_ユーザパラメータならび) :- current_prolog_flag(argv,_ユーザパラメータならび). program :- ユーザパラメータならび([_入力ファイル,_出力ファイル]), '入力ファイルからみかんの重さならびを得て、三人とも同量の重さで、配分した候補を得て、重複を取り除いて出力する'(_入力ファイル,_出力ファイル). :- program,halt. % 以下のサイトは 250 ToastXToast 要約  何種類かのパンがあり,種類ごとにちょうどよい焼き時間が決まっている.その焼き時間より短ければ生焼けで,長ければ焦げてしまう.またどの種類のパンかは見た目にはわからない.生焼けのパンと焦げたパンがいくつか与えられていて.それぞれのパンの焼いた時間がわかっている.また,それぞれの種類で生焼けのパンと焦げたパンが少なくとも1枚ずつある事もわかっている.パンの種類として考えられるもののうち最小値を求めよ.  生焼けのパンの数と焦げたパンの数は1以上50以下,それぞれのパンの焼いた時間は1以上1000000以下.同じ時間だけ焼いたパンは2枚以上存在しない事は保証されている. 方針 生焼けのパンを○,焦げたパンを●で表し,焼き時間を横軸で表すと,一般的な状況では ○○ー○○○○○○ーーーー○○ーー○ー○○○ーー ーー●ーーーーーー●●●●ーー●●ー●ーーー●● の用になっている.この場合, ○○ー○○○○○○ーーーー○○ーー○ー○○○ーー ーーーーーーーーーーーーーーーーーーーーーー●● と ○○ーーーーーーーーーーーーーーーーーーーーーー ーー●ーーーーーー●●●●ーー●●ー●ーーーーー とわけることができ,答えは2種類とわかる.あとはこの状況にならないのはいつかを考えればよい. コード例 #include #include #include #include #include using namespace std; class ToastXToast { public: int bake(vector under, vector over) { sort(under.begin(), under.end()); sort(over.begin(), over.end()); if(over[0] <= under[0] ) return -1; if(under[under.size()-1] >= over[over.size()-1]) return -1; if(over[0] > under[under.size()-1]) return 1; else return 2; } }; 500 KingdomXCitiesandVillage 要約  座標平面上の格子点に町がいくつかと村がいくつか配置されている.次のアルゴリズムで,すべての村をいずれかの町と道路でつなぐ. はじめ,すべての村は町につながっていない 町につながっていない村をランダムに一つ選ぶ (それを sv(selected village) とする) 町 or「既に町につながっている村」のなかで sv に(ユークリッド距離で)最も近いものを選び,その2つを道路でつなぐ.最も近いものが複数ある場合はランダムに選ぶ. sv を「既に町につながっている村」に昇格させる. これをすべての村がつながるまで繰り返す.  道路の総距離の期待値を答えよ.町と村の数はそれぞれ1以上50以下,それぞれの町,村の座標は0以上1000000以下.同じ箇所に複数の町や村はない事は保証されている. 方針  まず期待値の加法性から,各々の村から延ばす道路の距離の期待値を合計すればよいので,一つの村に注目する(以降その村をvとし,その村から最も近い町をcとする).v とつながる可能性のある村は,v との距離が vc 間より短いもののみである.まずそれだけを取り出し v との距離が短い順に v[1], v[2], ・・・, v[k] とする.v と c がつながるのは,v が v[1], v[2], ・・・v[k] のいずれよりも先に選ばれたときなので,その確率は 1/(k+1).v と v[j] がつながるのは「 v[j]が vより先に選ばれ,かつvが v[1], v[2], ・・・, v[j-1]より先に選ばれる」ときである(前者が満たされないとv[j]は村とつながっていないのでそもそも候補に入らず,また後者が満たされないとvはv[1]・・・v[j-1]のいずれかとつながってしまう).v[j+1]・・・v[k]には制限がないので考慮しなくても良い.j+1個の球を横一列に並べる事を考えると,条件を満たすのは最左にv[j], その隣に v ,残りj-1個にv[1]・・・v[j-1]を自由に並べかえるものなので,その場合の数は(j - 1)!,全事象は(j + 1)! なので,求める確率は(j-1)! / (j+1)! = 1/ ( j * (j + 1) ) . #include #include #include #include #include #include using namespace std; typedef long long ll; ll dist2(int ax, int ay, int bx, int by){ return (ll)(ax - bx) * (ax - bx) + (ll)(ay - by) * (ay - by) ; } class KingdomXCitiesandVillages { public: double determineLength(vector cx, vector cy, vector vx, vector vy) { int n = cx.size(); int m = vx.size(); double ans = 0; for(int i = 0;i kouho; for(int j = 0;j% 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1295436346/173 # # 質問させてください # selectしたデータを一部だけ別のテーブルに入れる方法ってありますか? # # 例:insert into table2 (aaa,bbb,ccc) select aaa as aaa,bbb as bbb,ccc as ccc from table1 # この場合table1のデータがすべてtable2に入るのでaaaだけ別のデータを入れたいと思っています。 # よろしくお願いします。 # # 海に接していない都道府県名([栃木県,群馬県,埼玉県,山梨県,長野県,岐阜県,滋賀県,奈良県]). table1(奈良県,1000,aa). table1(埼玉県,2000,ab). selectしたデータを一部だけ別のテーブルに入れる方法 :- 海に接していない都道府県名(_海に接していない都道府県名ならび), table1(_都道府県名の一,_bbb,_ccc), 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二), assertz(table2(_都道府県名の二,_bbb,_ccc)), fail. selectしたデータを一部だけ別のテーブルに入れる方法. 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二) :- M is (random mod 8) + 1, list_nth(M,_海に接していない道府県名ならび,_都道府県名の二), \+(_都道府県名の一 = _都道府県名の二), \+(table2(_都道府県名の二,_,_)). 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二) :- 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二). ?- 'a##'. # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/584 # # MySQL 5.5.19 . 長くなりますので # テーブルの定義・内容と欲しい結果はここに # http://ime.nu/codepad.org/oe1jhVrF # # で、 # # create table a_tbl( # code int(9) not null, # input_date date not null, # data1 double(9,2) unsigned default 0 not null, # data2 double(9,2) unsigned default 0 not null, # primary key(code,input_date) # ) ; # # insert into a_tbl # values # (1111,'2012-02-01',10,12), # (1111,'2012-02-02',133,14), # (1111,'2012-02-04',13,15), # (1111,'2012-02-06',13,10); # # create table b_tbl( # code varchar(10) not null, # input_date date not null, # data1 double(9,2) unsigned default 0 not null, # data2 double(9,2) unsigned default 0 not null, # primary key(code,input_date) # ) ; # # insert into b_tbl # values # ('ddd','2012-02-01',122,13), # ('ddd','2012-02-03',127,18), # ('ddd','2012-02-04',11,14), # ('ddd','2012-02-05',16,95), # ('ddd','2012-02-06',13,10); # # 欲しい結果 # input_date a.data1 a.data2 b.data2 # 2012-02-01 10 12 13 # 2012-02-02 133 14 null # 2012-02-03 null null 18 # 2012-02-04 13 15 14 # 2012-02-05 null null 95 # 2012-02-06 13 10 10 # # # select a.input_date,b.input_date,a.data1,a.data2,b.data2 # from a_tbl a # right join b_tbl b # on a.input_date = b.input_date; とすると、結果が # +------------+------------+-------+-------+-------+ # | input_date | input_date | data1 | data2 | data2 | # +------------+------------+-------+-------+-------+ # | 2012-02-01 | 2012-02-01 | 10 | 12 | 13 | # | NULL | 2012-02-03 | NULL | NULL | 18 | # | 2012-02-04 | 2012-02-04 | 13 | 15 | 14 | # | NULL | 2012-02-05 | NULL | NULL | 95 | # | 2012-02-06 | 2012-02-06 | 13 | 10 | 10 | # +------------+------------+-------+-------+-------+ # なんですが、実際にはいろんなコードが入っているので、コードも抽出条件に入れたら # select a.input_date,b.input_date,a.data1,a.data2,b.data2 # from a_tbl a # right join b_tbl b # on a.input_date = b.input_date # where # a.code=1111 and b.code='ddd'; # +------------+------------+-------+-------+-------+ # | input_date | input_date | data1 | data2 | data2 | # +------------+------------+-------+-------+-------+ # | 2012-02-01 | 2012-02-01 | 10 | 12 | 13 | # | 2012-02-04 | 2012-02-04 | 13 | 15 | 14 | # | 2012-02-06 | 2012-02-06 | 13 | 10 | 10 | # +------------+------------+-------+-------+-------+ # になってしまいました。 # コードを抽出条件に入れた状態で望ましい結果または上の方の結果になるようなSQLを教えて下さい。 # 'input_dateの集合を得る'(_input_dateの集合) :- findall(_input_date,a_tbl(_input_date,_,_),L1), findall(_input_date,b_tbl(_input_date,_,_),L2), append(L1,L2,L3), setof(_input_date,member(_input_date,L3),_input_dateの集合). 抽出(_input_date,_tbl_aのdata1ならび,_tbl_aのdata2ならび,_tbl_bのdata2ならび) :- 'input_dateの集合を得る'(_input_dateの集合), member(_input_date,_input_dateの集合), findall([_data1],tbl_a(_,_input_date,_data1,_),_tbl_aのdata1ならび), findall([_data2],tbl_a(_,_input_date,_,_data2),_tbl_aのdata2ならび), findall([_data2],tbl_b(_,_input_date,_,_data2),_tbl_bのdata2ならび). # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/633 # # MySQL 5.1です。 # # create table staff_list( # staff_id int(5) primary key //社員番号 # staff_name varchar(8) //社員名 # unit varchar(8) primary key //部署名 # ) # # insert into staff_list (staff_id,staff_name,unit) values # (1,'範馬','総務'), # (2,'愚地','総務'), # (3,'花山','総務'), # (1,'高津','企画'), # (2,'池谷','企画'), # (3,'長嶋','企画'), # (1,'鳩山','営業'), # (2,'野田','営業'), # (3,'小沢','営業'), # (4,'枝野','営業') # # # # このようなテーブルに対してSELECTをかける際、一度のクエリーで # 部署別にソートしたうえで、総務だけstaff_id降順で他を昇順で出したいと思っています。 # # order by unit,IF(staff_name='総務',staff_id desc,staff_id asc) # などと試行してみているのですがうまくできません。 # # どなたかうまい方法をご存じないでしょうか。 # # よろしくお願いいたします。 # スタッフリスト(1,範馬,総務). スタッフリスト(2,愚地,総務). スタッフリスト(3,花山,総務). スタッフリスト(1,高津,企画). スタッフリスト(2,池谷,企画). スタッフリスト(3,長嶋,企画). スタッフリスト(1,鳩山,営業). スタッフリスト(2,野田,営業). スタッフリスト(3,小沢,営業). スタッフリスト(4,枝野,営業). 'このようなテーブルを選択する際、一度部署別にソートしたうえで、総務だけ社員番号降順で出したいと思っています。'(_部署名,_社員番号,_社員名) :- 一度部署別にソートしたうえで(_部署名ならび), 総務だけ社員番号降順で出したい(_部署名ならび,_部署名,_社員番号,_社員名). 一度部署別にソートしたうえで(_部署名ならび) :- findsetof(_部署名,( スタッフリスト(_社員番号,_社員名,_部署名)), _部署名ならび). 総務だけ社員番号降順で出したい(_部署名ならび,_部署名,_社員番号,_社員名) :- member(_部署名,_部署名ならび), 総務だけ社員番号降順で出したい(_部署名,_社員番号,_社員名). 総務だけ社員番号降順で出したい(総務,_社員番号,_社員名) :- 総務だけ社員番号降順で(_社員番号,_社員名). 総務だけ社員番号降順で出したい(_部署名,_社員番号,_社員名) :- \+(_部署名 == 総務), スタッフリスト(_社員番号,_社員名,_部署名). 総務だけ社員番号降順で(_社員番号,_社員名) :- findall([_社員番号,_社員名],( スタッフリスト(_社員番号,_社員名,総務)), L1), 降順でソート(L1,L2), member([社員番号,_社員名],L2). 降順でソート(L1,L2) :- sort(L1,L3), reverse(L3,L2). % % findsetof/3 % # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/666 # # SQLite3を使っています。 # # カラムがなかったらinsert # あったらupdateしたいのですが、 # どういうSQLをかけばいいのでしょうか? # # insert into t1(c1, c2) values("hoge",10) # update t1 set c2=10 WHERE c1="hoge" # このときc1はuniqueです。 # # よろしくお願いします。 # # 'カラムがなかったらinsert あったらupdateしたい'(_テーブル,_カラムならび,_鍵カラム,_鍵値) :- findall(_カラム,( テーブル定義(_テーブル,_番目,_カラム)), L1), 鍵値をセットする(_テーブル,_鍵カラム,_鍵値,P), 'カラムがなかったらinsert あったらupdateしたい'(P,_テーブル,_カラムならび). 鍵値をセットする(_テーブル,L1,_鍵カラム,_鍵値,P) :- length(L1,Len), length(L2,Len), nth1(Nth,L1,_鍵カラム), nth1(Nth,L2,_鍵値), P =.. [_テーブル|L2]. 'カラムがなかったらinsert あったらupdateしたい'(P,_テーブル,_カラムならび) :- call(P),!, ( retract(P), Q =.. [_テーブル|_カラムならび], asserta(Q), fail; true). 'カラムがなかったらinsert あったらupdateしたい'(_,_テーブル,_カラムならび) :- Q =.. [_テーブル|_カラムならび], asserta(Q). # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/684 # # ・DBMS名とバージョン # Oracle 10g # ・テーブルデーた # create table aaa ( # id number(5,0) primary key, -- 主キー # nendo char(4), -- 年度 # tsuki char(2) -- 月 # ); # insert into aaa values (1, '2012', '01'); # insert into aaa values (2, '2012', '02'); # insert into aaa values (3, '2012', '03'); # insert into aaa values (4, '2012', '04'); # insert into aaa values (5, '2012', '05'); # ・欲しい結果 # id, nendo, tsuki # -------------------- # 4, '2012', '04' # 5, '2012', '05, # 1, '2012', '01' # 2, '2012', '02' # 3, '2012', '03' # # ・説明 # 年度/月の昇順に並べたいです。 # 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。 # '・テーブルデータ create table aaa ( id number(5,0) primary key, -- 主キー nendo char(4), -- 年度 tsuki char(2) -- 月 ); insert into aaa values (1, '2012', '01'); insert into aaa values (2, '2012', '02'); insert into aaa values (3, '2012', '03'); insert into aaa values (4, '2012', '04'); insert into aaa values (5, '2012', '05'); ・欲しい結果 id, nendo, tsuki -------------------- 4, '2012', '04' 5, '2012', '05, 1, '2012', '01' 2, '2012', '02' 3, '2012', '03' ・説明 年度/月の昇順に並べたいです。 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。'(_id,_年度,_月) :- 欲しい結果(_id,_年度,_月). 年度の場合の月順('04','05'). 年度の場合の月順('05','06'). 年度の場合の月順('06','07'). 年度の場合の月順('07','08'). 年度の場合の月順('08','09'). 年度の場合の月順('09','10'). 年度の場合の月順('10','11'). 年度の場合の月順('11','12'). 年度の場合の月順('12','01'). 年度の場合の月順('01','02'). 年度の場合の月順('02','03'). 年度の場合の月順('03','04'). 欲しい結果(_id,_年度,_月) :- findsetof(_年度,aaa(_,_年度,_),_年度ならび), member(_年度,_年度ならび), 年度順に並べる('04',_id,_年度,_月). 年度順に並べる(_月,_id,_年度,_月) :- aaa(_id,_年度,_月). 年度順に並べる(_月_1,_id,_年度,_月) :- \+(_月_1 = '03'), 年度の場合の月順(_月,_次の月), 年度順に並べる(_次の月,_id,_年度,_月). # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/684 # # ・DBMS名とバージョン # Oracle 10g # ・テーブルデーた # create table aaa ( # id number(5,0) primary key, -- 主キー # nendo char(4), -- 年度 # tsuki char(2) -- 月 # ); # insert into aaa values (1, '2012', '01'); # insert into aaa values (2, '2012', '02'); # insert into aaa values (3, '2012', '03'); # insert into aaa values (4, '2012', '04'); # insert into aaa values (5, '2012', '05'); # ・欲しい結果 # id, nendo, tsuki # -------------------- # 4, '2012', '04' # 5, '2012', '05, # 1, '2012', '01' # 2, '2012', '02' # 3, '2012', '03' # # ・説明 # 年度/月の昇順に並べたいです。 # 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。 # '・テーブルデータ create table aaa ( id number(5,0) primary key, -- 主キー nendo char(4), -- 年度 tsuki char(2) -- 月 ); insert into aaa values (1, '2012', '01'); insert into aaa values (2, '2012', '02'); insert into aaa values (3, '2012', '03'); insert into aaa values (4, '2012', '04'); insert into aaa values (5, '2012', '05'); ・欲しい結果 id, nendo, tsuki -------------------- 4, '2012', '04' 5, '2012', '05, 1, '2012', '01' 2, '2012', '02' 3, '2012', '03' ・説明 年度/月の昇順に並べたいです。 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。'(_id,_年度,_月) :- 欲しい結果(_id,_年度,_月). 欲しい結果(_id,_年度,_月) :- findsetof(_年度,aaa(_,_年度,_),_年度ならび), member(_年度,_年度ならび), 年度順に並べる(['04','05','06','07','08','09','10','11','12','01','02','03'],_id,_年度,_月). 年度順に並べる([_月|R],_id,_年度,_月) :- aaa(_id,_年度,_月). 年度順に並べる([_|R],_id,_年度,_月) :- 年度順に並べる(R,_id,_年度,_月). # 質問です。 # MySQL5です。 # テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。 # 各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。 # 言っていることが、よくわからなくてすみません。 # # 元テーブル # DATE, CODE, VALUE # .... # 20140401, 11, A # 20140402, 12, B # 20140403, 11, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # .... # # 欲しい結果 # 20140401, 11, A # 20140403, 11, C # 20140406, 11, F # 20140402, 12, B # 20140405, 12, E # 20140404, 13, D # # 宜しくお願い致します。 # # # 879 名前:NAME IS NULL [sage]: 2014/04/25(金) 17:41:21.67 ID:??? # >>877 # どうも質問が明確じゃないけど、 # insert into tname select 〜 # の形式にすればとりあえず解決しそうな話に見える。 # # >>878 # order by code, date ということ? # # # 880 名前:NAME IS NULL []: 2014/04/25(金) 17:47:38.30 ID:+Fb19Efw (3) # 879 # 分かりずらい # 欲しい結果にしてしまいました。 # # 第1キーは、日付です。 # # 元テーブル # DATE, CODE, VALUE # 20140401, 13, A # 20140402, 11, B # 20140403, 12, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # # 欲しい結果 # 20140401, 13, A # 20140404, 13, D # 20140402, 11, B # 20140406, 11, F # 20140403, 12, C # 20140405, 12, E # # 宜しくお願い致します。 # # # 要するに第一キーは降順、第二キーは昇順で整列する。 # 'テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。'(_DATE,_CODE,_VALUE) :- '要するに第一キーは降順、第二キーは昇順で整列する。'(_DATE,_CODE,_VALUE). '要するに第一キーは降順、第二キーは昇順で整列する。'(_DATE,_CODE,_VALUE) :- 第一キー順序(_CODE), 第二キー順序(_CODE,_DATE), 元テーブル(_DATE,_CODE,_VALUE). 第一キー順序(_CODE) :- findsetof(_CODE,( 元テーブル(_DATE,_CODE,_VALUE)), L1), reverse(L1,L2), member(_CODE,L2). 第二キー順序(_CODE,_DATE) :- findsetof(_DATE,( 元テーブル(_DATE,_CODE,_VALUE)), L1), member(_DATE,L1). % 以下のサイトは # # qsort # 昇順整列([],[]). 昇順整列(_要素ならび,_昇順に整列した要素ならび) :- 軸要素(_要素ならび,_軸要素,_軸要素を除いた要素ならび), '軸要素より小さい要素ならびを昇順に整列したものと,軸要素に等しいか大きい要素ならびを昇順に整列したものを軸要素を挟んで結合する'(_軸要素を除いた要素ならび,_軸要素,_昇順に整列した要素ならび). 軸要素(_要素ならび,_軸要素,_軸要素を除いた要素ならび) :- select(_軸要素,_要素ならび,_軸要素を除いた要素ならび),!. '軸要素より小さい要素ならびを昇順に整列したものと,軸要素に等しいか大きい要素ならびを昇順に整列したものを軸要素を挟んで結合する'(_軸要素を除いた要素ならび,_軸要素,_昇順に整列した要素ならび) :- 軸要素より小さい要素ならびを昇順に整列したものと(_軸要素を除いた要素ならび,_軸要素,_昇順に整列した軸要素より小さい要素ならび), 軸要素に等しいか大きい要素ならびを昇順に整列したものを(_軸要素を除いた要素ならび,_軸要素,_昇順に整列した軸要素に等しいか大きい要素ならび), 軸要素を挟んで結合する(_昇順に整列した軸要素より小さい要素ならび,_軸要素,_昇順に整列した軸要素に等しいか大きい要素ならび,_昇順に整列した要素ならび). 軸要素より小さい要素ならびを昇順に整列したものと(_軸要素を除いた要素ならび,_軸要素,_昇順に整列した軸要素より小さい要素ならび) :- findall(_軸要素より小さい要素,( member(_軸要素より小さい要素,_軸要素を除いた要素ならび), _軸要素より小さい要素 @< _軸要素),_軸要素より小さい要素ならび), 昇順整列(_軸要素より小さい要素ならび,_昇順に整列した軸要素より小さい要素ならび). 軸要素に等しいか大きい要素ならびを昇順に整列したものを(_軸要素を除いた要素ならび,_軸要素,_昇順に整列した軸要素に等しいか大きい要素ならび) :- findall(_軸要素に等しいか大きい要素,( member(_軸要素に等しいか大きい要素,_軸要素を除いた要素ならび), _軸要素に等しいか大きい要素 @>= _軸要素),_軸要素に等しいか大きい要素ならび), 昇順整列(_軸要素に等しいか大きい要素ならび,_昇順に整列した軸要素に等しいか大きい要素ならび). 軸要素を挟んで結合する(_昇順に整列した軸要素より小さい要素ならび,_軸要素,_昇順に整列した軸要素に等しいか大きい要素ならび,_昇順に整列した要素ならび) :- append(_昇順に整列した軸要素より小さい要素ならび,[_軸要素|_昇順に整列した軸要素に等しいか大きい要素ならび],_昇順に整列した要素ならび). % 以下のサイトは ハイカード(_手札,_数字_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']). % 以下のサイトは # # 3年H組で最も高い身長は # '3年H組で最も高い身長'(_3年H組の身長ならび,_3年H組で最も高い身長) :- select(_3年H組で最も高い身長,_3年H組の身長ならび,_残り身長ならび), forall(member(_生徒の身長,_残り身長ならび),_生徒の身長 @=< _3年H組で最も高い身長). % この select/3, forall/2, member/2 を具象化させることはかなり難しい。 % 例えば、ここで具象化とは、'3年H組・・・' に述語名を置き直すこと。 % 以下のサイトは # プログラミングのお題スレ Part5 #27 # # nこの角砂糖でできる直方体は何種類あるか? # 'nこの角砂糖でできる直方体は何種類あるか?'(_n,_何種類) :- 'nこの角砂糖でできる直方体は'(_n,_直方体ならび), length(_直方体ならび,_何種類). 'nこの角砂糖でできる直方体は'(_n,_直方体ならび) :- findall(M,between(1,_n,M),L), findall([_辺1,_辺2,_辺3],( 直方体(L,_n,_辺1,_辺2,_辺3)),_直方体ならび). 直方体(L,_n,_辺1,_辺2,_辺3) :- '_辺1,_辺2,_辺3を選択'(L,_辺1,_辺2,_辺3), '_辺1,_辺2,_辺3は昇順'(_辺1,_辺2,_辺3), _n is _辺1 * _辺2 + _辺3. '_辺1,_辺2,_辺3を選択'(L,_辺1,_辺2,_辺3) :- select(_辺1,L,R1), select(_辺2,L,R2), select(_辺3,L,R3). '_辺1,_辺2,_辺3は昇順'(_辺1,_辺2,_辺3) :- _辺1 =< _辺2, _辺2 =< _辺3. % 以下のサイトは # 問題文 # (21:13 追記) |A|=|B|=1のケースがテスト中に一つ含まれていましたので、リジャッジを行います。なお、このケースでNOを出力するプログラムに影響はありません。 # # 文字列 A の文字をちょうど 3 回スワップすることにより、文字列 B に変換できるとき、二つの文字列 A, B を、仲良し文字列と呼ぶことにします。 # # スワップとは、文字列に含まれる 2 つの文字を、入れ替えることを指します。 例えば、abcという文字列であれば、aとcを入れ替えて、cbaのように変換することが出来ます。 # # aaのような文字列に対し、 1 文字目のaと、 2 文字目のaを入れ替えることは許されていますが、同じ場所の文字を指定することはできません。 # # 文字列 A, B が与えられるので、仲良し文字列になっているかどうかを判定しなさい。 # # 入力 # 入力は以下の形式で標準入力から与えられる。 # # A # B # 1 行目には、文字列 A(2≦|A|≦1000) が与えられる。 # 2 行目には、文字列 B(|B|=|A|) が与えられる。 # A, B 共に、小文字アルファベットのみで構成されていることが保障されている。 # 出力 # 与えられた 2 つの文字列が、仲良し文字列であればYES、そうでなければNOを出力せよ。 出力の末尾には改行をいれること。 # # 入力例1 # abcdef # fedcba # 出力例1 # YES # まず、文字列 A のabcdefのaとfをスワップし、fbcdeaとします。 # # 次に、bとeをスワップし、fecdbaとします。 # # 最後に、cとdをスワップし、fedcbaとすると、文字列 B と一致します。 # # よって、この 2 つの文字列は、仲良し文字列となるため、YESと出力します。 # # 入力例2 # abababab # babababa # 出力例2 # NO # 使っている文字数が同じでも、 3 回のスワップでは同じ文字列にできないパターンも存在します。 # # 入力例3 # nt # nt # 出力例3 # NO # スワップの仕方が 1 通りしかなく、 3 回のスワップを繰り返すと、tnになってしまいます。 よって、同じ 2 つの文字列ですが、仲良し文字列ではありません。 # # 入力例4 # pqqq # pqqq # 出力例4 # YES # まず、 1 番目の文字と 2 番目の文字を入れ替え、qpqqとします。 次に、 3 番目の文字と 4 番目の文字を入れ替え、qpqqとします。この際、同じ文字を選んでいますが、場所が違うので問題ありません。 最後に、1番目の文字と、2番目の文字を入れ替え、pqqqとします。 # # 入力例5 # abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvxyzw # abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz # 出力例5 # YES # 長い文字列が与えらえれることがあることにも注意してください。 # # 入力例6 # abcdef # ghijkl # 出力例6 # NO '文字列 A, B が与えられるので、仲良し文字列になっているかどうかを判定しなさい。'(A,B) :- 標準入力から二つの文字列を得る(A,B), '文字列 A, B が与えられるので、仲良し文字列になっているかどうかを判定しなさい。'(A,B). '文字列 A, B が与えられるので、仲良し文字列になっているかどうかを判定しなさい。'(A,B) :- 文字列と仲良し文字列(A,B), write('YES\n'),!. '文字列 A, B が与えられるので、仲良し文字列になっているかどうかを判定しなさい。'(A,B) :- write('NO\n'). 文字列と仲良し文字列(_文字列,_仲良し文字列) :- 二つの文字列をならびに変換する(_文字列,_仲良し文字列,L1,L2), '二つのならびの差分(L3,L4)と同一部分(L5)'(L1,L2,L3,L4,L5), 三組のスワップが存在する(L3,L4,L5,Len). 二つの文字列をならびに変換する(_文字列,_仲良し文字列,L1,L2) :- atom_chars(_文字列,L1), atom_chars(_仲良し文字列,L2). '二つのならびの差分(L3,L4)と同一部分(L5)'([],[],[],[],[]). '二つのならびの差分(L3,L4)と同一部分(L5)'([A|R1],[A|R2],R3,R4,[A|R5]) :- '二つのならびの差分(L3,L4)と同一部分(L5)'(R1,R2,R3,R4),!. '二つのならびの差分(L3,L4)と同一部分(L5)'([A|R1],[B|R2],[A|R3],[B|R4],R5) :- '二つのならびの差分(L3,L4)と同一部分(L5)'(R1,R2,R3,R4,R5). 三組のスワップが存在する(L3,L4,L5,Len) :- 二つのならびは同一要素からなる(L3,L4,Len), 整列(L5,L6), 同一文字のペアの可能性を含めて三組のスワップが存在するかどうかの検査(Len,L6). 二つのならびは同一要素からなる(L3,L4,Len) :- length(L3,Len), length(L4,Len). 同一の要素からなる(L3,L4). 同一の要素からなる([],[]). 同一の要素からなる([A|R1],L2) :- select(A,L2,R2), 同一の要素からなる(R1,R2). 同一文字のペアの可能性を含めて三組のスワップが存在するかどうかの検査(Len,L6) :- 同一文字ペアを数える(L6,_同一文字ペア数), 同一文字同士のスワップ検査(Len,_同一文字ペア数). 同一文字ペアの数を数える([],[]). 同一文字ペアの数を数える([A,A|R],[_|R2]) :- 同一文字ペアの数を数える(R1,R2),!. 同一文字ペアの数を数える([_|R1],R2) :- 同一文字ペアの数を数える(R1,R2). 同一文字同士のスワップ検査(3,_) :- !. 同一文字同士のスワップ検査(2,[_|_]) :- !. 同一文字同士のスワップ検査(1,[_,_|_]) :- !. 同一文字同士のスワップ検査(0,[_,_,_|_]). 整列([],[]). 整列([_軸要素|_残りならび],_整列したならび) :- 軸要素との大小で分割してそれぞれ整列する(_軸要素,_残りならび,_整列したL1,_整列したL2), append(_整列したL1,[_軸要素|_整列したL2],_整列したならび). 軸要素との大小で分割してそれぞれ整列する(_軸要素,_残りならび,_整列したL1,_整列したL2) :- 分割(_軸要素,_残りならび,L1,L2), 整列(L1,_整列したL1), 整列(L2,_整列したL2). 分割(_軸要素,[],[],[]). 分割(_軸要素,[A|R1],[A|R2],R3) :- 軸要素より大きい時は(_軸要素,A,R1,R2,R3). 分割(_軸要素,[A|R1],[A|R2],R3) :- 軸要素と等しいか小さい時は(_軸要素,A,R1,R2,R3). 軸要素より大きい時は(_軸要素,A,R1,R2,R3) :- _軸要素 @< A, 分割(_軸要素,R1,R2,R3). 軸要素と等しいか小さい時は(_軸要素,A,R1,R2,R3) :- _軸要素 @>= A, 分割(_軸要素,R1,R2,R3). 標準入力から二つの文字列を得る(A,B) :- 標準入力から文字列を得る(A), 標準入力から文字列を得る(B). 標準入力から文字列を得る(_文字列) :- findall(_文字,( 一文字を得る(_文字), (終了文字(_文字),!,fail;true)),_文字ならび), atom_chars(_文字列,_文字ならび). 一文字を得る(_文字) :- get_char(_文字). 一文字を得る(_文字) :- 一文字を得る(_文字). 終了文字('\n'). 終了文字(end_of_file). % 以下のサイトは # # あなたは既に読んでしまった札を記憶していることにします。 # まだ読まれていない、読み札も分かっていることとします。 # 読み札/2、既に読んでしまった札/2、自陣/1、敵陣/1がそれぞれ # 述語としして定義済みだとして、自陣、敵陣、あるいはその両方の札の # 決まり字を示すプログラムを定義してください。 # :- dynamic(読み札/1). :- dynamic(既に読んでしまった札/1). :- dynamic(自陣/1). :- dynamic(敵陣/1). 自陣または敵陣の全ての札の決まり字(_下の句,_上の句,_決まり字) :- 自陣または敵陣(_下の句), 読み札(_上の句,_下の句), 決まり字(_上の句,_決まり字). 自陣の札の決まり字(_下の句,_上の句,_決まり字) :- 自陣(_下の句), 読み札(_上の句,_下の句), 決まり字(_上の句,_決まり字). 敵陣の札の決まり字(_下の句,_上の句,_決まり字) :- 敵陣(_下の句), 読み札(_上の句,_下の句), 決まり字(_上の句,_決まり字). 決まり字(_上の句,_決まり字) :- 最長共通文字数(_上の句,_最長共通文字数), succ(_最長共通文字数,_決まり字の位置), sub_atom(_上の句,0,_決まり時の位置,_,_決まり字). 最長共通文字数(_上の句,_最長共通文字数) :- findmax(_先頭から最長共通文字数,( 対象としている上の句とは別の上の句を読み札から得る(_上の句,_別の上の句), '先頭から最長共通文字数(0オリジン)'(_上の句,別の上の句,_先頭からの最長共通文字数)),_最長共通文字数). 対象としている上の句とは別の上の句を読み札から得る(_上の句,_別の上の句) :- 読み札(_別の上の句,_), \+(_上の句 = _別の上の句). '先頭から最長共通文字数(0オリジン)'(_上の句,_別の上の句,_文字数) :- nth0(_文字数,_,_), sub_atom(_上の句,_文字数,1,_,_文字_1), sub_atom(_別の上の句,_文字数,1,_,_文字_2), \+(_文字_1=_文字_2),!. 下の句から決まり字を得る(_下の句,_決まり字) :- 自陣または敵陣(_下の句), '下の句から上の句を得る'(_下の句,_上の句), 決まり字(_上の句,_決まり字). 自陣または敵陣(_下の句) :- 自陣(_下の句). 自陣または敵陣(_下の句) :- 敵陣(_下の句). 下の句から上の句を得る(_下の句,_上の句) :- 読み札(_上の句,_下の句). findmax(_値,_目標,_最大値) :- findall(_値,_目標,_値ならび), 最大値(_値ならび,_最大値). 最大値(_標本ならび,_最大値) :- select(_最大値,_標本ならび,_残り標本ならび), forall(member(_標本_1,_残り標本ならび),_標本_1 @=< _最大値),!. /* 読み札('あきのたのかりほのいほのとまをあらみ,わがころもではつゆにぬれつつ'). 読み札('はるすぎてなつきにけらししろたへの,ころもほすてふあまのかぐやま'). 読み札('あしびきのやまどりのをのしだりをの,ながながしよをひとりかもねむ'). 読み札('たごのうらにうちいでてみればしろたへの,ふじのたかねにゆきはふりつつ'). 読み札('おくやまにもみぢふみわけなくしかの,こゑきくときぞあきはかなしき'). 読み札('かささぎのわたせるはしにおくしもの,しろきをみればよぞふけにける'). 読み札('あまのはらふりさけみればかすがなる,みかさのやまにいでしつきかも'). 読み札('わがいほはみやこのたつみしかぞすむ,よをうぢやまとひとはいふなり'). 読み札('はなのいろはうつりにけりないたづらに,わがみよにふるながめせしまに'). 読み札('これやこのゆくもかへるもわかれては,しるもしらぬもあふさかのせき'). 読み札('わたのはらやそしまかけてこぎいでぬと,ひとにはつげよあまのつりぶね'). 読み札('あまつかぜくものかよひぢふきとぢよ,をとめのすがたしばしとどめむ'). 読み札('つくばねのみねよりおつるみなのがは,こひぞつもりてふちとなりぬる'). 読み札('みちのくのしのぶもぢずりたれゆゑに,みだれそめにしわれならなくに'). 読み札('きみがためはるののにいでてわかなつむ,わがころもでにゆきはふりつつ'). 読み札('たちわかれいなばのやまのみねにおふる,まつとしきかばいまかへりこむ'). 読み札('ちはやぶるかみよもきかずたつたがは,からくれなゐにみづくくるとは'). 読み札('すみのえのきしによるなみよるさへや,ゆめのかよひぢひとめよくらむ'). 読み札('なにはがたみじかきあしのふしのまも,あはでこのよをすぐしてよとや'). 読み札('わびぬればいまはたおなじなにはなる,みをつくしてもあはむとぞおもふ'). 読み札('いまこむといひしばかりにながつきの,ありあけのつきをまちいでつるかな'). 読み札('ふくからにあきのくさきのしをるれば,むべやまかぜをあらしといふらむ'). 読み札('つきみればちぢにものこそかなしけれ,わがみひとつのあきにはあらねど'). 読み札('このたびはぬさもとりあへずたむけやま,もみぢのにしきかみのまにまに'). 読み札('なにしおはばあふさかやまのさねかづら,ひとにしられでくるよしもがな'). 読み札('をぐらやまみねのもみぢばこころあらば,いまひとたびのみゆきまたなむ'). 読み札('みかのはらわきてながるるいづみがは,つみきとてかこひしかるらむ'). 読み札('やまざとはふゆぞさびしさまさりける,ひとめもくさもかれぬとおもへば'). 読み札('こころあてにをらばやをらむはつしもの,おきまどはせるしらぎくのはな'). 読み札('ありあけのつれなくみえしわかれより,あかつきばかりうきものはなし'). 読み札('あさぼらけありあけのつきとみるまでに,よしののさとにふれるしらゆき'). 読み札('やまがはにかぜのかけたるしがらみは,ながれもあへぬもみぢなりけり'). 読み札('ひさかたのひかりのどけきはるのひに,しづごころなくはなのちるらむ'). 読み札('たれをかもしるひとにせむたかさごの,まつもむかしのともならなくに'). 読み札('ひとはいさこころもしらずふるさとは,はなぞむかしのかににほひける'). 読み札('なつのよはまだよひながらあけぬるを,くものいづこにつきやどるらむ'). 読み札('しらつゆにかぜのふきしくあきののは,つらぬきとめぬたまぞちりける'). 読み札('わすらるるみをばおもはずちかひてし,ひとのいのちのをしくもあるかな'). 読み札('あさぢふのをののしのはらしのぶれど,あまりてなどかひとのこひしき'). 読み札('しのぶれどいろにいでにけりわがこひは,ものやおもふとひとのとふまで'). 読み札('こひすてふわがなはまだきたちにけり,ひとしれずこそおもひそめしか'). 読み札('ちぎりきなかたみにそでをしぼりつつ,すゑのまつやまなみこさじとは'). 読み札('あひみてののちのこころにくらぶれば,むかしはものをおもはざりけり'). 読み札('あふことのたえてしなくはなかなかに,ひとをもみをもうらみざらまし'). 読み札('あはれともいふべき人はおもほえで,みのいたづらになりぬべきかな'). 読み札('ゆらのとをわたるふなびとかぢをたえ,ゆくへもしらぬこひのみちかな'). 読み札('やへむぐらしげれるやどのさびしきに,ひとこそみえねあきはきにけり'). 読み札('かぜをいたみいはうつなみのおのれのみ,くだけてものをおもふころかな'). 読み札('みかきもりゑじのたくひのよるはもえ,ひるはきえつつものをこそおもへ'). 読み札('きみがためをしからざりしいのちさへ,ながくもがなとおもひけるかな'). 読み札('かくとだにえやはいぶきのさしもぐさ,さしもしらじなもゆるおもひを'). 読み札('あけぬればくるるものとはしりながら,なほうらめしきあさぼらけかな'). 読み札('なげきつつひとりぬるよのあくるまは,いかにひさしきものとかはしる'). 読み札('わすれじのゆくすゑまではかたければ,けふをかぎりのいのちともがな'). 読み札('たきのおとはたえてひさしくなりぬれど,なこそながれてなほきこえけれ'). 読み札('あらざらむこのよのほかのおもひでに,いまひとたびのあふこともがな'). 読み札('めぐりあひてみしやそれともわかぬまに,くもがくれにしよはのつきかな'). 読み札('ありまやまゐなのささはらかぜふけば,いでそよひとをわすれやはする'). 読み札('やすらはでねなましものをさよふけて,かたぶくまでのつきをみしかな'). 読み札('おほえやまいくののみちのとほければ,まだふみもみずあまのはしだて'). 読み札('いにしへのならのみやこのやへざくら,けふここのへににほひぬるかな'). 読み札('よをこめてとりのそらねははかるとも,よにあふさかのせきはゆるさじ'). 読み札('いまはただおもひたえなむとばかりを,ひとづてならでいふよしもがな'). 読み札('あさぼらけうぢのかはぎりたえだえに,あらはれわたるせぜのあじろぎ'). 読み札('うらみわびほさぬそでだにあるものを,こひにくちなむなこそをしけれ'). 読み札('もろともにあはれとおもへやまざくら,はなよりほかにしるひともなし'). 読み札('はるのよのゆめばかりなるたまくらに,かひなくたたむなこそをしけれ'). 読み札('こころにもあらでうきよにながらへば,こひしかるべきよはのつきかな'). 読み札('あらしふくみむろのやまのもみぢばは,たつたのかはのにしきなりけり'). 読み札('さびしさにやどをたちいでてながむれば,いづこもおなじあきのゆふぐれ'). 読み札('ゆふさればかどたのいなばおとづれて,あしのまろやにあきかぜぞふく'). 読み札('おとにきくたかしのはまのあだなみは,かけじやそでのぬれもこそすれ'). 読み札('たかさごのをのへのさくらさきにけり,とやまのかすみたたずもあらなむ'). 読み札('うかりけるひとをはつせのやまおろしよ,はげしかれとはいのらぬものを'). 読み札('ちぎりおきしさせもがつゆをいのちにて,あはれことしのあきもいぬめり'). 読み札('わたのはらこぎいでてみればひさかたの,くもゐにまがふおきつしらなみ'). 読み札('せをはやみいはにせかるるたきがはの,われてもすゑにあはむとぞおもふ'). 読み札('あはぢしまかよふちどりのなくこゑに,いくよねざめぬすまのせきもり'). 読み札('あきかぜにたなびくくものたえまより,もれいづるつきのかげのさやけさ'). 読み札('ながからむこころもしらずくろかみの,みだれてけさはものをこそおもへ'). 読み札('ほととぎすなきつるかたをながむれば,ただありあけのつきぞのこれる'). 読み札('おもひわびさてもいのちはあるものを,うきにたへぬはなみだなりけり'). 読み札('よのなかよみちこそなけれおもひいる,やまのおくにもしかぞなくなる'). 読み札('ながらへばまたこのごろやしのばれむ,うしとみしよぞいまはこひしき'). 読み札('よもすがらものおもふころはあけやらで,ねやのひまさへつれなかりけり'). 読み札('なげけとてつきやはものをおもはする,かこちがほなるわがなみだかな'). 読み札('むらさめのつゆもまだひぬまきのはに,きりたちのぼるあきのゆふぐれ'). 読み札('なにはえのあしのかりねのひとよゆゑ,みをつくしてやこひわたるべき'). 読み札('たまのをよたえなばたえねながらへば,しのぶることのよわりもぞする'). 読み札('みせばやなをじまのあまのそでだにも,ぬれにぞぬれしいろはかはらず'). 読み札('きりぎりすなくやしもよのさむしろに,ころもかたしきひとりかもねむ'). 読み札('わがそではしほひにみえぬおきのいしの,ひとこそしらねかわくまもなし'). 読み札('よのなかはつねにもがもななぎさこぐ,あまのをぶねのつなでかなしも'). 読み札('みよしののやまのあきかぜさよふけて,ふるさとさむくころもうつなり'). 読み札('おほけなくうきよのたみにおほふかな,わがたつそまにすみぞめのそで'). 読み札('はなさそふあらしのにはのゆきならで,ふりゆくものはわがみなりけり'). 読み札('こぬひとをまつほのうらのゆふなぎに,やくやもしほのみもこがれつつ'). 読み札('かぜそよぐならのをがはのゆふぐれは,みそぎぞなつのしるしなりける'). 読み札('ひともをしひともうらめしあぢきなく,よをおもふゆゑにものおもふみは'). 読み札('ももしきやふるきのきばのしのぶにも,なほあまりあるむかしなりけり'). */ % 以下のサイトは # 問題文 # ぼく、一目惚れをしました。昨日学内ですれ違った彼女の名前、どうしても知りたいんです。いや、名前だけじゃない……!身長も体重も、彼女の全てが知りたい! # でも、僕には彼女に話しかける勇気なんてない。彼女の体重は何 kg なんだろうか...彼女の身長は何 cm くらいなんだろうか...。結局、一晩中彼女のことだけを考えてぜんぜん寝られていない。 # さすがに女性にいきなり体重を聞くのは失礼だろう。そんなことは分かっている。そんなものを聞いたりしたら、間違いなく嫌われてしまうだろう。 # 「うーむ、どうしたものか……ハッ!」 # 僕の脳内に稲妻が走った。そうだ、身長とBMI(※)を聞けばいいんだ。そうしたら体重を逆算できる。名前はもうどうでもいいや、これは名案だ。 # そうと決まれば、 身長[cm] と BMI[kg?m2] の2つの値に基づいて 体重[kg] を逆算してくれるプログラムを有能プログラマーである君に作ってもらいたい。 # # # ※ BMI[kg?m2] とは、ボディマス指数と呼ばれるもので、以下の計算式で与えられる。ただし、Height と Weight はそれぞれ身長と体重のことである。 # # 入力 # 入力は以下の形式で標準入力から与えられる。 # # Height BMI # Height(120.0≦Height≦200.0) は、プログラムに与えられる身長[cm]を表す実数である。小数点第 1 位まで与えられる。 # BMI(10.0≦BMI≦40.0) は、プログラムに与えられる BMI[kg?m2] を表す実数である。小数点第 1 位まで与えられる。 # 出力 # 入力に基づいて逆算した 体重 [kg] を一行に出力せよ。 # 出力は絶対誤差が 10−2 以下であれば許容される。 # なお、出力の最後には改行を入れること。 'ぼく、一目惚れをしました。昨日学内ですれ違った彼女の名前、どうしても知りたいんです。いや、名前だけじゃない……!身長も体重も、彼女の全てが知りたい! でも、僕には彼女に話しかける勇気なんてない。彼女の体重は何 kg なんだろうか...彼女の身長は何 cm くらいなんだろうか...。結局、一晩中彼女のことだけを考えてぜんぜん寝られていない。 さすがに女性にいきなり体重を聞くのは失礼だろう。そんなことは分かっている。そんなものを聞いたりしたら、間違いなく嫌われてしまうだろう。 「うーむ、どうしたものか……ハッ!」 僕の脳内に稲妻が走った。そうだ、身長とBMI(※)を聞けばいいんだ。そうしたら体重を逆算できる。名前はもうどうでもいいや、これは名案だ。' :- 標準入力から身長とBMIを得る(_身長,_BMI), '身長[cm] と BMI[kg?m2] の2つの値に基づいて 体重[kg] を逆算する'(_身長,_BMI,_体重), format('~1f\n',[_体重]). 標準入力から身長とBMIを得る(_身長,_BMI) :- 文字列を得る(_文字列), split(_文字列,[' '],[_身長文字列,_BMI文字列]), get_term_from_atom(_身長文字列,_身長,[]), get_term_from_atom(_BMI文字列,_BMI,[]). '身長[cm] と BMI[kg?m2] の2つの値に基づいて 体重[kg] を逆算する'(_身長,_BMI,_体重) :- '身長[cm] と BMI[kg?m2] の2つの値に基づいて 体重[kg] を逆算する'(0,_身長,_BMI,_体重_BMIとの差ならび), 'BMIの計算差が最小のものの体重'(_体重_BMIとの差ならび,_体重). '身長[cm] と BMI[kg?m2] の2つの値に基づいて 体重[kg] を逆算する'(2000,_身長,_BMI,[]) :- !. '身長[cm] と BMI[kg?m2] の2つの値に基づいて 体重[kg] を逆算する'(N,_身長,_BMI,[[N,_BMI_の計算差]|R]) :- '身長、体重から、BMIの計算差を得る'(N,_身長,_BMI,N_2,_体重,_BMIの計算差), '身長[cm] と BMI[kg?m2] の2つの値に基づいて 体重[kg] を逆算する'(N_2,_身長,_BMI,R). '身長、体重から、BMIの計算差を得る'(N,_身長,_BMI,N_2,_体重,_BMIの計算差) :- _BMIの計算差 is abs((N / 10) / ((_身長 / 100) ^ 2)) - _BMI), succ(N,N_2), _体重 is N / 10. 'BMIの計算差が最小のものの体重'(_N_BMIとの差ならび,_体重) :- select([_体重,_BMIの差],_N_BMIとの差ならび,R), forall(member([_,_BMIの差_1],R),_BMIの差 =< _BMIの差_1). 文字列を得る(_文字列) :- findall(_文字,(repeat,get_char(_文字),(_文字=end_of_file,!,fail;_文字='\n',!,fail;true)),L), atomic_list_concat(L,_文字列). 文字列を区切り文字列で分ける(_文字列,_区切り文字列候補,[_前文字列|R]) :- 文字列を区切り文字列候補で前文字列と後文字列に分ける(_文字列,_区切り文字列候補,_前文字列,_区切り文字列,_後文字列), 文字列を区切り文字列で分ける(_後文字列,_区切り文字列候補,R),!. 文字列を区切り文字列で分ける(_文字列,_,[_文字列]). 文字列を区切り文字列候補で前文字列と後文字列に分ける(_文字列,_区切り文字列候補,_前文字列,_区切り文字列,_後文字列) :- 文字列の先頭から区切り文字列を捜す(_文字列,_区切り文字列候補,_区切り文字列,S,R), 前文字列と後文字列に分ける(_文字列,S,R,_前文字列,_後文字列). 文字列の先頭から区切り文字列を捜す(_文字列,_区切り文字列候補,_区切り文字列,S,R) :- sub_atom(_文字列,S,Len,R,_区切り文字列), member(_区切り文字列,_区切り文字列候補). 前文字列と後文字列に分ける(_文字列,S,R,_前文字列,_後文字列) :- sub_atom(_文字列,0,S,_,_前文字列), sub_atom(_文字列,_,R,0,_後文字列),!. % 以下のサイトは 攪乱順列(_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). % 以下のサイトは # 出典: プログラミングのお題スレ Part4 #674 # あなた(霧島京子) は20万人月の巨大なプロジェクトを一ヶ月で終わらせるために無数の下請け会社から人員をかき集める仕事をすることになりました。 # プロジェクトを終わらせるのに必要な人員数 m 名 と、発注可能な下請け会社の数 n 社、各下請け会社のアサイン可能なエンジニア人員数 q_i 名 と、発注に必要な費用 r_i 万円が与えられます。 # # 各下請け会社の人員は、一部を使うなどは出来ず全員を使わなくてはいけません。 # プロジェクトに必要な人員数 m 以上を満たせる組み合わせで、最も安くすむ合計金額(単位:万円)を出力してください。 # 各下請け会社の人員数の合計はプロジェクトの規模 m 人月以上になるものとします。 # ヒントを見る # ※ 実際のプロジェクトではこの様には行きませんので、人員を増やす場合は慎重に検討する事をお勧めいたします。 # ※この物語はフィクションであり、実在の人物・団体とは一切関係ありません # # # # 入力される値 # 入力は以下のフォーマットで与えられます。 # # m (プロジェクトに必要な人員数) # n (下請け会社の数) # q_1 r_1 (1番目の下請け会社の人員数 発注に必要な費用[単位:万円]) # q_2 r_2 (2番目の下請け会社の人員数 発注に必要な費用[単位:万円]) # ・・・ # q_i r_i (n 番目の下請け会社の人員数 発注に必要な費用[単位:万円]) # 条件 # 1 ≦ m ≦ 200000(プロジェクトに必要な人数:最大20万人) # 1 ≦ n ≦ 50(下請け会社数:最大50社) # 1 ≦ q_i ≦ 10000(各下請け会社の人員数:最大1万人) # 1 ≦ r_i ≦ 5000000(各下請け会社のへの発注費用[単位:万円]:1万円〜最大500億円) # m ≦ q_1 + q_2 + q_3 ... + q_i(各下請け会社の人員数の合計はプロジェクトに必要な人数 m 人以上になる) # 期待する出力 # 最もコストが安くなる組み合わせの総コストを出力して下さい。 # 最後は改行し、余計な文字、空行を含んではいけません。 # 入力例1 # 60 # 3 # 40 4300 # 30 2300 # 20 2400 # # # 出力例1 # 6600 # 入力例2 # 250 # 5 # 35 3640 # 33 2706 # 98 9810 # 57 5472 # 95 7790 # 出力例2 # 23072 'あなた(霧島京子) は20万人月の巨大なプロジェクトを一ヶ月で終わらせるために 無数の下請け会社から人員をかき集める仕事をすることになりました。 プロジェクトを終わらせるのに必要な人員数 m 名 と、発注可能な下請け会社の数 n 社、 各下請け会社のアサイン可能なエンジニア人員数 q_i 名 と、発注に必要な費用 r_i 万円が与えられます。 各下請け会社の人員は、一部を使うなどは出来ず全員を使わなくてはいけません。 プロジェクトに必要な人員数 m 以上を満たせる組み合わせで、 最も安くすむ合計金額(単位:万円)を出力してください。 各下請け会社の人員数の合計はプロジェクトの規模 m 人月以上になるものとします。' :- 'プロジェクトを終わらせるのに必要な人員数 m 名 と、発注可能な下請け会社の数 n 社、 各下請け会社のアサイン可能なエンジニア人員数 q_i 名 と、発注に必要な費用 r_i 万円が与えられます。'(_m,_n,_下請け人数_費用ならび), findmin(_合計金額,( 'プロジェクトに必要な人員数 m 以上を満たせる組み合わせで、 最も安くすむ合計金額(単位:万円)を'(_m,_n,_下請け人数_費用ならび,0,0,_合計人数,_合計金額)),_最も安くすむ合計金額), '出力してください。'(_最も安くすむ合計金額). 'プロジェクトを終わらせるのに必要な人員数 m 名 と、発注可能な下請け会社の数 n 社、 各下請け会社のアサイン可能なエンジニア人員数 q_i 名 と、発注に必要な費用 r_i 万円が与えられます。'(_m,_n,_下請け人数_費用ならび) :- get_split_line([' ',','],[_m,_n]), findall([_下請け人数,_費用],( between(1,_n,_), get_split_line([' ',','],[_下請け人数,_費用])),_下請け人数_費用ならび). 'プロジェクトに必要な人員数 m 以上を満たせる組み合わせで、 最も安くすむ合計金額(単位:万円)を'(_m,_n,_下請け人数_費用ならび,_合計人数,_合計金額,_合計人数,_合計金額) :- _合計人数 >= _m,!. 'プロジェクトに必要な人員数 m 以上を満たせる組み合わせで、 最も安くすむ合計金額(単位:万円)を'(_m,_n,_下請け人数_費用ならび,_合計人数_1,_合計金額_1,_合計人数,_合計金額) :- ひとつ下請け人数と費用を取り出す(_下請け人数_費用ならび,_合計人数_1,_合計金額_1,_合計人数_2,_合計金額_2,_残りならび), 'プロジェクトに必要な人員数 m 以上を満たせる組み合わせで、 最も安くすむ合計金額(単位:万円)を'(_m,_n,_残りならび,_合計人数_2,_合計金額_2,_合計人数,_合計金額). ひとつ下請け人数と費用を取り出す(_下請け人数_費用ならび,_合計人数_1,_合計金額_1,_合計人数_2,_合計金額_2,_残りならび) :- select([_下請け人数_1,_費用_1],_下請け人数_費用ならび,_残りならび), _合計金額_2 is _合計金額_1 + _費用_1, _合計人数_2 is _合計人数_1 + _下請け人数_1. '出力してください。'(_最も安くすむ合計金額) :- writef('%t万円\n',[_最も安くすむ合計金額]). % 以下のサイトは # 出題場所 :: 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). % 以下のサイトは 魔方陣(_魔方陣) :- 魔方陣の構成要素を得る(_魔方陣,Ln1,Ln2,_数ならび), 魔方陣を構成してみる(Ln1,Ln2,_数ならび,_行_列_合計,_魔方陣), 魔方陣列検査(_魔方陣,_行_列_合計). 魔方陣の構成要素を得る(_魔方陣,Ln1,Ln2,_数ならび) :- length(_魔方陣,_n), length(Ln1,_n), length(Ln2,_n), _n掛けるn is _n * _n, findall(M,between(1,_n掛けるn,M),_数ならび). 魔方陣を構成してみる([],Ln2,_,_行の合計,[]). 魔方陣を構成してみる([_|Ln1],Ln2,_数ならび_1,_行の合計,[L|R]) :- 魔方陣の一行を得る(Ln2,_数ならび_1,L,_数ならび_2), sum_list(L,_行の合計), 魔方陣を構成してみる(Ln1,Ln2,_数ならび_2,_行の合計,R). 魔方陣の一行を得る([],_残り数ならび,[],_残り数ならび). 魔方陣の一行を得る([_|Ln],_数ならび_1,[_n|R4],_残り数ならび) :- select(_n,_数ならび_1,_数ならび_2), 魔方陣の一行を得る(Ln,_数ならび_2,R4,_残り数ならび). 魔方陣列検査(_行列,_行_列の合計) :- 転置(_行列,_転置行列), 行の合計が全て一致する(_転置行列,_行_列の合計). 行の合計が全て一致する([],_). 行の合計が全て一致する([L|R],S) :- sum_list(L,S), 行の合計が全て一致する(R,S). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは # 出典: プログラミングのお題スレ Part4 #81 # お題:0から9のうち8種類の数字を使って4桁の10進数を2個つくり、その積をとると # 4桁の2個の数に使用した8種類の数字はひとつも現れなかった。 # この4桁の2個の10進数を求める。 '0から9のうち8種類の数字を使って4桁の10進数を2個つくり、その積をとると 4桁の2個の数に使用した8種類の数字はひとつも現れなかった。 この4桁の2個の10進数を求める。'(_4桁の10進数_1,_4桁の10進数_2) :- '0から9のうち8種類の数字を使って4桁の10進数を2個つくり、'(_8種類の数字,_4桁の10進数_1,_4桁の10進数_2), 'その積をとると4桁の2個の数に使用した8種類の数字はひとつも現れなかった。'(_8種類の数字,_4桁の10進数_1,_4桁の10進数_2). '0から9のうち8種類の数字を使って4桁の10進数を2個つくり、'(_8種類の数字,_4桁の10進数_1,_4桁の10進数_2) :- select(_残り数字_1,['0','1','2','3','4','5','6','7','8','9'],_残りならび_1), select(_残り数字_2,_残りならび_1,_8種類の数字), '4桁の10進数を2個つくり、'(_8種類の数字,_4桁の10進数_1,_4桁の10進数_2). '4桁の10進数を2個つくり、'(_8種類の数字,_4桁の10進数_1,_4桁の10進数_2) :- select(_1,_8種類の数字,R_1), select(_2,R_1,R_2), select(_3,R_2,R_3), select(_4,R_3,R_4), select(_5,R_4,R_5), select(_6,R_5,R_6), select(_7,R_6,R_7), select(_8,R_7,_), number_chars(_4桁の10進数_1,[_1,_2,_3,_4]), number_chars(_4桁の10進数_2,[_5,_6,_7,_8]), _4桁の10進数_1 >= 1023, _4桁の10進数_2 >= 1023. 'その積をとると4桁の2個の数に使用した8種類の数字はひとつも現れなかった。'(_8種類の数字,_4桁の10進数_1,_4桁の10進数_2) :- _積 is _4桁の10進数_1 * _4桁の10進数_2, '4桁の2個の数に使用した8種類の数字はひとつも現れなかった。'(_8種類の数字,_積). '4桁の2個の数に使用した8種類の数字はひとつも現れなかった。'(_8種類の数字,_積) :- number_chars(_積,_積の数字ならび), forall(member(_積に現れる数字,_積の数字ならび),\+(member(_積に現れる数字,_8種類の数字))). % 以下のサイトは 色(赤). 色(青). 色(緑). 色(黄). 区画(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). % 以下のサイトは # # 2×2の升を3色で塗り分ける。 # # _1 | _2 # ---+--- # _3 | _4 # 隣接(赤,青). 隣接(赤,白). 隣接(青,赤). 隣接(青,白). 隣接(白,赤). 隣接(白,青). 色塗り(_1,_2,_3,_4) :- '_1の隣接'(_1,_2,_3,_4), '_2の隣接'(_1,_2,_3,_4), '_3の隣接'(_1,_2,_3,_4), '_4の隣接'(_1,_2,_3,_4), '二箇所が同じ色、残り二箇所は別の色'(_1,_2,_3,_4). '_1の隣接'(_1,_2,_3,_4) :- 隣接(_1,_2), 隣接(_1,_3). '_2の隣接'(_1,_2,_3,_4) :- 隣接(_2,_1), 隣接(_2,_4). '_3の隣接'(_1,_2,_3,_4) :- 隣接(_3,_1), 隣接(_3,_4). '_4の隣接'(_1,_2,_3,_4) :- 隣接(_4,_2), 隣接(_4,_3). '二箇所が同じ色、残り二箇所は別の色'(_1,_2,_3,_4) :- '二箇所が同じ色、'(_1,_2,_3,_4,_二箇所が同じ色,_残りの色_1,_残りの色_2), '残り二箇所は別の色'(_二箇所が同じ色,_残りの色_1,_残りの色_2),!. '二箇所が同じ色、'(_1,_2,_3,_4,_二箇所が同じ色,_残りの色_1,_残りの色_2) :- select(_二箇所が同じ色,[_1,_2,_3,_4],R), select(_二箇所が同じ色,R,[_残りの色_1,_残りの色_2]). '残り二箇所は別の色'(_二箇所が同じ色,_残りの色_1,_残りの色_2) :- \+(member(_二箇所が同じ色,[_残りの色_1,_残りの色_2])), \+(_残りの色_1=_残りの色_2). % 以下のサイトは # 複数の持ち回りのタスクを、同じ人が連続しないとかの条件付きでスケヂュールしてくれるプログラム作るとしたら言語は何で作る? # あーエクセルでも出来そうだなー。なんか解の探索?みたいな問題になって、使ったことないけどLispとかPrologとかそういうプログラムで作ると良いのかなとか考えてたんだよね。 # 具体的に言えば、輪講・論文紹介・研究進捗報告、の3種のタスクを毎週こなしましょう。学生のリストがあってそれぞれ持ちまわります。ただしドクターの人は輪講はやらない。なるべく2週続けてタスクが割り振られないようにしたい。という感じですね。 # # @tonno727 具体的に言えば、輪講・論文紹介・研究進捗報告、の3種のタスクを # 毎週こなしましょう。学生のリストがあってそれぞれ持ちまわります。 # ただしドクターの人は輪講はやらない。 # なるべく2週続けてタスクが割り振られないようにしたい。という感じですね。 学生(馬場,学生). 学生(横溝,学生). 学生(円谷,ドクター). 学生(船井,学生). 学生(金井,ドクター). 学生(山内,学生). 学生(林田,学生). 学生(沢木,学生). スケジュール(_輪講回数,_論文紹介回数,_研究進捗報告回数,_スケジュール) :- 輪講者ならびを生成(_輪講者ならび), 論文紹介者ならびを生成(_論文紹介者ならび), 研究進捗報告者ならびを生成(_研究進捗報告者ならび), スケジュール(_輪講回数,_論文紹介回数,_研究進捗報告回数,[],_輪講者ならび,_論文紹介者ならび,_研究進捗報告者ならび,_スケジュール). スケジュール(0,0,0,_,_,_,_,[]) :- !. スケジュール(_輪講残り回数,_論文紹介残り回数,_研究進捗報告残り回数,_前週ならび,_輪講者,_論文紹介者,_研究進捗報告者,[[_輪講者,_論文紹介者,_研究進捗報告者]|R]) :- 輪講者候補(_輪講残り回数,_前週ならび,_輪講者ならび,_輪講残り回数_2,_輪講者,_輪講者ならび_2), 論文紹介者候補(_論文紹介残り回数,_前週ならび,_論文紹介者ならび,_論文紹介残り回数_2,_論文紹介者,_論文紹介者ならび_2), 研究進捗報告者候補(_研究進捗報告残り回数,_前週ならび,_研究進捗報告者ならび,_研究進捗報告残り回数_2,_研究進捗報告者,_研究進捗報告者ならび_2), スケジュール(_輪講残り回数_2,_論文紹介残り回数_2,_研究進捗報告残り回数_2,[_輪講者,_論文紹介者,_研究進捗報告者],_輪講者ならび_2,_論文紹介者ならび_2,_研究進捗報告報告者ならび_2,R). 輪講者候補(0,_,_,0,'',_) :- !. 輪講者候補(M,_前週ならび,[],N,_輪講者,_輪講者ならび_2) :- 輪講者ならびを生成してから候補を得る(M,_前週ならび,[],N,_輪講者,_輪講者ならび_2). 輪講者候補(M,_前週ならび,_輪講者ならび,N,_輪講者,_輪講者ならび_2) :- 現在の輪講者ならびから候補を得る(M,_前週ならび,_輪講者ならび,N,_輪講者,_輪講者ならび_2). 輪講者ならびを生成してから候補を得る(M,_前週ならび,[],N,_輪講者,_輪講者ならび_2) :- 輪講者ならびを生成(_輪講者ならび), 現在の輪講者ならびから候補を得る(M,_前週ならび,_輪講者ならび,N,_輪講者,_輪講者ならび_2). 現在の輪講者ならびから候補を得る(M,_前週ならび,_輪講者ならび,N,_輪講者,_輪講者ならび_2) :- select(_輪講者,_輪講者ならび,_輪講者ならび_2), \+(member(_輪講者,_前週ならび)), succ(N,M). 論文紹介者候補(0,_,_,0,'',_) :- !. 論文紹介者候補(M,_前週ならび,[],N,_論文紹介者,_論文紹介者ならび_2) :- 論文紹介者ならびを生成してから候補を得る(M,_前週ならび,[],N,_論文紹介者,_論文紹介者ならび_2). 論文紹介者候補(M,_前週ならび,_論文紹介者ならび,N,_論文紹介者,_論文紹介者ならび_2) :- 現在の論文紹介者ならびから候補を得る(M,_前週ならび,_論文紹介者ならび,N,_論文紹介者,_論文紹介者ならび_2). 論文紹介者ならびを生成してから候補を得る(M,_前週ならび,[],N,_論文紹介者,_論文紹介者ならび_2) :- 論文紹介者ならびを生成(_論文紹介者ならび), 論文紹介者ならびを生成してから候補を得る(M,_前週ならび,_論文紹介者ならび,N,_論文紹介者,_論文紹介者ならび_2). 現在の論文紹介者ならびから候補を得る(M,_前週ならび,_論文紹介者ならび,N,_論文紹介者,_論文紹介者ならび_2) :- select(_論文紹介者,_論文紹介者ならび,_論文紹介者ならび_2), \+(member(_論文紹介者,_前週ならび)), succ(N,M). 研究進捗報告者候補(0,_,_,0,'',_) :- !. 研究進捗報告者候補(M,_前週ならび,[],N,_研究進捗報告者,_研究進捗報告者ならび_2) :- 研究進捗報告者ならびを生成してから候補を得る(M,_前週ならび,[],N,_研究進捗報告者,_研究進捗報告者ならび_2). 研究進捗報告者候補(M,_前週ならび,_研究進捗報告者ならび,N,_研究進捗報告者,_研究進捗報告者ならび_2) :- 現在の研究進捗報告者ならびから候補を得る(M,_前週ならび,_研究進捗報告者ならび,N,_研究進捗報告者,_研究進捗報告者ならび_2). 研究進捗報告者ならびを生成してから候補を得る(M,_前週ならび,[],N,_研究進捗報告者,_研究進捗報告者ならび_2) :- 研究進捗報告者ならびを生成(_研究進捗報告者ならび), 現在の研究進捗報告者ならびから候補を得る(M,_前週ならび,_研究進捗報告者ならび,N,_研究進捗報告者,_研究進捗報告者ならび_2). 現在の研究進捗報告者ならびから候補を得る(M,_前週ならび,_研究進捗報告者ならび,N,_研究進捗報告者,_研究進捗報告者ならび_2) :- select(_研究進捗報告者,_研究進捗報告者ならび,_研究進捗報告者ならび_2), \+(member(_研究進捗報告者,_前週ならび)), succ(N,M). 輪講者ならびを生成(_輪講者ならび) :- findall(_学生,( 学生(_学生,_クラス), \+(_クラス = ドクター)), _輪講者ならび). 論文紹介者ならびを生成(_論文紹介者ならび) :- findall(_学生,学生(_学生,_),_論文紹介者ならび). 研究進捗報告者ならびを生成(_研究進捗報告者ならび) :- findall(_学生,学生(_学生,_),_研究進捗報告者ならび). % 以下のサイトは # 出典: プログラミングのお題スレ Part3 #729 # # お題:○×ゲームで○が勝つ局面までの手順を深さ優先探索ですべて探し出して出力。手順の重複は認めない。 # 勝ち((1,1),(1,2),(1,3)). 勝ち((2,1),(2,2),(2,3)). 勝ち((3,1),(3,2),(3,3)). 勝ち((1,1),(2,1),(3,1)). 勝ち((1,2),(2,2),(3,2)). 勝ち((1,3),(2,3),(3,3)). 勝ち((1,1),(2,2),(3,3)). 勝ち((1,3),(2,2),(3,1)). '○×ゲーム'(_勝ち,_着手ならび) :- 交互着手([(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)],○,×,[],[],_勝ち,_着手ならび). 交互着手(_,_,_手番,_,L2,_手番,[]) :- 勝ち(L2),!. 交互着手(_着手可能点,_手番,_次の手番,L1,L2,_勝ち,[_着手|_着手ならび]) :- select(_着手,_着手可能点,_残り着手可能点), 交互着手(_残り着手可能点,_次の手番,_手番,L2,[_着手|L1],_勝ち,_着手ならび). 勝ち(L) :- 勝ち(A,B,C), member(A,L), member(B,L), member(C,L). % 以下のサイトは 覆面算(kadokawa+dwango+kada=kandouii,N1+N2+N3=N4,_文字と数字の対応) :- 覆面(kadokawa+dwango+kada=kandouii,L0_1,L0_2,L0_3,L1,L2,L3,L4), 覆面算(L0_3,L0_2), 覆面算計算(L1,L2,L3,L4,N1,N2,N3,N4), 文字と数字の対応(L0_1,L0_2,_文字と数字の対応). 覆面(A_1+A_2+A_3=A_4,L0_1,L0_2,L0_3,L1,L2,L3,L4) :- 文字出現順の決定([A_1,A_2,A_3,A_4],L0_1), findall(N,between(1,9,_),L0_2), L0_3 = ['1','2','3','4','5','6','7','8','9','0'], 覆面文字と変数の対応付け(L0_1,L0_2,A_1,A_2,A_3,A_4,L1,L2,L3,L4). 文字出現順の決定(L,L0_1) :- atomic_list_concat(L,A), atom_chars(A,Chars), 唯一の文字ならびを得る(Chars,L0_1). 要素に重複のない文字ならび(_文字ならび,_要素に重複のない文字ならび) :- findall(_文字,( append(L1,[_文字|_],_文字ならび), \+(member(_文字,L1))), _要素に重複のない文字ならび). 数式の対応付け(L0_1,L0_2,A_1,A_2,A_3,A_4,L1,L2,L3,L4) :- 数式の対応付け(L0_1,L0_2,A_1,L1), 数式の対応付け(L0_1,L0_2,A_2,L2), 数式の対応付け(L0_1,L0_2,A_3,L3), 数式の対応付け(L0_1,L0_2,A_4,L4). 覆面文字と変数の対応付け(L0_1,L0_2,_覆面文字列,_変数ならび) :- atom_chars(_覆面文字列,_覆面文字ならび), findall(V,( nth1(_nth1,_覆面文字ならび,_文字), nth1(_nth1,L0_1,_文字), nth1(_nth1,L0_2,V)), _変数ならび). 覆面算計算(L1,L2,L3,L4,N1,N2,N3,N4) :- number_chars(N1,L1), number_chars(N2,L2), number_chars(N3,L3), number_chars(N4,L4), N1 + N2 + N3 =:= N4. 覆面算(_,[]). 覆面算(L,[A|R2]) :- select(A,L,R), 覆面算(R,R2). 文字と数字の対応(L0_1,L0_2,_文字と数字の対応) :- findall(A=B,( nth1(_nth1,L0_1,A), nth1(_nth1,L0_2,B)), _文字と数字の対応). 唯一の文字ならびを得る([],[]). 唯一の文字ならびを得る([A|R1],[A|R2]) :- \+(member(A,R1)), 唯一の文字ならびを得る(R1,R2). 唯一の文字ならびを得る([A|R1],R2) :- member(A,R1), 唯一の文字ならびを得る(R1,R2). % 以下のサイトは # 出典: SQL質疑応答スレ 14問目 #934 # たとえばですがある大会で1位3P・2位2P・3位1P・4位以下は0Pという風な加点があって # それぞれのチームの競技結果がデータとしてあるとします # # というわけでテーブル # ・競技結果 # 順位,チームコード,競技コード # ・加点 # 順位,得点 # ・チーム # チーム名,チームコード # # このとき大会後の各チームの総得点とチーム名を出力させたいわけですが0点のチームがうまく出せません # # select チーム名, sum(得点) as 総得点 # from (チーム join 競技結果 using (チームコード)) join 加点 using (順位) # where 順位 <= 3 # group by チーム名, チームコード # # こうすると総得点が0点のチームはチーム名すら出なくなってしまうわけですが上手い方法はありませんか? 競技結果(3,1,16,13). 競技結果(8,2,16,7). 競技結果(4,1,3,6). 競技結果(2,2,3,10). 競技結果(1,1,1,8). チーム(雨夜の星座,1). チーム(消えた蠍,2). 'ある大会で1位3P・2位2P・3位1P・4位以下は0Pという風な加点があって、それぞれのチームの競技結果から加算された総得点とチーム名を求める'(_総得点,_チーム名) :- チーム(_チーム名,_チームコード), 総得点(_チームコード,_総得点). 総得点(_チームコード,_総得点) :- findsum(_加算された得点,( 競技結果(_順位,_チームコード,_競技コード,_得点), 加算された得点(_順位,_得点,_加算された得点)),_総得点). 加算された得点(_順位,_得点,_加算された得点) :- 加点(_順位,_加点), _加算された得点 is _得点 + _加点. 加点(1,3) :- !. 加点(2,2) :- !. 加点(3,1) :- !. 加点(_,0). findsum(A,P,Sum) :- findall(A,P,L), sum_list(L,Sum). % 以下のサイトは # 出典 :: 「受験全解算数」日能研発行 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). % 以下のサイトは # 出典 :: SQL質疑応答スレ14問目 #890 # 質問させてください。MySQLです。 # 上位100件を抽出してその中から10件をランダムに抽出したい。 # SELECT文はどう書けばいいですか?1行でできますか? '上位100件を抽出してその中から10件をランダムに抽出したい。'(_10件をランダムに抽出) :- 上位100件を抽出して(_上位100件), 'その中から10件をランダムに抽出したい。'(_上位100件,_10件をランダムに抽出). '上位100件を抽出して'(_上位100件) :- findall(_値,テーブル(_値),_値ならび), 上位100件(_値ならび,_上位100件). 上位100件(_値ならび,_上位100件) :- length(_上位100件,100), 降順整列して先頭から100件(_値ならび,_上位100件). 降順整列して先頭から100件(_値ならび,_上位100件) :- 降順整列(_値ならび,_降順整列した値ならび), append(_上位100件,_,_降順整列した値ならび). 'その中から10件をランダムに抽出したい。'(_上位100件,_10件をランダムに抽出) :- findnsols(10,'ランダムに抽出したい。'(_上位100件,_10件をランダムに抽出),!. 'ランダムに抽出したい。'(_値ならび,_選択値) :- random_select(_選択値_1,_値ならび,_残りならび), 'ランダムに抽出したい。'(_選択値_1,_残りならび,_選択値). 'ランダムに抽出したい。'(_選択値,_,_選択値). 'ランダムに抽出したい。'(_,_残りならび,_選択値) :- 'ランダムに抽出したい。'(_残りならび,_選択値). 降順整列(L1,L2) :- 降順整列(L1,L2,[]). 降順整列([],L,L). 降順整列([A|R],L,L3) :- 降順分割(A,R,L1,L2), 降順整列(L1,L,[A|L4]), 降順整列(L2,L4,L3). 降順分割(_,[],[],[]). 降順分割(A,[B|R],[B|L1],L2) :- B @> A, 降順分割(A,R,L1,L2). 降順分割(A,[B|R],L1,[B|L2]) :- B @=< A, 降順分割(A,R,L1,L2). % 以下のサイトは # 出典 :: プログラミングのお題スレ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). % 以下のサイトは # 質問です。 # MySQL5です。 # テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。 # 各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。 # 言っていることが、よくわからなくてすみません。 # # 元テーブル # DATE, CODE, VALUE # .... # 20140401, 11, A # 20140402, 12, B # 20140403, 11, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # .... # # 欲しい結果 # 20140401, 11, A # 20140403, 11, C # 20140406, 11, F # 20140402, 12, B # 20140405, 12, E # 20140404, 13, D # # 宜しくお願い致します。 # # # 879 名前:NAME IS NULL [sage]: 2014/04/25(金) 17:41:21.67 ID:??? # >>877 # どうも質問が明確じゃないけど、 # insert into tname select 〜 # の形式にすればとりあえず解決しそうな話に見える。 # # >>878 # order by code, date ということ? # # # 880 名前:NAME IS NULL []: 2014/04/25(金) 17:47:38.30 ID:+Fb19Efw (3) # 879 # 分かりずらい # 欲しい結果にしてしまいました。 # # 第1キーは、日付です。 # # 元テーブル # DATE, CODE, VALUE # 20140401, 13, A # 20140402, 11, B # 20140403, 12, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # # 欲しい結果 # 20140401, 13, A # 20140404, 13, D # 20140402, 11, B # 20140406, 11, F # 20140403, 12, C # 20140405, 12, E # # 宜しくお願い致します。 # # # 要するに第一キーは降順、第二キーは昇順で整列する。 # 'テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。'(_DATE,_CODE,_VALUE) :- '要するに第一キーは降順、第二キーは昇順で整列する。'(L1,_第一番目の日付ならび), 情報を取り出す(_第一番目の日付ならび,L1,_DATE,_CODE,_VALUE). '要するに第一キーは降順、第二キーは昇順で整列する。'(L1,_第一番目の日付ならび) :- 第一キー順序(_逆順コードならび), setof(_第一番目の日付, [_CODE,_第一番目の日付] ^ ( 'CODEを取り出す'(_逆順コードならび,_CODE), 第二キー順序(_CODE,_,_第一番目の日付)),_第一番目の日付ならび). 第一キー順序(_逆順コードならび) :- setof(_CODE,[_DATE,_CODE,_VALUE] ^ 元テーブル(_DATE,_CODE,_VALUE),L1), reverse(L1,_逆順コードならび). 逆順に整列して取り出す(_逆順コードならび,_CODE) :- member(_CODE,_逆順コードならび). 第二キー順序(_CODE,[_第一番目の日付|R],_第一番目の日付) :- setof(_DATE,[_DATE,_CODE,_VALUE] ^ 元テーブル(_DATE,_CODE,_VALUE),[_第一番目の日付|R]). 情報を取り出す(_第一番目の日付ならび,_逆順コードならび,_DATE,_CODE,_VALUE) :- member(_DATE_1,_第一番目の日付ならび), 'CODEを決める'(_逆順コードならび,_DATE_1,_CODE), 元テーブル(_DATE,_CODE,_VALUE). 'CODEを決める'(_逆順コードならび,_DATE_1,_CODE) :- member(_CODE,_逆順コードならび), setof(_DATE,[_DATE,_VALUE] ^ 元テーブル(_DATE,_CODE,_VALUE),[_DATE_1|_]). % 以下のサイトは ぶどうの房パズル([[_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/282 # お題:1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。 # のこりの数からとりのぞいた2個の数を求める。 # 例 # 3,1,2,6 -> 4,5 # # '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。 のこりの数からとりのぞいた2個の数を求める。'(_n,_とりのぞいた数_1,_とりのぞいた数_2) :- '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。'(_n,_2個をとりのぞいたのこりの数), 'のこりの数からとりのぞいた2個の数を求める。'(1,_2個をとりのぞいたのこりの数,[],[_とりのぞいた数_1,_とりのぞいた数_2]). '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。'(_n,_2個をとりのぞいたのこりの数) :- '1からnのn個の連続した整数を'(_n,_1からnのn個の連続した整数), シャッフルして(_n,_1からnのn個の連続した整数,_シャッフルした1からnのn個の連続した整数), '適当に選んだ2個をとりのぞく。'(_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数). '1からnのn個の連続した整数を'(_n,_1からnのn個の連続した整数) :- findall(M,between(1,_n,M),_1からnのn個の連続した整数). シャッフルして(_n,L1,L2) :- シャッフルして(1000,_n,L1,L2),!. シャッフルして(0,_,L,L). シャッフルして(M,_n,L1,L) :- R is random(_n) + 1, select(R,L1,L2), M_1 is M - 1, シャッフルして(M_1,_n,[R|L2],L). '適当に選んだ2個をとりのぞく。'(_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数) :- _シャッフルした1からnのn個の連続した整数=[_,_|_2個をとりのぞいたのこりの数]. 'のこりの数からとりのぞいた2個の数を求める。'(_,_,L,L) :- length(L,2),!. 'のこりの数からとりのぞいた2個の数を求める。'(_n,L1,L2,L) :- select(_n,L1,L1_2),!, _n_2 is _n + 1, 'のこりの数からとりのぞいた2個の数を求める。'(_n_2,L1_2,L2,L). 'のこりの数からとりのぞいた2個の数を求める。'(_n,L1,L2,L) :- _n_2 is _n + 1, 'のこりの数からとりのぞいた2個の数を求める。'(_n_2,L1,[_n|L2],L). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/tech/1390525149/282 # お題:1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。 # のこりの数からとりのぞいた2個の数を求める。 # 例 # 3,1,2,6 -> 4,5 # # '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。 のこりの数からとりのぞいた2個の数を求める。'(_n,_とりのぞいた数_1,_とりのぞいた数_2) :- '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。'(_n,_2個をとりのぞいたのこりの数), 'のこりの数からとりのぞいた2個の数を求める。'(1,_2個をとりのぞいたのこりの数,[],[_とりのぞいた数_1,_とりのぞいた数_2]). '1からnのn個の連続した整数をシャッフルして適当に選んだ2個をとりのぞく。'(_n,_2個をとりのぞいたのこりの数) :- '1からnのn個の連続した整数を'(_n,_1からnのn個の連続した整数), シャッフルして(_n,_1からnのn個の連続した整数,_シャッフルした1からnのn個の連続した整数), '適当に選んだ2個をとりのぞく。'(_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数). '1からnのn個の連続した整数を'(_n,_1からnのn個の連続した整数) :- findall(M,between(1,_n,M),_1からnのn個の連続した整数). シャッフルして(_n,L1,L2) :- シャッフルして(1000,_n,L1,L2),!. シャッフルして(0,_,L,L). シャッフルして(M,_n,L1,L) :- R is random(_n) + 1, select(R,L1,L2), M_1 is M - 1, シャッフルして(M_1,_n,[R|L2],L). '適当に選んだ2個をとりのぞく。'(_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数) :- 適当に選んだ2個を(_シャッフルした1からnのn個の連続した整数,[],[_数_1,_数_2]), 'とりのぞく。'(_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数). 適当に選んだ2個を(_シャッフルした1からnのn個の連続した整数,[A,B],[A,B]) :- !. 適当に選んだ2個を(_シャッフルした1からnのn個の連続した整数,L1,L) :- 適当に選んだ(_シャッフルした1からnのn個の連続した整数,_適当に選んだ数), 適当に選んだ2個を(_シャッフルした1からnのn個の連続した整数,[_適当に選んだ数|L1],L). 適当に選んだ(_シャッフルした1からnのn個の連続した整数,_適当に選んだ数) :- length(_シャッフルした1からnのn個の連続した整数,Len), R1 is random(Len), nth0(R1,_シャッフルした1からnのn個の連続した整数,_適当に選んだ数), \+(member(_適当に選んだ数,L1)),!. 適当に選んだ(_シャッフルした1からnのn個の連続した整数,_適当に選んだ数) :- 適当に選んだ(_シャッフルした1からnのn個の連続した整数,_適当に選んだ数). 'とりのぞく。'(_数_1,_数_2,_シャッフルした1からnのn個の連続した整数,_2個をとりのぞいたのこりの数) :- select(_数_1,_シャッフルした1からnのn個の連続した整数,L1), select(_数_2,L1,_2個をとりのぞいたのこりの数). 'のこりの数からとりのぞいた2個の数を求める。'(_,_,L,L) :- length(L,2),!. 'のこりの数からとりのぞいた2個の数を求める。'(_n,L1,L2,L) :- select(_n,L1,L1_2),!, _n_2 is _n + 1, 'のこりの数からとりのぞいた2個の数を求める。'(_n_2,L1_2,L2,L). 'のこりの数からとりのぞいた2個の数を求める。'(_n,L1,L2,L) :- _n_2 is _n + 1, 'のこりの数からとりのぞいた2個の数を求める。'(_n_2,L1,[_n|L2],L). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/db/1371476534/599 # こういうSQLがあって、 # select groups.name as "group", members.name as "member" # from groups # join members on groups.id = members.group_id # order by groups.id, members.id; # # 実行結果はこうなっています。 # group | member # --------------------+----------------- # 麦わら | ルフィ # 麦わら | ナミ # 麦わら | チョッパー # 木ノ葉隠れの里 | ナルト # 木ノ葉隠れの里 | カカシ # # ここで、memberに対してグループごとの連番をつけるにはどうしたらいいですか。 # 希望する出力結果はつぎのとおり # # group | num | member # --------------------+-----+-------------- # 麦わら | 1 | ルフィ # 麦わら | 2 | ナミ # 麦わら | 3 | チョッパー # 木ノ葉隠れの里 | 1 | ナルト # 木ノ葉隠れの里 | 2 | カカシ # # なおPostgres 9.2です。よろしくお願いします。 # # 'memberに対してグループごとの連番をつけるにはどうしたらいいですか。'(_group,_連番,_member) :- 'memberに対してグループごとの'(LL1), 連番を付ける(1,LL1,LL2), member([_group,_連番,_member],LL2). 'memberに対してグループごとの'(LL1) :- findall([_group,_member],( 'member.group'(_group,_member), members(_member)), LL1). 連番を付ける(_,[],[]). 連番を付ける(N,[[A,B],[A,C]|R1],[[A,N,B]|R2]) :- N_2 is N + 1, 連番を付ける(N_2,[[A,C]|R1],R2),!. 連番を付ける(N,[[A,B]|R1],[[A,N,B]|R2]) :- N_2 is N + 1, 連番を付ける(1,R1,R2). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/db/1371476534/577 # こんなSQLがあります。 # # select id, name, utime # from something # order by utime desc; # # このとき、idが、ある指定された値までは読み飛ばし、それ以降のレコードを取得するにはどうしたらいいですか。 # ポイントは、 # * id順とutime順とで順番が異なること # * ソートキーは utime だが、読み飛ばす条件は id を使っていること # # whileループなら簡単な処理ですが、SQLだとどうするのでしょうか。 # # (使用DB: PostgreSQL 9.3) # 'こんなSQLがあります。 select id, name, utime from something order by utime desc; idが、ある指定された値までは読み飛ばし、それ以降のレコードを取得する'(_指定された値,_id,_name,_utime) :- 'idが、ある指定された値までは読み飛ばし、'(_指定された値,_それ以降), それ以降のレコードを取得する(_それ以降,_id,_name,_utime). 'idが、ある指定された値までは読み飛ばし、'(_指定された値,_それ以降) :- findall([_utime,_id,_name],something(_id,_name,_utime),LL1), 降順整列(LL1,LL2), append(_,[[_,_指定された値,_]|_それ以降],LL2),!. それ以降のレコードを取得する(_それ以降,_id,_name,_utime) :- member([_utime,_id,_name],_それ以降). 降順整列([],[]). 降順整列([_軸要素|_残りならび],_降順に整列したならび) :- 軸要素より大きい要素ならびと等しいか小さい要素要素ならびに分割(_軸要素,_残りならび,_軸要素より大きい要素ならび,_軸要素に等しいか小さい要素ならび), それぞれのならびを降順に整列する(_軸要素より大きい要素ならび,_軸要素に等しいか小さい要素ならび,_降順整列ならび_1,_降順整列ならび_2), append(_降順整列ならび_1,[_軸要素|_降順整列ならび_2],_降順に整列したならび). 軸要素より大きい要素ならびと等しいか小さい要素要素ならびに分割(_軸要素,[],[],[]) :- !. 軸要素より大きい要素ならびと等しいか小さい要素要素ならびに分割(_軸要素,[A|R1],[A|R2],R3) :- A @> _軸要素, 軸要素より大きい要素ならびと等しいか小さい要素要素ならびに分割(_軸要素,R1,R2,R3). 軸要素より大きい要素ならびと等しいか小さい要素要素ならびに分割(_軸要素,[A|R1],R2,[A|R3]) :- A @=< _軸要素, 軸要素より大きい要素ならびと等しいか小さい要素要素ならびに分割(_軸要素,R1,R2,R3). それぞれのならびを降順に整列する(_軸要素より大きい要素ならび,_軸要素に等しいか小さい要素ならび,_降順整列ならび_1,_降順整列ならび_2) :- 降順整列(_軸要素より大きい要素ならび,_降順整列ならび_1), 降順整列(_軸要素に等しいか小さい要素ならび,_降順整列ならび_2),!. % 以下のサイトは # 出題場所 :: 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). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/tech/1381909900/885 # 夜分遅くに申し訳ございません… # 本日9時提出の課題を今になって気づいたのですが、私の頭ではさっぱりわからないのでお助け下さい… # # [1]プログラミングC # [2] 問題文(含コード&リンク): # 問1:以下の実行結果に示すような、3つの実数を入力した後、最大値と最小値の差を求めるプログラムを作成せよ。 # ※例 # 3つの整数を入力してください。 # na=12 # nb=65 # nc=44 # 65と12の差は53です。 # # 問2:以下の文字列(programming_jissyu)が配列に格納されているとする。 # この文字列を任意の位置で2つ分割して表示するプログラムを作成せよ。 # ※例 # 難文字目で分割しますか:11 # 文字列の前半 # programming # 文字列の後半 # _jissyu # '問1:以下の実行結果に示すような、3つの整数を入力した後、最大値と最小値の差を求めるプログラムを作成せよ。 ※例 3つの整数を入力してください。 na=12 nb=65 nc=44 65と12の差は53です。' :- '3つの整数を入力した後、'(_3つの整数), 最大値と最小値の差(_3つの整数,_最大値,_最小値,_最大値と最小値の差), writef('%tと%tの差は%tです。',[_最大値,_最小値,_最大値と最小値の差]). '3つの整数を入力した後、'(_3つの整数) :- write('3つの整数を入力してください。\n'), findall(_整数,( member(A,[na,nb,nc]), writef('%t=',[A]), 整数を得る(_整数)), _3つの整数). 最大値と最小値の差(_3つの整数,_最大値,_最小値,_最大値と最小値の差) :- 最大値(_3つの整数,_最大値), 最小値(_3つの整数,_最小値), _最大値と最小値の差 is _最大値 - _最小値. 最大値(_整数ならび,_最大値) :- select(N,_整数ならび,R), forall(member(M,R),M =< N). 最小値(_整数ならび,L_最小値) :- select(N,_整数ならび,R), forall(member(M,R),M >= N). 整数を得る(_整数) :- 一行読み込む(Line), '診断: 整数を得る'(Line,_整数),!. 整数を得る(_整数) :- 整数を得る(_整数). '診断: 整数を得る'(Line,_整数) :- read_term_from_atom(Line,_整数,[]), integer(_整数),!. '診断: 整数を得る'(Line,_整数) :- writef('入力された値"%t"から整数は得られません。再入力をお願いします。\n',[Line]), fail. 一行読み込む(_行) :- get_line(_行). get_line(Stream,X) :- get_char(Stream,C), get_line_1(Stream,C,Chars), atom_chars(X,Chars). get_line_1(Stream,'\n',[]) :- !. get_line_1(Stream,end_of_file,[e,n,d,'_',o,f,'_',f,i,l,e]) :- !. get_line_1(Stream,C,[C|R]) :- get_char(Stream,C2), get_line_1(Stream,C2,R). get_line(X) :- get_char(C), get_line_1(C,Chars), atom_chars(X,Chars). get_line_1('\n',[]) :- !. get_line_1(end_of_file,[e,n,d,'_',o,f,'_',f,i,l,e]) :- !. get_line_1(C,[C|R]) :- get_char(C2), get_line_1(C2,R). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/tech/1357191974/896 # お題:単語データファイル「words.txt」から英単語リストを読み取り、アルファベットでしりとりを行い、 # 一番長いしりとりの単語列を出力せよ。同じ単語は二度使わない。 # # '一番長いしりとりの単語列を出力せよ。同じ単語は二度使わない。'(_単語列,_一番長いしりとりの単語列) :- '同じ単語は二度使わない。'(_単語列,_整列した重複のない単語列), forall(一番長いしりとり単語列を(_整列した重複のない単語列,_一番長いしりとりの単語列),'出力せよ。'(_一番長いしりとりの単語列)). 一番長いしりとり単語列を(_整列した重複のない単語列,_一番長いしりとりの単語列) :- しりとり単語列を(_整列した重複のない単語列,_長さを鍵に持つしりとり単語列), 一番長い(_長さを鍵に持つしりとり単語列,_一番長いしりとりの単語列). しりとり単語列を(_整列した重複のない単語列,_長さを鍵に持つしりとり単語列) :- findall([_長さ,_しりとりの単語列],しりとりの単語列(_整列した重複のない単語列,_しりとりの単語列,_長さ),_長さを鍵に持つしりとり単語列). '同じ単語は二度使わない。'(_単語列,_整列した重複のない単語列) :- sort(_単語列,_整列した重複のない単語列). しりとりの単語列(_単語列,_しりとりの単語列,_長さ) :- select(_単語,_単語列,_残り単語列), しりとり(_単語,_残り単語列,[_単語],_しりとりの単語列), length(_しりとりの単語列,_長さ). しりとり(_単語,_単語列,L1,_しりとりの単語列) :- 単語列の中から単語の末尾文字と同じ先頭文字を持つ単語を捜す(_単語,_単語列,_次の単語候補,_残り単語列), しりとり(_次の単語候補,_残り単語列,[_次の単語候補|L1],_しりとりの単語列). しりとり(_,_,_しりとりの単語列,_しりとりの単語列). 単語列の中から単語の末尾文字と同じ先頭文字を持つ単語を捜す(_単語,_単語列,_単語_2,_残り単語列) :- sub_atom(_単語,_,1,0,_文字), select(_単語_2,_単語列,_残り単語列), sub_atom(_単語_2,0,1,_,_文字). 一番長い(LL,_一番長いしりとりの単語列) :- 最大値を捜す(_長さ,member([_長さ,_],LL),_一番長い), member([_一番長い,_一番長いしりとりの単語列],LL). 最大値を捜す(A,B,C) :- findall(A,B,L), 最大値(L,C). 最大値(L,C) :- select(C,L,R), forall(member(A,R),A @=< C),!. '出力せよ。'(_一番長い逆順のしりとりの単語列) :- reverse(_一番長い逆順のしりとりの単語列,_一番長いしりとりの単語列), atomic_list_concat(_一番長いしりとりの単語列,' ',_一番長いしりとりの単語列表現), writef('%t\n',[_一番長いしりとりの単語列表現]). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/db/1371476534/487 # 次のようなデータがあります。 # tozai nihon # 関東 関東 # 関西 関西 # −− 関西 # 関西 関東 # −− 関東 # −− −− # 関東 関東 # 関西 関西 # # (−−)は空のデータ # # # tozaiとnihonではtozaiが優先されます。 # 例えば、tozai=関西,nihon=関東となっていた場合、tozaiが優先されるので「関西」と見なされます。 # この条件で、関東と関西のデータがそれぞれ何件あるか調査する為に次の3つのSQL文を出しました。 # これらを一つの文にまとめたいのですが、どのようにしたらよいでしょうか? # # select count(*) from hoge where tozai='関東' or (tozai='' and nihon='関東'); # 結果=3 # # select count(*) from hoge where tozai='関西' or (tozai='' and nihon='関西'); # 結果=4 # # select count(*) from hoge where tozai='' and nihon=''; # 結果=1 # # 'tozaiとnihonではtozaiが優先されます。 例えば、tozai=関西,nihon=関東となっていた場合、tozaiが優先されるので「関西」と見なされます。 この条件で、関東と関西のデータがそれぞれ何件あるか調査する為に次の3つのSQL文を出しました。 これらを一つの文にまとめたいのですが、どのようにしたらよいでしょうか?'(_関東,_関西,_どちらでもない) :- findall([N1,N2,N3], 'hogeのtozai,nohonからhoge_tableの値をえる'(N1,N2,N3),LL), 縦列を合計する(LL,_関東,_関西,_どちらでもない). 'hogeのtozai,nohonからhoge_tableの値をえる'(N1,N2,N3) :- hoge(_tozai,_nihon), hoge_select(_tozai,_hihon,N1,N2,N3). 縦列を合計する(LL,_関東,_関西,_どちらでもない) :- 転置(LL,[L1,L2,L3]), '転置された三つの行から_関東,_関西,_どちらでもないを求める'(L1,L2,L3,_関東,_関西,_どちらでもない). '転置された三つの行から_関東,_関西,_どちらでもないを求める'(L1,L2,L3,_関東,_関西,_どちらでもない). '転置された1行目の合計が_関東となる'(L1,_関東), '転置された2行目の合計が_関西となる'(L2,_関西), '転置された3行目の合計が_どちらでもないとなる'(L3,_どちらでもない), '転置された1行目の合計が_関東となる'(L1,_関東) :- sum_list(L1,_関東). '転置された2行目の合計が_関西となる'(L2,_関西) :- sum_list(L2,_関西). '転置された3行目の合計が_どちらでもないとなる'(L3,_どちらでもない) :- sum_list(L3,_どちらでもない). hoge_select('','',0,0,1). hoge_select('',関東,1,0,0). hoge_select('',関西,0,1,0). hoge_select(関東,_,1,0,0). hoge_select(関西,_,0,1,0). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは 加算の覆面演算行列([S,E,N,D,M,O,R,E,M,O,N,E,Y],[[0,S,E,N,D],[0,M,O,R,E],[M,O,N,E,Y]]). 加算の覆面算(_覆面ならび) :- 覆面に数字を当てはめる(_覆面ならび,[1,2,3,4,5,6,7,8,9,0]), 転置した覆面演算を反転したもの(_覆面ならび,LL), 加算(0,LL). 加算(_,[]). 加算(O,[L|R]) :- append(L0,[S],L2), list_sum(L0,S0), S is S0 mod 10, S2 is S0 // 10, 加算(S2,R). 覆面に数字を当てはめる([],_). 覆面に数字を当てはめる([_変数|R1],_数字ならび) :- 変数の場合は数字ならびから一つ数字を選択する(_変数,R1,_数字ならび). 覆面に数字を当てはめる([A|R1],_数字ならび) :- 既に定数の場合は読み飛ばす(A,R1,_数字ならび). 変数の場合は数字ならびから一つ数字を選択する(_変数,R1,_数字ならび,_残り数字ならび) :- var(_変数), select(_変数,_数字ならび,_残り数字ならび), 覆面に数字を当てはめる(R1,_残り数字ならび). 既に定数の場合は読み飛ばす(A,R1,_数字ならび) :- \+(var(A)), 覆面に数字を当てはめる(R1,_数字ならび). 転置した覆面演算を反転したもの(_覆面ならび,LL) :- 加算の覆面演算行列(_覆面ならび,LL1), 転置(LL1,LL2), reverse(LL2,LL). % 以下のサイトは 'SEND + MORE = MONEY'(S,E,N,D,M,O,R,E,M,O,N,E,Y) :- 覆面に数字を当てはめる([S,E,N,D,M,O,R,Y],[1,2,3,4,5,6,7,8,9,0]), 演算は整合する(S,E,N,D,M,O,R,Y). 演算は整合する(S,E,N,D,M,O,R,Y) :- 繰り上がり足し算(D,E,0,_繰り上がり_1,Y), 繰り上がり足し算(N,R,_繰り上がり_1,_繰り上がり_2,E), 繰り上がり足し算(E,O,_繰り上がり_2,_繰り上がり_3,N), 繰り上がり足し算(S,M,_繰り上がり_3,M,O). 覆面に数字を当てはめる([],_). 覆面に数字を当てはめる([V|R1],_数字ならび) :- 'Vが変数の場合は新たな数字を整数の場合はそれを利用'(V,_数字ならび,_残り数字ならび), 覆面に数字を当てはめる(R1,_残り数字ならび). 'Vが変数の場合は新たな数字を整数の場合はそれを利用'(V,_数字ならび,_数字ならび) :- 'Vが整数の場合はそれを利用'(V). 'Vが変数の場合は新たな数字を整数の場合はそれを利用'(V,_数字ならび,_残り数字ならび) :- 'Vが変数の場合は新たな数字を'(V,_数字ならび,_残り数字ならび). 'Vが整数の場合はそれを利用'(V) :- integer(V). 'Vが変数の場合は新たな数字を'(V,_数字ならび,_残り数字ならび) :- var(V), select(V,_数字ならび,_残り数字ならび). 繰り上がり足し算(A,B,C,E,F) :- D is A + B + C, E is D // 10, F is D mod 10. % 以下のサイトは # 【 課題 】マス取りゲーム # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 期限 】11/27 24:00 # 【 Ver  】"1.7.0_45" # 【 補足 】3×3のマスに『○』と『×』を交互に入力して9マス埋まったら終了です。 # 勝ち負けはいりません 戦略なしマス取りゲーム(_手順) :- 戦略なしマス取りゲーム(○,[a1,a2,a3,b1,b2,b3,c1,c2,c3],_手順). 戦略なしマス取りゲーム(_手番,[],[]) :- !. 戦略なしマス取りゲーム(_手番,_残りマスならび,_手順) :- 空いたマスがあれば戦略なしマス取りゲームを続ける(_手番,_残りマスならび,_手順). 空いたマスがあれば戦略なしマス取りゲームを続ける(_手番,_残りマスならび,[[_手番,_マス]|_手順]) :- 手番がマスをひとつ取る(_手番,_残りマスならび,_次の手番,_マス,_ひとつマスを取られた残りマスならび), 戦略なしマス取りゲーム(_次の手番,_ひとつマスを取られた残りマスならび,_手順). 手番がマスをひとつ取る(_手番,_残りマスならび,_次の手番,_マス,_ひとつマスを取られた残りマスならび) :- マスをひとつ取る(_残りマスならび,_マス), ひとつマスを取られた残りマスならび(_マス,_残りマスならび,_ひとつマスを取られた残りマスならび), 次の手番(_手番,_次の手番). マスをひとつ取る(_残りマスならび,_マス) :- length(_残りマスならび,_残りマス数), _乱順数 is random(_残りマス数), nth0(_乱順数,_残りマスならび,_マス). ひとつマスを取られた残りマスならび(_マス,_残りマスならび,_ひとつマスを取られた残りマスならび) :- select(_マス,_残りマスならび,_ひとつマスを取られた残りマスならび). 次の手番(○,×). 次の手番(×,○). % 以下のサイトは # お題: # 例:数列[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). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1381909900/194 # # [1] 授業単元:C言語 # # [2] 問題文(含コード&リンク): # 1〜100の整数のうち「6の倍数」の個数を表示するプログラムを作成しなさい、ただし、for文とif文を用いて作成すること # 1次元配列を用いて5人分の数学の得点を100点満点で入力し、「数学の得点の最小値と最大値」を画面表示、およびファイルに書き出すプログラムを作成しなさい。ただし、書き出し用ファイル名は「sugaku.txt」にしなさい。 # # '1次元配列を用いて5人分の数学の得点を100点満点で入力し、「数学の得点の最小値と最大値」を画面表示、およびファイルに書き出すプログラムを作成しなさい。ただし、書き出し用ファイル名は「sugaku.txt」にしなさい。' :- '1次元配列を用いて5人分の数学の得点を100点満点で入力し'(_5人文の数学の得点), '「数学の得点の最小値と最大値」を'(_5人分の数学の得点,_数学得点の最小値,_数学得点の最大値), '画面表示、'(_数学得点の最小値,_数学得点の最大値), 'およびファイルに書き出すプログラムを作成しなさい。ただし、書き出し用ファイル名は「sugaku.txt」にしなさい。'(_5人分の数学の得点). '1次元配列を用いて5人分の数学の得点を100点満点で入力し'(_5人文の数学の得点) :- length(_5人分の数学の得点,5), forall(nth1(_nth1,_5人分の数学の得点,_数学の得点),整数を得る(数学の得点,(_数学の得点>=0,_数学の得点=<100),_数学の得点)). '「数学の得点の最小値と最大値」を'(_5人分の数学の得点,_数学得点の最小値,_数学得点の最大値,_数学得点の最小値,_数学得点の最大値) :- 数学の得点の最小値(_5人分の数学の得点,_数学得点の最小値), 数学の得点の最大値(_5人分の数学の得点,_数学得点の最大値). 数学の得点の最小値(_5人分の数学の得点,_数学得点の最小値) :- select(_数学得点の最小値,_5人分の数学の得点,_残りの数学の得点), forall(member(N,_残りの数学の得点),N>=_数学得点の最小値). 数学の得点の最大値(_5人分の数学の得点,_数学得点の最大値) :- select(_数学得点の最大値,_5人分の数学の得点,_残りの数学の得点), forall(member(N,_残りの数学の得点),N=<_数学得点の最大値). '画面表示、'(_数学得点の最小値,_数学得点の最大値) :- writef('数学得点の最小値 = %t\n数学得点の最大値 = %t\n',[_数学得点の最小値,_数学得点の最大値]). 'およびファイルに書き出すプログラムを作成しなさい。ただし、書き出し用ファイル名は「sugaku.txt」にしなさい。'(_5人分の数学の得点) :- open('sugaku.txt',write,Outstream), forall(nth1(_nth1,_5人分の数学の得点,_数学の得点),writef(Outstream,'%t\n',[_数学の得点])), close(Outstream). % 以下のサイトは # 【 課題 】 # 入力: 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). % 以下のサイトは # # 二つの集合が等しいかどうかの判定は、 # 二つの集合が等しい([],[]). 二つの集合が等しい([A|R1],L2) :- select(A,L2,R2), 二つの集合が等しい(R1,R2). % 以下のサイトは 要素ごとの度数を得る([],[]). 要素ごとの度数を得る(_ならび,[[_度数,_選択した要素]|R2]) :- 要素を一つ選択してその度数と残りならびをえる(_ならび,0,_度数,_選択した要素,_残りならび), 要素ごとの度数を得る(_残りならび,R2). 要素を一つ選択してその度数と残りならびをえる(L1,_度数_1,_度数,_要素,L) :- select(_要素,L1,R1), _度数_2 is _度数_1 + 1, 要素を一つ選択してその度数と残りならびをえる(R1,_度数_2,_度数,_要素,L). 要素を一つ選択してその度数と残りならびをえる(L,_度数,_度数,_,L) :- !. % 以下のサイトは # # 集合として一致するかどうか調べる # 集合として一致([],[]) :- !. 集合として一致(L1,L2) :- select(A,L1,R1), select(A,L2,R2), 集合として一致(R1,R2). select(_取り出し要素,[_取り出し要素|R],R). select(_取り出し要素, [A|R1], [A|R2]) :- select(_取り出し要素, R1, R2). % 以下のサイトは # # 「キミならどう書く 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) % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/659 # # A_table # # ID | title | keyword # ------------------- # 1 | いうえ | あいうえお # 2 | きくけ | かきくけこ # 3 | しすせ | さしすせそ # # select * from A_table where "あいうえお" like "%titel%" # # 結果を # ID 1 の "いうえ" を結果としてだしたいのですが、 # WEBで入力した文字列の中に titleの中身を like検索してヒットする物をだしたい感じです。 # # MYSQLですが、、なかなかいい方法がわからなくて・・・ # 'A_table ID | title | data ------------------- 1 | いうえ | あいうえお 2 | きくけ | かきくけこ 3 | しすせ | さしすせそ select * from A_table where "あいうえお" like "%titel%" 結果を ID 1 の "いうえ" を結果としてだしたいのですが、 WEBで入力した文字列の中に titleの中身を like検索してヒットする物をだしたい感じです。'(_WEBで入力した文字列,_ID,_title,_data) :- 'A_table'(_ID,_title,_data), sub_atom(_WEBで入力した文字列,_,_,_,_title). % 以下のサイトは # # 集約鍵の詳細化 (坂内広蔵氏による集約キーのグラフ化の研究の一部をなぞったもの) # 集約鍵の詳細化(_集約鍵ならび,_詳細化された集約鍵) :- append(_詳細化された集約鍵,_,_集約鍵ならび). % % ?- 集約鍵の詳細化([部,課,係],_詳細化された集約鍵). % % _詳細化された集約鍵 = []; % _詳細化された集約鍵 = [部]; % _詳細化された集約鍵 = [部,課]; % _詳細化された集約鍵 = [部,課,係]; % % false. % % ?- findall(L,集約鍵の詳細化([部,課,係],L),_詳細化された集約鍵ならび). % % _詳細化された集約鍵ならび = [[],[部],[部,課],[部,課,係]] % % ?- % % それでは、 % 集約鍵の詳細化とはどういう意味か。SQLを使って説明する。 ここでは社員数を把握している。 % % 集約鍵 = [] の場合、 % % select count(*) from 社員; % 336 % % % 集約鍵 = [部] の場合、 % % select 部,count(*) from 社員 group by 部; % 営業,200 % 開発,136 % % % 集約鍵 = [部,課] の場合、 % % select 部,課,count(*) from 社員 group by 部,課; % 営業,食品,112 % 営業,薬品,88 % 開発,食品,70 % 開発,薬品,60 % 開発,検査,6 % % % 集約鍵 = [部,課,係] の場合、 % % select 部,課,係,count(*) from 社員 group by 部,課,係; % 営業,食品,東東京,18 % 営業,食品,西東京,20 % 営業,食品,神奈川,20 % 営業,食品,埼玉,16 % 営業,食品,千葉,16 % 営業,食品,群馬,8 % 営業,食品,栃木,7 % 営業,食品,茨城,7 % 営業,薬品,東京,19 % 営業,薬品,神奈川,12 % <以下省略> % % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/628 # # t_guest、t_address、t_friend という3つのテーブルがあって、 # t_guestを基本にして、left joinをt_jushoとt_friendにそれぞれ仕掛けてselectのクエリを作りたいと考えています # # SELECT g.namae, a.prefecture, f.namae # FROM t_guest AS g # LEFT JOIN t_address AS a #  ON g.id = a.guestId # LEFT JOIN t_friend AS f #  ON g.id = f.guestId # WHERE g.age = 20; # # こんなイメージなんですが、ここで、t_addressに住所を登録していないguestのユーザーを検索しないようにするには # どうしたら良いんでしょうか # それぞれのテーブルのカラムへの条件付けはできるんですが、「登録していない状況」をどう表現したら良いのか # わかりません # # 't_guest、t_address、t_friend という3つのテーブルがあって、 t_guestを基本にして、left joinをt_jushoとt_friendにそれぞれ仕掛けてselectのクエリを作りたいと考えています SELECT g.namae, a.prefecture, f.namae FROM t_guest AS g LEFT JOIN t_address AS a  ON g.id = a.guestId LEFT JOIN t_friend AS f  ON g.id = f.guestId WHERE g.age = 20; こんなイメージなんですが、ここで、t_addressに住所を登録していないguestのユーザーを検索しないようにするにはどうしたら良いんでしょうか それぞれのテーブルのカラムへの条件付けはできるんですが、「登録していない状況」をどう表現したら良いのかわかりません'(_namae,_prefecture,_namae) :- t_guest(_id,g_namae), t_address(_id,_address,_prefecture), \+(_address = ''), t_friend(_id,f_namae). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/598 # # mysql 5.5 # # テーブル master # tcode # tname # lastdate # 〜 # # daily_data # select tcode,max(tdate) as maxdate # from daily_date # group by tcode; # # このdaily_dateから得られるmaxdateを使って # masterのtcodeの対応するlastdateに入れたいのですが、 # どのようにupdateを書けば良いのでしょうか? # 'daily_dateから得られるmaxdateを使ってmasterのtcodeの対応するlastdateに入れたい' :- dail_dateテーブルの構造(P1,_daily_date_tcode,_date), masterテーブルの構造(P2,_master_tcode,_lastdate), findsetof(_tcode,P1,L1), 最大日付に変更する(L1,P1,P2,_daily_date_tcode,_date,_master_tcode,_lastdate),!. daily_dateテーブルの構造(P,_tcode,_date) :- count(テーブル定義(daily_date,_,_),_アリティ), length(L,_アリティ), P =.. [daily_date|L], tcodeとdateの列位置を確定する(L,_tcode,_date),!. tcodeとdateの列位置を確定する(L,_tcode,_date),!. テーブル定義(daily_date,_nth1_tcode,tcode), テーブル定義(daily_date,_nth1_date,date), nth1(_nth1_tcode,L,_tcode), nth1(_nth1_date,L,_date),!. masterテーブルの構造(P,_tcode,_date) :- count(テーブル定義(master,_,_),_アリティ), length(L,_アリティ), P =.. [master|L], tcodeとlastdateの列位置を確定する(L,_tcode,_lastdate),!. tcodeとlastdateの列位置を確定する(L,_tcode,_date),!. テーブル定義(master,_nth1_tcode,tcode), テーブル定義(master,_nth1_lastdate,lastdate), nth1(_nth1_tcode,L,_tcode), nth1(_nth1_date,L,_lastdate),!. 最大日付に変更する(L1,P1,P2,_daily_date_tcode,_date,_master_tcode,_lastdate) :- forall(( member(_tcode,L1), findmax(_date,P1,_maxdate), lastdateの更新(_maxdate,P2,_tcode,_lastdate)), true). lastdateの更新(_maxdate,P,_tcode,_lastdate) :- retract(P), _lastdate = _maxdate, asserta(P),!. lastdateの更新(_maxdate,P,_tcode,_lastdate) :- _lastdate = _maxdate, asserta(P),!. % 以下のサイトは # 出典 :: SQL質疑応答スレ 13問目 #562 # t_all #  id/groupType/userId # t_groupA #  id/c1/c2/c3 # t_groupB #  id/c1/c2/c3 # # 以上のような3つのテーブルがあって、t_all.groupTypeの値はgroupAまたはgroupBのいずれか # かつ、t_all.userId は t_groupA.id または t_groupB.id のいずれかである構造になっています # # この状況で、t_all.idしかわかっていない時に最短で # t_all.groupType、t_all.userId と、それに付随するt_groupAの全カラムまたはt_groupBの全カラムを # 取得するにはどういうクエリ文を書いたら良いでしょうか? # # select t_all.groupType, t_all.userId from t_all where t_all.id = $id; # として、その返り値のgroupTypeとuserIdを元にif文で分けてもう一度グループのテーブルにselectをするしかないですか? # よろしくお願いします。環境はmysql5.5です # # 't_all  id/groupType/userId t_groupA  id/c1/c2/c3 t_groupB  id/c1/c2/c3 以上のような3つのテーブルがあって、t_all.groupTypeの値はgroupAまたはgroupBのいずれか かつ、t_all.userId は t_groupA.id または t_groupB.id のいずれかである構造になっています この状況で、t_all.idしかわかっていない時に最短で t_all.groupType、t_all.userId と、それに付随するt_groupAの全カラムまたはt_groupBの全カラムを 取得するにはどういうクエリ文を書いたら良いでしょうか?'(_id,_goupType,_userId,_c1,_c2,_c3) :- t_all(_id,_groupType,_userId), atomic_list_concat(['t_group',_groupType],_t_groupType), list_call([_t_groupType,_userId,_c1,_c2,_c3]). list_call(L) :- P =.. L, call(P). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/212 # # 質問です。 # 開始地点を表すカラム start_point と終了地点を表すカラム end_point があり、その距離は # ST_Distance(ST_GeographyFromText(ST_AsText(start_point)), ST_GeographyFromText(ST_AsText(end_point))) # で計算できます。 # それで、 # ・select で距離を計算するときは round() するけど # ・order by でソートする時は round() なしで(つまりfloatのまま)ソートする # ということをしたいです。 # SQLはこんな感じになるんですけど、 # select round(ST_Distance(ST_GeographyFromText(ST_AsText(start_point)), ST_GeographyFromText(ST_AsText(end_point)))) as distance # from geo_data # order by ST_Distance(ST_GeographyFromText(ST_AsText(start_point)), ST_GeographyFromText(ST_AsText(end_point))) # これだと距離の計算が二重に行われてしまい、無駄です。 # これを、距離の計算を二重に行わずに意図した通りのSQLを発行することはできますか。 # よろしくお願いします。 # 環境:PostgreSQL 9.1 # テーブル定義(geo,1,id). テーブル定義(geo,2,start_point). テーブル定義(geo,3,end_point). '開始地点を表すカラム start_point と終了地点を表すカラム end_point があり、その距離を小さい順に取り出す(距離を四捨五入)'(_start_point,_end_point,_distance) :- テーブル述語を得る(geo,[start_point,end_point],[_start_point,_end_point],P), 四捨五入しない距離で整列(P,_start_point,_end_point,L2), member([_distance_1,_start_point,_end_point],L2), 四捨五入(_distance_1,_distance). テーブル述語を得る(_テーブル名,_カラムならび,_カラム変数ならび,_テーブル述語) :- findall(_,( テーブル定義(テーブル名,_,_)), L, カラム変数ならびを得る(_テーブル名,_カラムならび,_カラム変数ならび,L), _テーブル述語 =.. [_テーブル名|L]. カラム変数ならびを得る(_テーブル名,_カラムならび,[],L) :- !. カラム変数ならびを得る(_テーブル名,[_カラム|R1],[_カラム変数|R2],L) :- テーブル定義(_テーブル名,Nth,_カラム), nth1(Nth,L,_カラム変数), カラム変数ならびを得る(_テーブル名,R1,R2,L). 四捨五入しない距離で整列(P,_start_point,_end_point,L2) :- findall([_distance,_start_point,_end_point],( _テーブル述語, _distance is _end_point - _start_point), L1), 整列(L1,L2). 四捨五入(A,B) :- B is round(A). % 以下のサイトは # 出典 :: SQL質疑応答スレ 13問目 # SQLに関して質問です。MySQL5.1.41です。 # # 【チームテーブル(team)】 # -------------------- # チームID  チーム名 # -------------------- # 1      巨人 # 2      阪神 # 3      中日 # # 【選手テーブル(player)】 # -------------------------------------- # 選手ID  チームID  選手名  背番号 # -------------------------------------- # 1     1      阿部   10 # 2     1      杉内   18 # 3     2      金本   6 # 4     2      鳥谷   1 # 5     3      岩瀬   13 # 6     3      谷繁   27 # # この条件で、各チームから背番号最少の選手を抽出するのが目的です。 # 結果イメージは、 # # ---------------------------- # チーム名  選手名  背番号 # ---------------------------- # 巨人    阿部    10 # 阪神    鳥谷    1 # 中日    岩瀬    13 # # です。SQLで # SELECT チーム名, 選手名, 背番号 FROM team LEFT JOIN player USING (チームID) WHERE MIN(背番号); # ではエラーになってしまいました。 # # ご教示宜しくお願いいたします。 # # チーム(1,巨人). チーム(2,阪神). チーム(3,中日). 選手(1,1,阿部,10). 選手(2,1,杉内,18). 選手(3,2,金本,6). 選手(4,2,鳥谷,1). 選手(5,3,岩瀬,13). 選手(6,3,谷繁,27). 各チームから背番号最少の選手を抽出する(_チーム,_選手名,_チーム最小背番号) :- チーム(_チームID,_チーム), 背番号最少の選手を抽出する(_チームID,_選手名,_チーム最小背番号). 背番号最少の選手を抽出する(_チームID,_選手名,_チーム最小背番号) :- 選手を抽出する(_チームID,_選手名,_チーム最小背番号,_残りならび), 背番号最少の(_残りならび,_チーム最小背番号). 選手を抽出する(_チームID,_選手名,_チーム最小背番号,_残りならび) :- findall([_背番号,_選手名],選手(_,_チームID,_選手名,_背番号),_背番号_選手名ならび), select([_チーム最小背番号,_選手名],_背番号_選手名ならび,_残りならび). 背番号最少の(_残りならび,_チーム最小背番号) :- forall(member([_背番号,_],_残りならび),_背番号 @>= _チーム最小背番号). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1342966104/844 # # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク): # http://ime.nu/codepad.org/DXRUGC3J # http://ime.nu/codepad.org/e9CIf3Iy # # /* # # 4. # 2次元平面上の3つの座標 p1、p2、 p3 を頂点とする # 3角形を考え、構造体 triangle を以下のように定義する。 # struct triangle { # double p1[2]; double p2[2]; double p3[2]; # }; # # 構造体 triangle に対して、以下の関数を作成せよ。 適当な構造体 triangle の変数を # いくつか作成して、この関数が正しく動作することを確認するプログラムを作成せよ。 # # int congruence (structure triangle *a, structure triangle *b) # # 三角形 a と三角形 b が合同かどうかを判定する、 # 合同なら 1 を合同でないなら 0 を返す # # */ '三角形 a と三角形 b が合同かどうかを判定する、合同なら 1 を合同でないなら 0 を返す'(_p1_a,_p2_a,_p3_a,_p1_b,_p2_b,_p3_b,1) :- 三角形の三辺を得る(_p1_a,_p2_a,_p3_a,L1), 三角形の三辺を得る(_p1_b,_p2_b,_p3_b,L2), 'L1とL2の三辺がそれぞれ等しい'(L1,L2),!. '三角形 a と三角形 b が合同かどうかを判定する、合同なら 1 を合同でないなら 0 を返す'(_,_,_,_,_,_,0). 三角形の三辺を得る((_x1,_y1),(_x2,_y2),(_x3,_y3),[_辺1,_辺2,_辺3]) :- _辺1 is sqrt((_x2 - _x1) * (_x2 - _x1) + (_y2 - _y1) * (_y2 - _y1)), _辺2 is sqrt((_x3 - _x2) * (_x3 - _x2) + (_y3 - _y2) * (_y3 - _y2)), _辺3 is sqrt((_x1 - _x3) * (_x1 - _x3) + (_y1 - _y3) * (_y1 - _y3)). 'L1とL2の三辺がそれぞれ等しい'([],[]). 'L1とL2の三辺がそれぞれ等しい'([A|R1],L2) :- select(A,L1,R1), select(A,L2,R2), 'L1とL2の三辺がそれぞれ等しい'(R1,R2). % 以下のサイトは # 出典::SQL質疑応答スレ 13問目 #154 # Oracle10g # # 企業TBL # 1:企業ID # 2:企業名 # 3:電話番号 # 4:最終発送日 # # 上記のようなテーブルがあり、同一企業でも # 複数のレコードに登録されています。 # 電話番号が同一であれば、同一企業とみなし、 # 最終発送日を同一企業内で最新の日付で # 一斉更新したいのですが、プログラムを使わず # SQL文だけで完結することは可能でしょうか? # # 下記のSQLで表示される電話番号のデータを # MAX(最終発送日)で更新するイメージです。 # # SELECT 電話番号,MAX(最終発送日),COUNT(*) # FROM 企業TBL # GROUP BY 電話番号 # HAVING COUNT(*) > 1; # '同一企業でも複数のレコードに登録されています。電話番号が同一であれば、同一企業とみなし、最終発送日を同一企業内で最新の日付で一斉更新したい' :- 電話番号ならびを得る(_電話番号ならび), 電話番号_最終発送日ならび(_電話番号ならび,_電話番号_最終発送日ならび), 最終発送日の更新(_電話番号_最終発送日ならび). 電話番号ならびを得る(_電話番号ならび) :- setof(_電話番号,[_企業ID,_企業名,_電話番号,_最終発送日] ^ ( 企業TBL(_企業ID,_企業名,_電話番号,_最終発送日)),_電話番号ならび). 電話番号_最終発送日ならび(_電話番号ならび,_電話番号_最終発送日ならび) :- findall([_電話番号,_最終発送日],( member(_電話番号,_電話番号ならび), 最終発送日(_電話番号,_最終発送日)),_電話番号_最終発送日ならび). 最終発送日(_電話番号,_最終発送日) :- findmax(_最終発送日,( 企業TBL(_企業ID,_企業名,_電話番号,_最終発送日)),_最終発送日). 最終発送日の更新(_電話番号_最終発送日ならび) :- forall(member([_電話番号,_最終発送日],_電話番号_最終発送日ならび), 最終発送日の更新(_電話番号,_最終発送日)). 最終発送日の更新(_電話番号,_最終発送日) :- 電話番号を鍵に企業データを削除(_電話番号), assertz(企業TBL(_企業ID,_企業名,_電話番号,_最終発送日)). 電話番号を鍵に企業データを削除(_電話番号) :- retract(企業TBL(_企業ID,_企業名,_電話番号,_最終発送日_1)), fail. 電話番号を鍵に企業データを削除(_電話番号). findmax(A,B,C) :- findall(A,B,L), 最大値(L,C). 最大値(L,_最大値) :- select(_最大値,L,R), forall(member(A,R),_最大値 @>= A). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1342966104/466 # # # [1] 授業単元:C言語 # [2] 問題文:プレイフェア暗号の作成 #       参考:http://ime.nu/www.tamagaki.com/math/PlayfairCipher.html # # #  プレイフェア暗号(Playfair cipher) # # プレイフェア暗号はイギリス人サー・チャールズ・ホイートストン(Sir Charles Wheatstone)により開発されライアン・プレイフェア(Lyon Playfair)が普及させました。プレイフェア暗号を用いて暗号化するとき、まずキーワードまたはキーフレーズをあらかじめ決めておきます。仮にキーワードをPlayfairとします。次にこのキーワードをアルファベットが重複することなく下の5×5の表に入れていきます。 # # ここで残りのセルに余ったアルファベットを挿入していくわけですが、アルファベットは26文字あって5×5では一字余ります。そこで I と J は同じセルに入れるとあらかじめ決めておきます。そこで新たに作られた表が下のようになります。 # # 準備ができたところで、次のメッセージを暗号化してみましょう。 # # メッセージ Abandon hope, all ye who enter here. # # このメッセージをまず二文字ずつ区切っていきます。 # # Ab-an-do-nh-op-ea-ll-ye-wh-oe-nt-er-he-re # # ここで7番目に ll と同じ文字が重複しているので間に x を入れます。 # # Ab-an-do-nh-op-ea-lx-ly-ew-ho-en-te-rh-er-e # # そうすると最後に e が一つ余ります。ここにもやはり x を入れておきます。 # # Ab-an-do-nh-op-ea-lx-ly-ew-ho-en-te-rh-er-ex # # まず最初の二文字 ab を暗号化してみましょう。ab は先ほど作った表では同じ列にあります。このときは ab の列のすぐ下の文字で置き換えます。 # # つまり ab は BH に変わります。ただし一番下の文字例えば w は一番上の文字 A に変換されます。 # # 同様に同じ行に入る二文字も出てきたとします。例えば ap などは右隣の文字に置き換えます。 # # つまり ap は YL になるわけですね。この場合も一番右の文字例えば f は一番左の文字 p に変換されます。 # # 最後に行も列も違う二文字が出てきた場合は次のようにします。例えば an を考えます。下の表のように a n それぞれの行および列を塗り分け、その交点となる文字を見ます。この場合、P と Q になります。 # # そこで a は、a h と同じ行の P に、n は、n と同じ行の Q に変換します。つまり、 # # do → RT # # nh → QE # # op → NL # # となるわけです。このルールに従って、先ほどのメッセージを暗号化すると、 # # 平文  Ab-an-do-nh-op-ea-lx-ly-ew-ho-en-te-rh-er-ex # # 暗号文 BH PQ RT QE NL HP YV AF HU GQ NU NM BG GI KU # # これでプレイフェア暗号による暗号化が終了したわけです。 # # この暗号はイギリスがボーア戦争(ブール戦争 BoreWar)で使用したといわれています。 プレイフェア暗号表の作成(_鍵文,_暗号表) :- 鍵文を25要素のならびに拡張して(_鍵文,_25要素ならび,_鍵文字以外の変数ならび), 'Jを除いたA-Zならびを切る'(_Jを除いたA_Zならび), 変数を埋める(_Jを除いたA_Zならび,Chars,_鍵文字以外の変数ならび), 'N個組'(5,_25要素のならび,_暗号表). 鍵文を25要素のならびに拡張して(_鍵文,_25要素ならび,_鍵文字ならび,_鍵文字以外の変数ならび) :- length(_25要素ならび,25), atom_chars(_鍵文,_鍵文字ならび), append(_鍵文字ならび,_鍵文字以外の変数ならび,_25要素ならび). 'A-Zならびを切る'(_Jを除いたA_Zならび) :- _切る回数 is random(113) + 1, トランプを切るようにならびを切る(_切る回数,25,['A','B','C','D','E','F','G','H','I','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'],_Jを除いたA_Zならび). 変数を埋める(_,_,[]). 変数を埋める(L_1,Chars,[V|R]) :- select(V,L_1,L_R), \+(member(V,Chars)), 変数を埋める(L_R,Chars,R). プレイフェア暗号による暗号化(_平文,_暗号文) :- メッセージをまず二文字ずつ区切っていきます(_平文,_二文字ずつに区切られたならび), プレイフェア暗号化(_二文字ずつに区切られたならび,_暗号文字ならび), atomic_list_concat(_暗号文字ならび,_暗号文). メッセージをまず二文字ずつ区切っていきます(_平文,_二文字ずつに区切られたならび) :- atom_chars(_平文,Chars), すべての文字を大文字に変換(Chars,_大文字の文字ならび), メッセージをまず二文字ずつ区切っていきます(_大文字の文字ならび,_二文字ずつに区切られたならび). メッセージをまず二文字ずつ区切っていきます([],[]). メッセージをまず二文字ずつ区切っていきます(['J'|R1],[['J','J']|R2]) :- メッセージをまず二文字ずつ区切っていきます(R1,R2). メッセージをまず二文字ずつ区切っていきます([A],[[A,'X']]). メッセージをまず二文字ずつ区切っていきます([A,A|R1],[[A,'X']|R2]) :- メッセージをまず二文字ずつ区切っていきます([A|R1],R2). メッセージをまず二文字ずつ区切っていきます([A,B|R1],[[A,B]|R2]) :- \+(A=B), メッセージをまず二文字ずつ区切っていきます(R1,R2). プレイフェア暗号化(_二文字ずつに区切られたならび,_暗号文字ならび) :- 暗号表(_暗号表), 転置(_暗号表,_転置された暗号表), プレイフェア暗号化(_二文字ずつに区切られたならび,_暗号表,_転置された暗号表,_暗号文字ならび). プレイフェア暗号化([],_,_,[]). プレイフェア暗号化([['J','J']|R1],_暗号表,_転置された暗号表,['J'|R2]) :- プレイフェア暗号化(R1,_暗号表,_転置された暗号表,R2). プレイフェア暗号化([[A,B]|R1],_暗号表,_転置された暗号表,[C,D|R2]) :- 暗号に変換(A,B,_暗号表,C,D), プレイフェア暗号化(R1,_暗号表,_転置された暗号表,R2). 暗号に変換(A,B,_暗号表,_転置された暗号表,C,D) :- member(L,_転置された暗号表), 'A,Bが暗号表の同一行または列にある'(A,B,L,C,D). 暗号に変換(A,B,_暗号表,_転置された暗号表,C,D) :- member(L,_暗号表), 'A,Bが暗号表の同一行にある'(A,B,L,C,D). 暗号に変換(A,B,_暗号表,_転置された暗号表,C,D) :- 暗号コードは矩形を仮想した時の他の二角(A,B,_暗号表,C,D). 'A,Bが暗号表の同一行または列にある'(A,B,L,C,D) :- member(A,L), member(B,L), 'A,Bの次の要素'(L,A,C), 'A,Bの次の要素'(L,B,D). 'A,Bの次の要素'(L,X,Y) :- append([Y|_],[X],L). 'A,Bの次の要素'(L,X,Y) :- append(_,[X,Y|_],L). 暗号コードは矩形を仮想した時の他の二角(A,B,_表,C,D) :- 'A,Bの行と列位置を得る'(A,B,_表,L_1,_列_A,L_2,_列_B), nth1(_列_B,L_1,C), nth1(_列_A,L_2,D). 'A,Bの行と列位置を得る'(A,B,_表,L_1,_列_A,L_2,_列_B) :- nth1(_行_A,_表,L_1), nth1(_列_A,L_1,A), nth1(_行_B,_表,L_2), nth1(_列_B,L_2,B). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1276873238/829 # # 問題 # 数独の解答が9行9列の文字列で与えられたとき正しいかどうか判定せよ。 # # '数独の解答が9行9列の文字列で与えられたとき正しいかどうか'(_文字列) :- '数独の解答が9行9列の文字列で与えられたとき'(_文字列,L), 数独の回答が正しい(L). '数独の解答が9行9列の文字列で与えられたとき'(_9行9列の文字列,L) :- atom_chars(_9行9列の文字列,Chars), 改行を取り除きながら数字列を数値ならびに変換(Chars,L). 改行を取り除きながら数字列を数値ならびに変換([],[]). 改行を取り除きながら数字列を数値ならびに変換(['\n'|R1],R2) :- 改行を取り除きながら数字列を数値ならびに変換(R1,R2). 改行を取り除きながら数字列を数値ならびに変換([A|R1],[N|R2]) :- atom_number(A,N), 改行を取り除きながら数字列を数値ならびに変換(R1,R2). 数独の回答が正しい([_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68,_69,_70,_71,_72,_73,_74,_75,_76,_77,_78,_79,_80,_81]) :- 数独診断([[_1,_2,_3,_4,_5,_6,_7,_8,_9], [_10,_11,_12,_13,_14,_15,_16,_17,_18], [_19,_20,_21,_22,_23,_24,_25,_26,_27], [_28,_29,_30,_31,_32,_33,_34,_35,_36], [_37,_38,_39,_40,_41,_42,_43,_44,_45], [_46,_47,_48,_49,_50,_51,_52,_53,_54], [_55,_56,_57,_58,_59,_60,_61,_62,_63], [_64,_65,_66,_67,_68,_69,_70,_71,_72], [_73,_74,_75,_76,_77,_78,_79,_80,_81], [_1,_10,_19,_28,_37,_46,_55,_64,_73], [_2,_11,_20,_29,_38,_47,_56,_65,_74], [_3,_12,_21,_30,_39,_48,_57,_66,_75], [_4,_13,_22,_31,_40,_49,_58,_67,_76], [_5,_14,_23,_32,_41,_50,_59,_68,_77], [_6,_15,_24,_33,_42,_51,_60,_69,_78], [_7,_16,_25,_34,_43,_52,_61,_70,_79], [_8,_17,_26,_35,_44,_53,_62,_71,_80], [_9,_18,_27,_36,_45,_54,_63,_72,_81], [_1,_2,_3,_10,_11,_12,_19,_20,_21], [_4,_5,_6,_13,_14,_15,_22,_23,_24], [_7,_8,_9,_16,_17,_18,_25,_26,_27], [_28,_29,_30,_37,_38,_39,_46,_47,_48], [_31,_32,_33,_40,_41,_42,_49,_50,_51], [_34,_35,_36,_43,_44,_45,_52,_53,_54], [_55,_56,_57,_64,_65,_66,_73,_74,_75], [_58,_59,_60,_67,_68,_69,_76,_77,_78], [_61,_62,_63,_70,_71,_72,_79,_80,_81]]). 数独診断([]) :- !. 数独診断([L|R]) :- sort(L,L1), length(L1,9), 数独診断(R). 数独([_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68,_69,_70,_71,_72,_73,_74,_75,_76,_77,_78,_79,_80,_81]) :- 数独生成([[_1,_2,_3,_4,_5,_6,_7,_8,_9], [_10,_11,_12,_13,_14,_15,_16,_17,_18], [_19,_20,_21,_22,_23,_24,_25,_26,_27], [_28,_29,_30,_31,_32,_33,_34,_35,_36], [_37,_38,_39,_40,_41,_42,_43,_44,_45], [_46,_47,_48,_49,_50,_51,_52,_53,_54], [_55,_56,_57,_58,_59,_60,_61,_62,_63], [_64,_65,_66,_67,_68,_69,_70,_71,_72], [_73,_74,_75,_76,_77,_78,_79,_80,_81], [_1,_10,_19,_28,_37,_46,_55,_64,_73], [_2,_11,_20,_29,_38,_47,_56,_65,_74], [_3,_12,_21,_30,_39,_48,_57,_66,_75], [_4,_13,_22,_31,_40,_49,_58,_67,_76], [_5,_14,_23,_32,_41,_50,_59,_68,_77], [_6,_15,_24,_33,_42,_51,_60,_69,_78], [_7,_16,_25,_34,_43,_52,_61,_70,_79], [_8,_17,_26,_35,_44,_53,_62,_71,_80], [_9,_18,_27,_36,_45,_54,_63,_72,_81], [_1,_2,_3,_10,_11,_12,_19,_20,_21], [_4,_5,_6,_13,_14,_15,_22,_23,_24], [_7,_8,_9,_16,_17,_18,_25,_26,_27], [_28,_29,_30,_37,_38,_39,_46,_47,_48], [_31,_32,_33,_40,_41,_42,_49,_50,_51], [_34,_35,_36,_43,_44,_45,_52,_53,_54], [_55,_56,_57,_64,_65,_66,_73,_74,_75], [_58,_59,_60,_67,_68,_69,_76,_77,_78], [_61,_62,_63,_70,_71,_72,_79,_80,_81]]). 数独生成([]) :- !. 数独生成([L|R]) :- 変数に数値を埋める(L), 数独生成(R). 変数に数値を埋める(L) :- 既に使われている数値は候補から外す(L,[1,2,3,4,5,6,7,8,9],_数字候補), 変数に数値を埋める(_数字候補,L). 既に使われている数値は候補から外す([],L,L). 既に使われている数値は候補から外す([V|R1],L1,L) :- var(V), 既に使われている数値は候補から外す(R1,L1,L). 既に使われている数値は候補から外す([N|R1],L1,L) :- integer(N), select(N,L1,L2), 既に使われている数値は候補から外す(R1,L2,L). 変数に数値を埋める([],[]). 変数に数値を埋める(_数字候補,[N|R]) :- integer(N), 変数に数値を埋める(_数字候補,R). 変数に数値を埋める(_数字候補,[V|R]) :- var(V), select(V,_数字候補,_残り数字候補), 変数に数値を埋める(_残り数字候補,R). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/963 # # ・DBMS名とバージョン # SQLite3 # # ・テーブルデータ # テーブル名 directory # folder   val # /contact/  index # /test/    connect # /example/  foo # /hoge/    bar # /fuga/    com # # ・欲しい結果 # 問い合わせ内容とfolderの内容が部分一致していればvalを返す # /contact/ にアクセスがあった場合はindexを返す # /contact/foo の場合もindexを返す # # ・説明 # $folder_hensuu = "%/contact/%"; # select * from directory WHERE folder LIKE $folder_hensuu # とした場合はヒットするが # # $folder_hensuu = "%/contact/hogehoge%"; # の場合はヒットしない。 # この場合はどうすれば一致判定が出来るようになりますか? # # '欲しい結果'(_検索語,_val) :- direcrory(_folder,_val), sub_atom(_folder,_,_,_,検索語). % 以下のサイトは # 出典::いろんな言語で宿題 第五編 # 問題 # # 三本のまっすぐな棒の長さ a, b, c (1<= a,b,c <=1000 の整数)が与えられたとき # 三本の棒で作ることの出来る三角形の最大面積を求めよ(計算誤差は 0.001以下とする) # 棒は切断したり曲げたりすることは出来ない # また棒の太さは十分細く無視できるものとする # '三本のまっすぐな棒の長さ a, b, c (1<= a,b,c <=1000 の整数)が与えられたとき三本の棒で作ることの出来る三角形の最大面積を求めよ(計算誤差は 0.001以下とする)棒は切断したり曲げたりすることは出来ないまた棒の太さは十分細く無視できるものとする'(_a,_b,_c,_三角形の面積) :- 最長辺の二乗が他の二辺のそれぞれの長さの二乗の和以下である(_a,_b,_c), ヘロンの公式(_a,_b,_c,_三角形の面積). '三本のまっすぐな棒の長さ a, b, c (1<= a,b,c <=1000 の整数)が与えられたとき三本の棒で作ることの出来る三角形の最大面積を求めよ(計算誤差は 0.001以下とする)棒は切断したり曲げたりすることは出来ないまた棒の太さは十分細く無視できるものとする'(_a,_b,_c,_三角形の面積) :- 最長辺の二乗が他の二辺のそれぞれの長さの二乗の和より大きい(_a,_b,_c,_最長辺,_辺_2,_辺_3), '最大面積の三角形は、長辺を直径として、頂点が円周上にある三角形つまり長編を斜辺とする直角三角形である'(_辺_2,_辺_3,_三角形の面積). 最長辺の二乗が他の二辺のそれぞれの長さの二乗の和以下である(_a,_b,_c) :- select(_最長辺,[_a,_b,_c],[_辺_2,_辺_3]), _最長辺 >= _辺_2, _最長辺 >= _辺_3, _最長辺 * _最長辺 =< _辺_2 * _辺_2 + _辺_3 * _辺_3,!. 最長辺の二乗が他の二辺のそれぞれの長さの二乗の和より大きい(_a,_b,_c,_最長辺,_辺_2,_辺_3) :- select(_最長辺,[_a,_b,_c],[_辺_2,_辺_3]), _最長辺 >= _辺_2, _最長辺 >= _辺_3, _最長辺 * _最長辺 > _辺_2 * _辺_2 + _辺_3 * _辺_3,!. ヘロンの公式(_a,_b,_c,_三角形の面積) :- _周囲の半分 is (_a + _b + _c) / 2, _三角形の面積 is sqrt(_周囲の半分 * (_周囲の半分 - _a) * (_周囲の半分 - _b) * (_周囲の半分 - _c)). '最大面積の三角形は、長辺を直径として、頂点が円周上にある三角形つまり長編を斜辺とする直角三角形である'(_辺_2,_辺_3,_三角形の面積) :- _三角形の面積 is _辺_2 * _辺_3 * 0.5. % 以下のサイトは # 出典 :: C/C++の宿題片付けます 158代目 #559 # [1] 授業単元: C言語 # [2] 問題文:文字列の全パターンを表示するプログラム # 実行結果例 # >abc # abc # acb # bca # … # 文字列の全パターンを表示する(_文字列) :- 文字列を文字ならびに変換して要素数を得る(_文字列,_文字ならび,_要素数), 文字ならびの全パターンを表示する(_文字ならび,_要素数). 文字列を文字ならびに変換して要素数を得る(_文字列,_文字ならび,_要素数) :- atom_chars(_文字列,_文字ならび), length(_文字ならび,_要素数). 文字ならびの全パターンを表示する(_文字ならび,_要素数) :- forall(全パターンを(_文字ならび,_要素数,L),表示する(L)). 全パターンを(_文字ならび,_要素数,L) :- between(1,_要素数,N), 順列(_文字ならび,N,L). 表示する(L) :- atomic_list_concat(L,S), writef('%t\n',[S]). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- select(A,Y,Z), M is N - 1, 順列(Z,M,X). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/816 # # table1 # id | name # ----------- # 0 | りんご # 1 | みかん # # table2 # no | id # ---------- # 0 | 0 # 1 | 0 # 2 | 1 # 3 | 1 # 4 | 1 # # この二つのテーブルから以下の結果を得るSQLの書き方を教えてください # id | name | num # ------------------- # 0 | りんご | 2 # 1 | みかん | 3 # # select id, name, (select count(code) from table2 as t2, table1 as t1 where t1.id=t2.code) as num from table1; # 自分で考えた↑では2行ともnumが5になってしまいました # # SELECT id, COUNT(id) # FROM table2 # GROUP BY id # # の結果と table1 を結合 # table1(0,りんご). table1(1,みかん). table2(0,0). table2(1,0). table2(2,1). table2(3,1). table2(4,1). 'table2をidで集約したテーブルにtable1を結合する'(_id,_name,_度数) :- setof(_id,[_no,_id] ^ ( table2(_no,_id)),_idならび), member(_id,_idならび), count(table2(_,_id),_度数), table1(_id,_name). % findsetof/3 % count/2 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1332279659/170 # # 円の内部(円周上を含む)に点を指定した数だけ打ちたい # それぞれの点の距離を最大化するように打つにはどうすればいい? # '原点を中心とした円内にランダムに3つの点を追加して行き、追加する毎に最短の距離の二点を取り除く'(0,_,_座標ならび,_座標ならび). '原点を中心とした円内にランダムに3つの点を追加して行き、追加する毎に最短の距離の二点を取り除く'(_試行回数,_半径,_座標ならび,_試行回数分の点を追加された座標ならび) :- 三座標を得る(_半径,X1,Y1,X2,Y2,X3,Y3), 座標ならびから最短の二座標を取り除く([[X1,Y1],[X2,Y2],[X3,Y3]|_座標ならび],_最短の二座標を取り除いた座標ならび), _試行回数_1 is _試行回数 - 1, '原点を中心とした円内にランダムに3つの点を追加して行き、追加する毎に最短の距離の二点を取り除く'(_試行回数_1,_半径,_最短の二座標を取り除いた座標ならび,_試行回数分の点を追加された座標ならび). 三座標を得る(_半径,X1,Y1,X2,Y2,X3,Y3) :- 座標点を得る(_半径,X1,Y1), 座標点を得る(_半径,X2,Y2), 座標点を得る(_半径,X3,Y3),!. 座標点を得る(_半径,X,Y) :- 座標点の位置要素(_半径,X), 座標点の位置要素(_半径,Y),!. 座標点の位置要素(_半径,_位置要素) :- M is truncate(_半径 * 1000), M_2 is M // 2, N is truncate(M), _位置要素 is (random(N+1) - M_2) / 1000. 座標ならびから最短の二座標を取り除く(_座標ならび,_最短の二座標を取り除いた座標ならび) :- findmin([_二点間の距離,[X1,Y1],[X2,Y2]],( 組み合わせ(_座標ならび,2,[[X1,Y1],[X2,Y2]]), _二点間の距離 is sqrt((X2-X1) * (X2-X1) + (Y2-Y1) * (Y2-Y1)), [_,[X1,Y1],[X2,Y2]]), ならびから一要素だけ削除([X1,Y1],_座標ならび,_座標ならびの一), ならびから一要素だけ削除([X2,Y2],_座標ならびの一,_最短の二座標を取り除いた座標ならび). ならびから一要素だけ削除(_削除する要素,_座標ならび,_一要素だけ削除されたならび) :- select(_削除する要素,_座標ならび,_一要素だけ削除されたならび),!. 可能な限り分散して円内にN個の点を打つ(N,_半径,_座標ならび) :- 円内にランダムに十分な点を打つ(N,_半径,[],L1), 最短点を持つ二座標を取り除く(L1,_座標ならび), length(_座標ならぴ,N). 円内にランダムに十分な点を打つ(N,_半径,L) :- M is 5 * N, 円内にランダムに十分な点を打つ(N,_半径,[],L). 円内にランダムに十分な点を打つ(N,_半径,L1,L) :- 座標点を得る(_半径,X,Y), N_1 is N - 1, 円内にランダムに十分な点を打つ(N_1,_半径,[[X,Y]|L1],L). 最短点を持つ二座標を取り除く(L1,L) :- 座標ならびから最短の二座標を取り除く(L1,L2), 最短点を持つ二座標を取り除くの二(L2,L). 最短点を持つ二座標を取り除くの二(L,L). 最短点を持つ二座標を取り除くの二(L2,L) :- 最短点を持つ二座標を取り除く(L2,L). % 以下のサイトは # 座標が[[X1,Y1],[X2,Y2],... [Xn,Yn]]のように保持されている。このなかで # 最も二点間の距離が近い二つの座標を取り除く述語を定義しなさい。 座標ならびから最短の二座標を取り除く(_座標ならび,_最短の二座標を取り除いた座標ならび) :- findmin([_二点間の距離,[X1,Y1],[X2,Y2]],( 組み合わせ(_座標ならび,2,[[X1,Y1],[X2,Y2]]), _二点間の距離 is sqrt((X2-X1) * (X2-X1) + (Y2-Y1) * (Y2-Y1)), [_,[X1,Y1],[X2,Y2]]), ならびから一要素だけ削除([X1,Y1],_座標ならび,_座標ならびの一), ならびから一要素だけ削除([X2,Y2],_座標ならびの一,_最短の二座標を取り除いた座標ならび). ならびから一要素だけ削除(_削除する要素,_座標ならび,_一要素だけ削除されたならび) :- select(_削除する要素,_座標ならび,_一要素だけ削除されたならび),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1276873238/602 # # 問題 # 辺の長さがa,b,c,dの四角形の面積の最大値を求めよ。 # # http://www2.ocn.ne.jp/~mizuryu/kadai5/kadai241a.htm # # 一般に, AB=a, BC=b, CD=c,DA=dの四角形ABCDの面積Sは, # http://www2.ocn.ne.jp/~mizuryu/kadai5/kadai241a.files/image006.gif # (但し,)(http://www2.ocn.ne.jp/~mizuryu/kadai5/kadai241a.files/image007.gif) # # で与えられる. # 今,a,b,c,d,pは一定だから, この四角形ABCDが最大となるのは, # http://www2.ocn.ne.jp/~mizuryu/kadai5/kadai241a.files/image012.gif のとき, すなわち, 円に内接するとき, である. # このとき http://www2.ocn.ne.jp/~mizuryu/kadai5/kadai241a.files/image013.gif # '辺の長さがa,b,c,dの四角形の面積の最大値を求める'(_a,_b,_c,_d,_辺の長さが_a_b_c_dの四角形の面積の最大値) :- findall(W,( select(D,[_a,_b,_c,_d],[A,B,C]), W is A+B+C-D), L), mult(L,X), _辺の長さが_a_b_c_dの四角形の面積の最大値 is sqrt(X) / 4. mult([],1). mult([A|R],X) :- mult(R,Y), X is A * Y. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/787 # # id5とid10という2つの情報しかないのですが # id5がもつc1とid10がもつc1を交換するとき # どういうクエリーをかけばよいでしょうか? # # 1.select c1 from t where id=5 or id=10 order by id # 2.begin transaction # 3.update t set c1=? where id=5 (?は1でとったid10のc1値) # 4.update t set c1=? where id=10 (?は1でとったid5のc1値) # 5.commit # # 自分の能力ではこんな手順が限界ですが # サブクエリーを駆使したらupdate1文でいけたりするのでしょうか? # もしできたらどんな感じの文になるか教えていただきたいです # 'id5とid10という2つの情報しかないのですがid5がもつc1とid10がもつc1を交換する' :- '引数の数,c1の位置,idの位置'(_引数の数,_c1の位置,_idの位置), idが5の処理(_引数の数,_c1の位置,_idの位置), idが10の処理(_引数の数,_c1の位置,_idの位置), 交換する(L0_1,L0_2,R1,R2). '引数の数,c1の位置,idの位置'(_引数の数,_c1の位置,_idの位置) :- findmax(_位置,( テーブル定義(t,_位置,_), _引数の数), テーブル定義(t,_c1の位置,c1), テーブル定義(t,_idの位置,id). idが5の処理(_引数の数,_c1の位置,_idの位置,L0_1,R1) :- 'idが5のデータを一旦削除する'(_引数の数,_c1の位置,_idの位置,L1), 'L1をc1の前と後に分解'(L1,L0_1,R1). idが5のデータを一旦削除する(_引数の数,_c1の位置,_idの位置,L1) :- length(L1,_引数の数), P =.. [t|L1], nth1(_c1の位置,L1,_c1_1), nth1(_idの位置,L1,5), retract(P). idが10の処理(_引数の数,_c1の位置,_idの位置,L0_2,R2) :- idが10のデータを一旦削除する(_引数の数,_c1の位置,_idの位置,L2), 'L1をc1の前と後に分解'(L2,L0_2,R2). idが10のデータを一旦削除する(_引数の数,_c1の位置,_idの位置,L2) :- length(L2,_引数の数), P =.. [t|L2], nth1(_c1の位置,L2,_c1_2), nth1(_idの位置,L2,10), retract(P). 'L1をc1の前と後に分解'(L1,L0_1,R1) :- length([_|L0_1],_c1の位置), append(L0_1,[A|R1],L1). 交換して定義する(L0_1,L0_2,R1,R2) :- append(L0_1,[B|R1],L1), append(L0_2,[A|R2],L2), P_1 =.. [t|L1], P_2 =.. [t|L2], asserta(P_1), asserta(P_2). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/763 # # A Table # a1 a2 # -- -- # 1 A # 3 B # 5 C # 6 D # # B Table # b1 b2 # -- -- # 2 E # 4 F # 6 G # # を select で # a1 a2 b1 b2 # -- -- -- -- # 1 A null null # 3 B 2 E # 5 C 4 F # 6 D 6 G # # にしたいけど、どうしたらいいでしょうか? 'A テーブルの_a1をキーに、B テーブルの_b1が_aに等しいか最も近い小さな値である組と結合する。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める' :- 'A テーブルの_a1をキーに'(_a1,_a2), 'B テーブルの_b1が_aに等しいか最も近い小さな値である組と結合する。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める'(_a1,_b1_b2). 'A テーブルの_a1をキーに'(_a1,_a2) :- 'A テーブル'(_a1,_a2). 'B テーブルの_b1が_aに等しいか最も近い小さな値である組と結合する。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める'(_a1,_b1_b2) :- setof(_b1,[_b1,_b2,_a1] ^ ( 'B Table'(_b1,_b2), _b1 @=< _a1),L1), 'Lの最大値から_b1,_b2を見つける。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める'(L1,B1,B2). 'Lの最大値から_b1,_b2を見つける。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める'([],'','') :- !. 'Lの最大値から_b1,_b2を見つける。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める'(L,B1,B2) :- findmax(B1,( member(B1,L)),MaxB1), findmax([MaxB1,B2],( 'B Table'(MaxB1,B2)),[B1,B2]). % findmax/3 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/763 # # A Table # a1 a2 # -- -- # 1 A # 3 B # 5 C # 6 D # # B Table # b1 b2 # -- -- # 2 E # 4 F # 6 G # # を select で # a1 a2 b1 b2 # -- -- -- -- # 1 A null null # 3 B 2 E # 5 C 4 F # 6 D 6 G # # にしたいけど、どうしたらいいでしょうか? 'A Table \n a1 a2 \n -- -- \n 1 A \n 3 B \n 5 C \n 6 D \n B Table \n b1 b2 \n -- -- \n 2 E \n 4 F \n 6 G \n を \n a1 a2 b1 b2 \n -- -- -- -- \n 1 A null null \n 3 B 2 E \n 5 C 4 F \n 6 D 6 G にしたい'(_a1,_a2,_b1,_b2) :- 'A テーブルの_aをキーにB テーブルの_b1が_aに等しいか最も近い小さな値である組と結合する。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める'. 'A テーブルの_aをキーにB テーブルの_b1が_aに等しいか最も近い小さな値である組と結合する。ただし対象組が見つからない時はBテーブルの二つのフィールドはnullで埋める' :- 'A Table'(_a1,_a2), 'B Table の中で _b1 の値が _a1 に等しいか最も近い組'(_a1,_b1,_b2). 'B Table の中で _b1 の値が _a1 に等しいか最も近い組'(_a1,B1,B2) :- setof(_b1,[_b1,_b2,_a1] ^ ( 'B Table'(_b1,_b2), _b1 @=< _a1),L1), '_b1の最大値'(L1,B1,B2). '_b1の最大値'(L,'','') :- 'L が[]の時はB1,B2はそれぞれnull'(L). '_b1の最大値'(L,B1,B2) :- findmax(B1,( member(B1,L)),MaxB1), findmax([MaxB1,B2],( 'B Table'(MaxB1,B2)),[B1,B2]) 'L が[]の時はB1,B2はそれぞれnull'([]). % 以下のサイトは '10未満且つ、3または5の倍数は、3、5、6、9であり、左の総和は23である。 同様に、1000未満且つ、3または5の倍数の総和を求めよ。'(_1000未満且つ_3または5の倍数の総和) :- '10未満且つ、3または5の倍数は、3、5、6、9であり、左の総和は23である。', '同様に、1000未満且つ、3または5の倍数の総和を求めよ。'(_1000未満且つ_3または5の倍数の総和). '10未満且つ、3または5の倍数は、3、5、6、9であり、左の総和は23である。' :- '10未満且つ、3または5の倍数は、3、5、6、9であり、', '左の総和は'([3,5,6,9],_左の総和は), _左の総和は = 23. '10未満且つ、3または5の倍数は、3、5、6、9であり、' :- findall(_10未満且つ_3または5の倍数,( '10未満且つ、3または5の倍数は、'(_10未満且つ_3または5の倍数)), _10未満且つ_3または5の倍数ならび), '3、5、6、9であり、'(_10未満且つ_3または5の倍数ならび,[3,5,6,9]). '10未満且つ、3または5の倍数は、'(_10未満且つ_3または5の倍数) :- between(1,9,_10未満且つ_3または5の倍数), '3または5の倍数'(_10未満且つ_3または5の倍数). '3、5、6、9であり、'([],[]). '3、5、6、9であり、'([N|R1],L2) :- select(N,L2,R2), '3、5、6、9であり、'(R1,R2). '左の総和は'(_左の,_総和は) :- sumlist(_左の,_総和は). '同様に、1000未満且つ、3または5の倍数の総和を求めよ。'(_1000未満且つ_3または5の倍数の総和) :- findall(_1000未満且つ_3または5の倍数,( '1000未満且つ、3または5の倍数は、'(_1000未満且つ_3または5の倍数)), _1000未満且つ_3または5の倍数ならび), '左の総和は'(_1000未満且つ_3または5の倍数ならび,_1000未満且つ_3または5の倍数の総和). '1000未満且つ、3または5の倍数は、'(_1000未満且つ_3または5の倍数) :- between(1,999,_1000未満且つ_3または5の倍数), 3または5の倍数'(_1000未満且つ_3または5の倍数). '3または5の倍数'(_3の倍数) :- 0 is _3の倍数 mod 3,!. '3または5の倍数'(_5の倍数) :- 0 is _5の倍数 mod 5. % 以下のサイトは # # ■Python # print map(lambda x: x*2, filter(lambda x: x>2 and x<5, [1,2,3,4,5])) # # ■Ruby # puts [1,2,3,4,5].select{|i| i > 2 and i < 5}.map{|i| i*2} # # ■C# # new{}{ 1,2,3,4,5 }.Where(x => 2 < x && x < 5).Select(x => x*2); # # ■Haskell # print [x*2| x <-[1,2,3,4,5], x > 2, x < 5] '集合[1,2,3,4,5]の2より大きく5より小さい要素を2倍したものの集合を表示する' :- findall(_x_2,( member(_x,[1,2,3,4,5]), _x > 2, _x < 5, _x_2 is _x * 2), L), writef('%t\n',[L]). 'Python: print map(lambda x: x*2, filter(lambda x: x>2 and x<5, [1,2,3,4,5]))' :- findall(_x_2,( member(_x,[1,2,3,4,5]), _x > 2, _x < 5, _x_2 is _x * 2), L), writef('%t\n',[L]). 'Ruby: puts [1,2,3,4,5].select{|i| i > 2 and i < 5}.map{|i| i*2}' :- findall(_x_2,( member(_x,[1,2,3,4,5]), _x > 2, _x < 5, _x_2 is _x * 2), L), writef('%t\n',[L]). 'C#: new{}{ 1,2,3,4,5 }.Where(x => 2 < x && x < 5).Select(x => x*2);' :- findall(_x_2,( member(_x,[1,2,3,4,5]), _x > 2, _x < 5, _x_2 is _x * 2), L), writef('%t\n',[L]). 'Haskell: print [x*2| x <-[1,2,3,4,5], x > 2, x < 5]' :- findall(_x_2,( member(_x,[1,2,3,4,5]), _x > 2, _x < 5, _x_2 is _x * 2), L), writef('%t\n',[L]). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/850 # # 3角形の3辺の長さがあたえられたとき、 # 正三角形、2等辺三角形、直角三角形か調べるプログラムをつくりなさい # ってな問題がでたことあるんだけど・・・ # 結構むずいよね。 # # '3角形の3辺の長さがあたえられたとき、正三角形、2等辺三角形、直角三角形か調べる'(_辺_1,_辺_2,_辺_3,_診断) :- 正三角形か調べる(_辺_1,_辺_2,_辺_3,_), 2等辺三角形か調べる(_辺_1,_辺_2,_辺_3,_2等辺三角形診断), 直角三角形か調べる(_辺_1,_辺_2,_辺_3,_直角三角形診断), 診断を編集する(_直角三角形診断,_2等辺三角形診断,_診断). 正三角形か調べる(_辺_1,_辺_2,_辺_3,_) :- 正三角形は2等辺三角形に属するからそちらで診断する. 正三角形は2等辺三角形に属するからそちらで診断する. '2等辺三角形か調べる'(_辺,_辺,_辺,'正') :- !. '2等辺三角形か調べる'(_辺,_辺,_,'2等辺') :- !. '2等辺三角形か調べる'(_,_辺,_辺,'2等辺') :- !. '2等辺三角形か調べる'(_辺,_,_辺,'2等辺') :- !. '2等辺三角形か調べる'(_,_,_,''). 直角三角形か調べる(_辺_1,_辺_2,_辺_3,直角) :- select(_長辺,[_辺_1,_辺_2,_辺_3],[_短辺_1,_短辺_2]), _長辺 * _長辺 =:= _短辺_1 * _短辺_1 + _短辺_2 * _短辺_2,!. 直角三角形か調べる(_,_,_,''). 診断を編集する('','','正三角形、2等辺三角形、直角三角形の何れでもない') :- !. 診断を編集する(_直角三角形診断,_2等辺三角形診断,_診断) :- atomic_list_concat([_直角三角形診断,_2等辺三角形診断,'三角形'],_診断). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/850 # # 3角形の3辺の長さがあたえられたとき、 # 正三角形、2等辺三角形、直角三角形か調べるプログラムをつくりなさい # ってな問題がでたことあるんだけど・・・ # 結構むずいよね。 # # '3角形の3辺の長さがあたえられたとき、正三角形、2等辺三角形、直角三角形か調べる'(_辺_1,_辺_2,_辺_3,_診断) :- 正三角形か(_辺_1,_辺_2,_辺_3,_), 2等辺三角形か(_辺_1,_辺_2,_辺_3,_2等辺三角形診断), 直角三角形か(_辺_1,_辺_2,_辺_3,_直角三角形診断), 調べる(_直角三角形診断,_2等辺三角形診断,_診断). 正三角形か(_辺_1,_辺_2,_辺_3,_) :- 正三角形は2等辺三角形に属するからそちらで診断する. 正三角形は2等辺三角形に属するからそちらで診断する. '2等辺三角形か'(_辺,_辺,_辺,'正') :- !. '2等辺三角形か'(_辺,_辺,_,'2等辺') :- !. '2等辺三角形か'(_,_辺,_辺,'2等辺') :- !. '2等辺三角形か'(_辺,_,_辺,'2等辺') :- !. '2等辺三角形か'(_,_,_,''). 直角三角形か(_辺_1,_辺_2,_辺_3,直角) :- select(_長辺,[_辺_1,_辺_2,_辺_3],[_短辺_1,_短辺_2]), _長辺 * _長辺 =:= _短辺_1 * _短辺_1 + _短辺_2 * _短辺_2,!. 直角三角形か(_,_,_,''). 調べる('','','正三角形、2等辺三角形、直角三角形の何れでもない') :- !. 調べる(_直角三角形診断,_2等辺三角形診断,_診断) :- atomic_list_concat([_直角三角形診断,_2等辺三角形診断,'三角形'],_診断). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/850 # # 3角形の3辺の長さがあたえられたとき、 # 正三角形、2等辺三角形、直角三角形か調べるプログラムをつくりなさい # ってな問題がでたことあるんだけど・・・ # 結構むずいよね。 # # '3角形の3辺の長さがあたえられたとき、正三角形、2等辺三角形、直角三角形か調べる'(_辺_1,_辺_2,_辺_3,_診断) :- 正三角形か調べる(_辺_1,_辺_2,_辺_3,_正三角形診断), 直角三角形か調べる(_辺_1,_辺_2,_辺_3,_直角三角形診断), '2等辺三角形か調べる'(_辺_1,_辺_2,_辺_3,_2等辺三角形診断), 診断を編集する(_正三角形診断,_直角三角形診断,_2等辺三角形診断,_診断). 正三角形か調べる(_辺,_辺,_辺,正) :- !. 正三角形か調べる(_,_,''). '2等辺三角形か調べる'(_辺,_辺,_,'2等辺') :- !. '2等辺三角形か調べる'(_,_辺,_辺,'2等辺') :- !. '2等辺三角形か調べる'(_辺,_,_辺,'2等辺') :- !. '2等辺三角形か調べる'(_,_,_,''). 直角三角形か調べる(_辺_1,_辺_2,_辺_3,直角) :- select(_長辺,[_辺_1,_辺_2,_辺_3],[_短辺_1,_短辺_2]), _長辺 * _長辺 =:= _短辺_1 * _短辺_1 + _短辺_2 * _短辺_2,!. 直角三角形か調べる(_,_,_,''). 診断を編集する('','','','正三角形、2等辺三角形,直角三角形の何れでもない') :- !. 診断を編集する(正,_,_,正三角形) :- !. 診断を編集する(_,_直角三角形診断,_2等辺三角形診断,_診断) :- atomic_list_concat([_直角三角形診断,_2等辺三角形診断,'三角形'],_診断),!. % % 一つ問題なのは、「正三角形は直角三角形にはならない」という事を分かって % しまっている定義だということだ。課題のどこを見てもそんな記述はない。 % % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/850 # # 3角形の3辺の長さがあたえられたとき、 # 正三角形、2等辺三角形、直角三角形か調べるプログラムをつくりなさい # ってな問題がでたことあるんだけど・・・ # 結構むずいよね。 # # '3角形の3辺の長さがあたえられたとき、正三角形、2等辺三角形、直角三角形か調べる'(_辺_1,_辺_2,_辺_3,_診断) :- 正三角形か(_辺_1,_辺_2,_辺_3,_正三角形診断), 直角三角形か(_辺_1,_辺_2,_辺_3,_直角三角形診断), '2等辺三角形か'(_辺_1,_辺_2,_辺_3,_2等辺三角形診断), 調べる(_正三角形診断,_直角三角形診断,_2等辺三角形診断,_診断). 正三角形か(_辺,_辺,_辺,正) :- !. 正三角形か(_,_,''). '2等辺三角形か'(_辺,_辺,_,'2等辺') :- !. '2等辺三角形か'(_,_辺,_辺,'2等辺') :- !. '2等辺三角形か'(_辺,_,_辺,'2等辺') :- !. '2等辺三角形か'(_,_,_,''). 直角三角形か(_辺_1,_辺_2,_辺_3,直角) :- select(_長辺,[_辺_1,_辺_2,_辺_3],[_短辺_1,_短辺_2]), _長辺 * _長辺 =:= _短辺_1 * _短辺_1 + _短辺_2 * _短辺_2,!. 直角三角形か(_,_,_,''). 調べる('','','','正三角形、2等辺三角形,直角三角形の何れでもない') :- !. 調べる(正,_,_,正三角形) :- !. 調べる(_,_直角三角形診断,_2等辺三角形診断,_診断) :- atomic_list_concat([_直角三角形診断,_2等辺三角形診断,'三角形'],_診断),!. % % 一つ問題なのは、「正三角形は直角三角形にはならない」という事を分かって % しまっている定義だということだ。課題のどこを見てもそんな記述はない。 % % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/710 # # # 質問です。。 # ・Postgresql 9 # ・テーブルデータはざっくりですが、以下のような感じです。 # # table_name # # id | state | name | pride # ------+-------+-----------+---------------- # 1 | 2 | hoge1 | 01 # 2 | 1 | hoge2 | 02 # 15 | 2 | hoge3 | 02,03 # 16 | 1 | hoge4 | 02,04,05 # 33 | 1 | hoge5 | 04 # 34 | 1 | hoge6 | 01,05 # 35 | 1 | hoge7 | 01,02,03 # 36 | 1 | hoge8 | 01,02,03,04 # # 実際は、もっとレコード数が多いと思っておいてください。 # # ・やりたい事 # ランダムに10件、とかselectして表示させたいのですが、 # state = 1 # である事が絶対条件で、 # なおかつ # pride # の、 # 「01」が含まれるものの中から10件、ランダムに抽出 # 「02」が含まれるものの中から10件、ランダムに抽出 # ・・・以下、実際のデータでは20位まで続きます。 # # ・・・といった内容を、出来るだけ簡潔に書こうと思うと、どんな方法があるでしょうか? # # ちなみに、最終的にはidとnameを表示させるだけ、 # phpでWEBに表示させます。 # # SELECT id,name FROM table_name WHERE state = 1 AND pride LIKE '%01%' ORDER BY RANDOM() LIMIT 10 # # これで「01」が含まれるものの中から10件、ランダムに抽出・・・ # はできるのですが、コレを20回って・・・と思いますし、 # SELECT id,name FROM table_name WHERE state = 1 # で全部出力して配列に突っ込んでからソートしなおす、 # というのもあまりスマートでないような気がして。。。 # # 良い方法ないでしょうか。 # 'ランダムに10件、とかselectして表示させたいのですが、state = 1である事が絶対条件で、なおかつprideの、「01」が含まれるものの中から10件、ランダムに抽出、「02」が含まれるものの中から10件、ランダムに抽出・・・以下、実際のデータでは20位まで続きます。'(_pride_の優先順位20位までのならび,_id,_name) :- member(_pride,_pride_の優先順位20位までのならび), '10件取り出す'(_pride,_id,_name). '10件取り出す'(_pride,_id,_name) :- findall([_id,_name],( table_name(_id,1,_name,_pride)), LL_1), 乱順処理(LL_1,_id,_name). 乱順処理(LL_1,_id,_name) :- length(LL_1,_要素数), length(Ln,10), 乱順処理(Ln,_要素数,LL_1,LL_2), member([_id,_name],LL_2). 乱順処理([],_,_,[]) :- !. 乱順処理(_,0,_,[]) :- !. 乱順処理([_|Ln],_要素数,LL_1,[L|R]) :- 乱数を使って候補節を取り出す(_要素数,LL_1,L,_残り要素数,LL_2), 乱順処理(Ln,_残り要素数,LL_2,R). 乱数を使って候補節を取り出す(_要素数,LL_1,[_id,_name],_残り要素数,LL_2) :- _乱数 is random(_要素数), length(L0,_乱数), append(L0,[[_id,_name]|R0],LL_1), append(L0,R0,LL_2), _残り要素数 is _要素数 - 1. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/456 # # {1] 授業単元:プログラミング演習 # [2] 問題文: # 100点満点の試験を10人分整数型配列data[10]に入力すると、得点の高い順に出力されるプログラムを作成。 # '100点満点の試験の点数を10人分入力し、得点の高い順に出力する' :- '100点満点の試験の点数を10人分入力し'(_10人分の点数ならび), 得点の高い順に出力する(_10人分の点数ならび). '100点満点の試験の点数を10人分入力し'(_10人分の点数ならび) :- '10人分'(_10人分の点数ならび), findall(_点数,( append(L1,[_点数|_],_10人分の点数ならび), '100点満点の試験の点数を入力'(L1,_点数)), _10人分の点数ならび). '10人分'(_10人分の点数ならび) :- length(_10人分の点数ならび,10). '100点満点の試験の点数を入力'(Ln,_点数) :- length([_|Ln],_何人目),- writef('%t人目の点数を入力してください : ',[_何人目]), get_line(Line), '100点満点の試験の点数を入力診断'(Line,_点数),!. '100点満点の試験の点数を入力'(Ln,_点数) :- '100点満点の試験の点数を入力'(Ln,_点数). '100点満点の試験の点数を入力診断'(Line,_点数) :- atom_to_term(Line,_点数,_), integer(_点数), '100点満点の'(_点数),!. '100点満点の試験の点数を入力診断'(Line,_点数) :- writef('入力された %t からは適切な試験の点数が得られません。\n再入力をお願いします。\n',[Line]), fail. '100点満点の'(_点数) :- _点数 >= 0, _点数 =< 100,!. 得点の高い順に出力する([_点数]) :- writef('%t\n',[_点数]),!. 得点の高い順に出力する(_点数ならび) :- max(_点数ならび,_選択された点数), select(_選択された点数,_点数ならび,_選択された点数を取り除いた点数ならび), writef('%t ',[_選択された点数]), 得点の高い順に出力する(_選択された点数を取り除いた点数ならび). % 以下のサイトは # # Prologで、 f(X1, X2, X3, X4 ・・・Xn) のX1〜Xnまでダブりがないのを簡単に書く # 方法が絶対にありそうなのに見つからない。X1 \= X2, を延々と書くのは無謀すぎる。 # 関数の引数変数にダブリがない(_関数) :- _関数 =.. [_関数名|_引数リスト], select(_着目する要素,_引数リスト,_着目する要素以外の要素リスト), 変数リストの中に着目する要素と同一変数がある(_着目する要素,_着目する要素以外の要素リスト), !, fail. 関数の引数変数にダブリがない(_). 変数リストの中に着目する要素と同一変数がある(E,[A|R]) :- E == A,!. 変数リストの中に着目する要素と同一変数がある(E,[_|R]) :- 変数リストの中に着目する要素と同一変数がある(E,R). % 以下のサイトは # 出典 :: SQL質疑応答スレ 12問目 #649 # SQLというよりテーブル設計の質問なんですがいいでしょうか? # # ユーザごとの日々変化するデータを1日1レコードずつ保存するために # 以下のようなテーブル構造を考えました。 # # USERSテーブル #  user_no (ユーザ番号 PK) #  latest_gen_no (最新世代番号) #  氏名その他の属性 # # RECORDSテーブル #  user_no (ユーザ番号 PK*) #  gen_no (世代番号 PK*) #  日々変化する値 # *user_no, gen_no のペアでPK # # GENERATIONSテーブル #  gen_no (世代番号 PK) #  date (日時) # # 全ユーザの最新世代の値を取得するべく、 # select ... from users u, records r # where u.user_no=r.user_no and u.latest_gen_no=r.gen_no; # というSQLを発行すると、ものすごく時間が掛かります。 # # PKやインデックスの設定の仕方に問題があるのでしょうか? # そもそもテーブルの構成がまずいでしょうか? # テーブル副目標(_テーブル名,_引数ならび,_属性名ならび,_副目標) :- findall(_,テーブル定義(_テーブル名,_,_属性名),_引数ならび), 属性名ならびを得る(_テーブル名,_属性名ならび), _副目標 =.. [_テーブル名|_引数ならび]. 属性名ならびを得る(_テーブル名,_属性名ならび) :- setof([_属性順位,_属性名],[_テーブル名,_属性順位,_属性名] ^ テーブル定義(_テーブル名,_属性順位,_属性名),_属性順位_属性名ならび), findall(_属性名,member([_,_属性名],_属性順位_属性名ならび),_属性名ならび). 'USERSテーブルを最新世代に更新する' :- ユーザごとの現在の最新世代を得る(_ユーザごとの最新世代ならび), 'USERSテーブルを更新する'(_ユーザごとの最新世代ならび). ユーザごとの現在の最新世代を得る(_ユーザごとの最新世代ならび) :- 'テーブル副目標'('USERS',[_ユーザ番号,_最新世代番号|_氏名その他の属性],_,_USERS), findsetof(_ユーザ番号,_USERS,_対象ユーザ番号ならび), ユーザごとの現在の最新世代を得る(_対象ユーザ番号ならび,_ユーザごとの最新世代ならび). ユーザごとの現在の最新世代を得る([],[]). ユーザごとの現在の最新世代を得る([_ユーザ番号|R1],[[_ユーザ番号,_最新世代番号]|R2]) :- テーブル副目標('RECORDS',[_ユーザ番号,_世代番号|_],_,_RECORDS), findmax([_日時,_世代番号],( 'USERSテーブルの日時、世代番号'(_RECODRS,_世代番号,_日時)),[_,_最新世代番号]), ユーザごとの現在の最新世代を得る(R1,R2). 'USERSテーブルの日時、世代番号'(_RECODRS,_世代番号,_日時) :- _RECORDS, 'GENERATIONS'(_世代番号,_日時). 'USERSテーブルを更新する'([]). 'USERSテーブルを更新する'([[_ユーザ番号,_最新世代番号]|R]) :- 'テーブル副目標の最新世代番号情報を更新する'(_ユーザ番号,_最新世代番号), 'USERSテーブルを更新する'(R),!. 'テーブル副目標の最新世代番号情報を更新する'(_ユーザ番号,_最新世代番号) :- テーブル副目標('USERS',[_ユーザ番号,_|_氏名その他の属性],_,_USERS_1), テーブル副目標('USERS',[_ユーザ番号,_最新世代番号|_氏名その他の属性],_,_USERS_2), 'USERSテーブルの更新'(_USERS_1,_USERS_2). 'USERSテーブルの更新'(_USERS_1,_USERS_2) :- retract(_USERS_1), assertz(_USERS_2). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/647 # # #インデントが崩れる場合は http://ime.nu/pastebin.com/26BkXDHs をみてください。 # # -- # -- 商品テーブルと、 # -- # create table items ( # id serial primary key, # name varchar(255) not null, # price integer not null -- 単価 # ); # # -- # -- 販売テーブルがあるとする。 # -- # create table sales ( # id serial primary key, # item_id integer not null references items(id), # count integer not null default 1, -- 個数 # total integer not null, -- 単価 * 個数 # created_at timestamp not null default current_datetime # ) # # -- # -- 日付を指定して、その日の商品別販売金額合計を大きい順に表示したい。 # -- どういうSQLを書けばいいの? # -- こんなかんじで書けたらいいんだけど。 # -- # select items.id, items.name # from items, # (select item_id, sum(total) as sum_total # from sales # where date(created_at) = '2012-04-01' # group by item_id) as totals # where items.id = totals.item_id # order by totals.sum_total desc; # # '日付を指定して、その日の商品別販売金額合計を大きい順に表示したい' :- '日付を指定して、'(_日付), その日の商品別販売金額合計を(_日付,L1), 大きい順に表示する(L1). '日付を指定して、'(_日付) :- write('日付を8桁の整数で入力して下さい : '), get_line(Line), '日付を指定して、の診断'(Line,_日付),!. '日付を指定して、'(_日付) :- '日付を指定して、'(_日付). '日付を指定して、の診断'(Line,_日付) :- atom_to_term(Line,_8桁の整数,_), '8桁の整数'(_8桁の整数), '8桁の整数から日付を得る'(_8桁の整数,_日付),!. '日付を指定して、の診断'(Line,_日付) :- writef('入力された %t からは日付が得られませんでした。再入力をお願いします\n',[Line]), fail. '8桁の整数'(_8桁の整数) :- integer(_8桁の整数), _8桁の整数 >= 10000000, _8桁の整数 =< 99999999. '8桁の整数から日付を得る'(_8桁の整数,_日付) :- swritef(_日付文字列,'%t',[_8桁の整数]), sub_atom(_日付文字列,0,4,_,_年), sub_atom(_日付文字列,4,2,_,_月), sub_atom(_日付文字列,6,2,_,_日), atomic_list_concat([_年,'-',_月,'-',_日],_日付),!. その日の商品別販売金額合計を(_日付,L1) :- findsetof(_id,( sales(_id,_item_id,_count,_total,_日付)), L), findall([_total,_id],( append(_,[_id|R],L), 商品の販売合計(_日付,_id,_合計金額)), L1). 商品の販売合計(_日付,_id,_合計金額) :- findsum(_total,( sales(_id,_item_id,_count,_total,_日付)), _合計金額). 大きい順に表示する(L1) :- 大きい順に(L1,L2), 表示する(L2). 大きい順に(L1,L2) :- sort(L1,L3), reverse(L3,L2). 表示する(_日付,[]). 表示する(_日付,[[_合計金額,_id]|R]) :- items(_id,_name,_price), writef('%t %t %20l %10r\n',[_日付,_id,_name,_合計金額]), 表示する(_日付,R). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/628 # # Mysql5を使っています。以下のようなテーブルがある時、 # ・table_male(カラム:id/name/address) # ・table_female(カラム:id/name/address) # ・table_X(カラム:id/sex_id/sex/unique_key) ※sex_idはtable_male.idもしくはtable_female.id # # クエリA # select `sex`, `sex_id` from table_X where unique_key = $key limit 1; # の結果(sexの値にmaleかfemaleが返る)に応じて # table_maleもしくはtable_femaleからaddressを引き出したいと思います # 今まではクエリAのあとに以下のようにしていたんですが、両方をまとめてやることはできないでしょうか? # select `address` from table_male where `id`=$sex_id limit 1; # # 最初のクエリの取得結果に応じて、続けて実行するクエリの対象テーブルを変更させるということに # なると思うんですが… # よろしくお願いします # # 'select `sex`, `sex_id` from table_X where unique_key = $key limit 1; select `address` from table_male where `id`=$sex_id limit 1;'(_uniqkey,_address) :- table_x(_id,_sexid,_sex,_uniqkey), 'maleテーブルまたはfemaleテーブルを参照する'(_sex,_id,_name,_address). 'maleテーブルまたはfemaleテーブルを参照する'(male,_id,_name,_address) :- table_male(_id,_name,_address),!. 'maleテーブルまたはfemaleテーブルを参照する'(female,_id,_name,_address) :- table_female(_id,_name,_address),!. % 以下のサイトは ?- 'a##'. # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/584 # # MySQL 5.5.19 . 長くなりますので # テーブルの定義・内容と欲しい結果はここに # http://ime.nu/codepad.org/oe1jhVrF # # で、 # # create table a_tbl( # code int(9) not null, # input_date date not null, # data1 double(9,2) unsigned default 0 not null, # data2 double(9,2) unsigned default 0 not null, # primary key(code,input_date) # ) ; # # insert into a_tbl # values # (1111,'2012-02-01',10,12), # (1111,'2012-02-02',133,14), # (1111,'2012-02-04',13,15), # (1111,'2012-02-06',13,10); # # create table b_tbl( # code varchar(10) not null, # input_date date not null, # data1 double(9,2) unsigned default 0 not null, # data2 double(9,2) unsigned default 0 not null, # primary key(code,input_date) # ) ; # # insert into b_tbl # values # ('ddd','2012-02-01',122,13), # ('ddd','2012-02-03',127,18), # ('ddd','2012-02-04',11,14), # ('ddd','2012-02-05',16,95), # ('ddd','2012-02-06',13,10); # # 欲しい結果 # input_date a.data1 a.data2 b.data2 # 2012-02-01 10 12 13 # 2012-02-02 133 14 null # 2012-02-03 null null 18 # 2012-02-04 13 15 14 # 2012-02-05 null null 95 # 2012-02-06 13 10 10 # # # select a.input_date,b.input_date,a.data1,a.data2,b.data2 # from a_tbl a # right join b_tbl b # on a.input_date = b.input_date; とすると、結果が # +------------+------------+-------+-------+-------+ # | input_date | input_date | data1 | data2 | data2 | # +------------+------------+-------+-------+-------+ # | 2012-02-01 | 2012-02-01 | 10 | 12 | 13 | # | NULL | 2012-02-03 | NULL | NULL | 18 | # | 2012-02-04 | 2012-02-04 | 13 | 15 | 14 | # | NULL | 2012-02-05 | NULL | NULL | 95 | # | 2012-02-06 | 2012-02-06 | 13 | 10 | 10 | # +------------+------------+-------+-------+-------+ # なんですが、実際にはいろんなコードが入っているので、コードも抽出条件に入れたら # select a.input_date,b.input_date,a.data1,a.data2,b.data2 # from a_tbl a # right join b_tbl b # on a.input_date = b.input_date # where # a.code=1111 and b.code='ddd'; # +------------+------------+-------+-------+-------+ # | input_date | input_date | data1 | data2 | data2 | # +------------+------------+-------+-------+-------+ # | 2012-02-01 | 2012-02-01 | 10 | 12 | 13 | # | 2012-02-04 | 2012-02-04 | 13 | 15 | 14 | # | 2012-02-06 | 2012-02-06 | 13 | 10 | 10 | # +------------+------------+-------+-------+-------+ # になってしまいました。 # コードを抽出条件に入れた状態で望ましい結果または上の方の結果になるようなSQLを教えて下さい。 # 'input_dateの集合を得る'(_input_dateの集合) :- findall(_input_date,a_tbl(_input_date,_,_),L1), findall(_input_date,b_tbl(_input_date,_,_),L2), append(L1,L2,L3), setof(_input_date,member(_input_date,L3),_input_dateの集合). 抽出(_input_date,_tbl_aのdata1ならび,_tbl_aのdata2ならび,_tbl_bのdata2ならび) :- 'input_dateの集合を得る'(_input_dateの集合), member(_input_date,_input_dateの集合), findall([_data1],tbl_a(_,_input_date,_data1,_),_tbl_aのdata1ならび), findall([_data2],tbl_a(_,_input_date,_,_data2),_tbl_aのdata2ならび), findall([_data2],tbl_b(_,_input_date,_,_data2),_tbl_bのdata2ならび). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1325685876/195 # # [1] 授業単元:C言語入門 # [2] 問題文: # http://ime.nu/codepad.org/xmcn6oBoに # select_sortを # void ins_sort(int a[],int n){ # int i,j,k; # for(i=1; i<n; i++){ # x=a[i]; # for(j=i-1; j>=0 && a[j]>x; j--;) # a[j+1]=a[j]; # a[j+1]=x; # } # } # に書き換え、小さい物から大きい物の順番に並び替えるようにするにはどうすれば良いのですか? # 挿入整列(_乱順ならび,_整列ならび) :- 挿入整列(_乱順ならび,[],_整列ならび). 挿入整列([],_整列ならび,_整列ならび). 挿入整列([A|R1],L1,_整列ならび) :- 挿入(A,L1,L2), 挿入整列(R1,L2,_整列ならび). 挿入(A,[],[A]). 挿入(A,[B|R],[A,B|R]) :- A @=< B,!. 挿入(A,[B|R1],[B|R2]) :- A @> B, 挿入(A,R1,R2). % 以下のサイトは # 出典::SQL質疑応答スレ 12問目 #353 # MySQL 5.1 # 株価テーブル kabuka # stock_code ←銘柄コード # vol_date ←出来高年月日 # sp # hp # lp # cp # vol # # 銘柄マスタ stock_info # stoc_code ←銘柄コード # shkbn ←商品区分(0,1,2,3,4) # stk_name ← 銘柄名 # delete_flg 削除区分 # 〜その他いろいろな項目 # # 銘柄マスタの商品区分0及び1は除外して銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と最新登録日の一覧を出したい # # select a.stock_code,stk_name,shkbn,min(vol_date),max(vol_date) # from kabuka a # inner join stock_info b # on a.stock_code = b.stock_code # where # a.stock_code in # (select b.stock_code from stock_info # where delete_flg=0 and shkbn not in(0,4)) # group by a.stock_code # order by shkbn,a.stock_code; # # で、上記のSQLを書いてみたんですが、shkbnが0及び4のもでてしまいます # 出さないようにするにはどうすればいいのでしょうか? # # 銘柄マスタの商品区分0及び1は除外して銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と最新登録日の一覧を出したい :- 一覧を出したい(銘柄マスタの商品区分0及び1は除外して(_銘柄,_銘柄名), 銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と最新登録日を表示する(_銘柄,_銘柄名)). 一覧を出したい(_表示対象,_表示する) :- forall(_表示対象,_表示する). 銘柄マスタの商品区分0及び1は除外して(_銘柄,_銘柄名) :- setof([_stoc_code,_stk_name],( [_stoc_code,_shkbn,_stk_name,_delete_flg] ^ stock_info(_stoc_code,_shkbn,_stk_name,_delete_flg), 商品区分0及び1は除外して(_shkbn)),LL), member([_銘柄,_銘柄名],LL). 商品区分0及び1は除外して(_shkbn) :- _shkbn=\=0, _shkbn=\=1. 銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と最新登録日を表示する(_stock_code,_銘柄名) :- 銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と最新登録日を(_stock_code,_最古登録日,_最新登録日), writef('%t,%t,最古登録日=%t,最新登録日=%t\n',[_stoc_code,_銘柄名,_最古登録日,_最新登録日]). 銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と最新登録日を(_stock_code,_最古登録日,_最新登録日) :- '銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と'(_stock_code,_最古登録日), 最新登録日を(_stock_code,_最新登録日). 銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と(_stock_code,_最古登録日) :- findmin(_vol_date,kabuka(_stock_code,_vol_date,_sp,_hp,_lp,_cp,_vol),_最古登録日). 最新登録日を(_stock_code,_最新登録日) :- findmax(_vol_date,kabuka(_stock_code,_vol_date,_sp,_hp,_lp,_cp,_vol),_最新登録日). findmin(A,B,C) :- findall(A,B,L), 昇順整列した最初の要素(L1,C). 昇順整列した最初の要素(L1,C) :- sort(L,[C|_]). findmax(A,B,C) :- findall(A,B,L1), 昇順整列した最終要素(L1,C). 昇順整列した最終要素(L1,C) :- sort(L1,L2), last(L2,C). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/351 # # 解決気味です。 # # 上記を諦め、 # # T1 マスタテーブル # ID | DATE    | DATA |ckbox # --+----------+----- |------ # 1 | 2007-11-11 | aaa | 201,202,205,401,403,404 # 2 | 2007-11-11 | bbb | 202,203 # 3 | 2007-11-10 | ccc | 203,204,403,404,405 # # 上記の形式にして # select ID,DATE,DATA from `T1` # where # CONCAT(',',chkbox,',') like '%,201,%' # and # CONCAT(',',chkbox,',') like '%,202,%' # and # CONCAT(',',chkbox,',') like '%,403,%' # # こういった形で取得。 # # チェックボックスは計300個程ありそれぞれユニークを振っています。 # チェックされている数は平均50個程。 # レコード数は約1万程なのですがこの方法で大丈夫かどうか心配です。 # 'チェックボックスならびを指定してT1の組を検索'(_チェックボックスならび,_ID,_DATE,_DATA,_ckbox) :- 'T1'(_ID,_DATE,_DATA,_ckbox), split(_ckbox,[','],L), 'チェックボックスならびの要素はすべてLの中にある'(_チェックボックスならび,L). 'チェックボックスならびの要素はすべてLの中にある'([],_). 'チェックボックスならびの要素はすべてLの中にある'([_要素|R],L) :- member(_要素,L), 'チェックボックスならびの要素はすべてLの中にある'(R,L). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/348 # # (質問) #  チェックボックス値による検索を行いたいと思っています。 # # MYSQL5.1 # # T1 マスタテーブル # ID | DATE     | DATA # --+----------+----- # 1 | 2007-11-11 | aaa # 2 | 2007-11-11 | bbb # 3 | 2007-11-10 | ccc # # T2 チェックボックステーブル1 # ID | cate1     | # --+--------- | # 1 | 201      | # 1 | 202      | # 1 | 205      | # 2 | 202      | # 2 | 203      | # 3 | 203      | # 3 | 204      | # # T3チェックボックステーブル2 # ID | cate2     | # --+--------- | # 1 | 401      | # 1 | 403      | # 1 | 404      | # 3 | 403      | # 3 | 404      | # 3 | 405      | # # このような3つのテーブルから、下記のように出したいがどうすれば # # T2で 201、202、を含み # 且つ # T3で 403 を含む  # # 結果 T1のIDレコード # 1 | 2007-11-11 | aaa # # 試した事 # select * from `T1` # join `T2` using(ID) # join `T3` using(ID) # where # cate1 in(201,202) # and cate2 in(403) # group by ID # having count(*)=?? # # 絞るのにカウント数がT1、T2のチェックレコード数で # 可変するので詰まっています。 # そもそも、考え方がおかしいのかもしれません。 # 良い方法をご教示ください。 # 'T2で 201、202、を含み 且つ T3で 403 を含む T1のIDレコード' :- 'T1'(_ID,_DATE,_DATA), 'T2'(_ID,_cate1), '201、202、を含み'(_cate1), 'T3'(_ID,403), writef('%t | %t | %t\n',[_ID,_DATE,_DATA]), fail. 'T2で 201、202、を含み 且つ T3で 403 を含む T1のIDレコード'. '201、202、を含み'(201). '201、202、を含み'(202). % 以下のサイトは # http://www.ioi-jp.org/joi/2011/2012-yo/2012-yo-t1/2012-yo-t1.html # 問題 # 1    ランチ (Lunch) # 問題 # # JOI パスタ店では,ランチのおすすめパスタと搾りたてジュースのセットメニューが # 好評である.このセットメニューを注文するときは,その日の 3 種類のパスタと # 2 種類のジュースから 1 つずつ選ぶ.パスタとジュースの値段の合計から 50 円を # 引いた金額が代金となる. # # ある日のパスタとジュースの値段が与えられたとき,その日のセットメニューの # 代金の最小値を求めるプログラムを作成せよ. # # 入力 # # 入力は 5 行からなり,1 行に 1 つずつ正の整数が書かれている. # 1 行目の整数は 1 つ目のパスタの値段である. # 2 行目の整数は 2 つ目のパスタの値段である. # 3 行目の整数は 3 つ目のパスタの値段である. # 4 行目の整数は 1 つ目のジュースの値段である. # 5 行目の整数は 2 つ目のジュースの値段である. # ただし,与えられる入力データにおいては全てのパスタとジュースの値段は # 100 円以上 2000 円以下であることが保証されている. # # 出力 # # その日のセットメニューの代金の最小値を 1 行で出力せよ. # # 入出力例 # # 入力例 1 入力例 2 # 800 1999 # 700 1999 # 900 100 # 198 189 # 330 100 # # 出力例 1 出力例 2 # 848 150 # # # 入出力例 1 では,2 つ目のパスタと 1 つ目のジュースを組み合わせた場合の 700 + 198 - 50 = 848 がその日のセットメニューの代金の最小値である. # # 入出力例 2 では,3 つ目のパスタと 2 つ目のジュースを組み合わせた場合の 100 + 100 - 50 = 150 がその日のセットメニューの代金の最小値である. # # ※各入出力例のデータは,右クリック等によりファイルに保存して利用可能です. # 'JOI パスタ店では,ランチのおすすめパスタと搾りたてジュースのセットメニューが好評である.このセットメニューを注文するときは,その日の 3 種類のパスタと 2 種類のジュースから 1 つずつ選ぶ.パスタとジュースの値段の合計から 50 円を引いた金額が代金となる.ある日のパスタとジュースの値段が与えられたとき,その日のセットメニューの代金の最小値を求める' :- '3書類のパスタと2種類のジュースの価格を得る'(_3種類のパスタの価格,_2種類のジュースの価格), 最小値を探しだす(_セットメニューの代金,( セットメニューを代金を得る(_3種類のパスタの価格,_2種類のジュースの価格,_セットメニューの代金)),_その日のセットメニューの代金の最小値), writef('%t\n',[_その日のセットメニューの代金の最小値]). '3書類のパスタと2種類のジュースの価格を得る'(_3種類のパスタの価格,_2種類のジュースの価格) :- '3種類のパスタの価格を得る'(_3種類のパスタの価格), '2種類のジュースの価格を得る'(_2種類のジュースの価格). '3種類のパスタの価格を得る'(_3種類のパスタの価格) :- findall(_パスタの価格,( パスタの価格を3回得る(_パスタの価格)),_3種類のパスタの価格). パスタの価格を3回得る(_パスタの価格) :- between(1,3,_), readln([_パスタの価格]). '2種類のジュースの価格を得る'(_2種類のジュースの価格) :- findall(_ジュースの価格,( ジュースの価格を2回得る(_ジュースの価格)),_2種類のジュースの価格). ジュースの価格を2回得る(_ジュースの価格) :- between(1,2,_), readln([_ジュースの価格]). 最小値を探しだす(_対象となる値,_副目標,_最小値) :- findall(_対象となる値,_副目標,L), 最小値(L,_最小値). 最小値(L,_最小値) :- select(_最小値,L,_最小値以外の要素ならび), 最小値はそれ以外の要素と等しいか小さい(_最小値,_最小値以外の要素ならび). 最小値はそれ以外の要素と等しいか小さい(最小値,_最小値以外の要素ならび) :- forall(member(_要素,_最小値以外の要素ならび),_要素 @>= _最小値). セットメニューを代金を得る(_3種類のパスタの価格,_2種類のジュースの価格,_セットメニューの代金) :- パスタとジュースの組み合わせを得る(_3種類のパスタの価格,_2種類のジュースの価格,_パスタの価格,_ジュースの価格), _セットメニューの代金 is _パスタの価格 + _ジュースの価格 - 50. パスタとジュースの組み合わせを得る(_3種類のパスタの価格,_2種類のジュースの価格,_パスタの価格,_ジュースの価格) :- member(_パスタの価格,_3種類のパスタの価格), member(_ジュースの価格,_2種類のジュースの価格). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1294641578/718 # # 最後から任意の件数を問い合わせたいのですが # select time from test order by time desc offset 0 limit 3;で # 呼び出すと下記のようになりますが # # time         # ------------------ # 2011-11-28 08:20:16 # 2010-10-26 06:20:16 # 2009-09-24 04:20:16 # # # ↓のように更にソートして呼び出すにはどう書けばよいのでしょうか? # time           # ------------------ # 2009-09-24 04:20:16 # 2010-10-26 06:20:16 # 2011-11-28 08:20:16 # # '最後から任意の件数を問い合わせる'(_任意の件数,L) :- テーブル構造の取得(test,time,P,_time), 全テーブルの取得(P,_time,LL1), 最後から任意の件数を取り出す(_任意の件数,LL1,L). テーブル構造の取得(_テーブル名,_鍵名,P,_項) :- findall(_,( テーブル定義(_テーブル名,_,_)), L), テーブル定義(_テーブル名,_項番号,_鍵名), nth1(_項番号,L,_項), P =.. [_テーブル名|L]. 全テーブルの取得(P,_time,LL1) :- findall([_time],( P), LL1). 逆順に整列(LL1,LL2) :- sort(LL1,LL3), reverse(LL3,LL2). 最後から任意の件数を取り出す(_任意の件数,LL,L) :- length(LL3,_任意の件数), append(LL3,_,LL2), 逆順に整列(LL1,LL2), member(L,LL3). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1294641578/678 # # point順に並び替え、ランクを表示する # # テーブル名 :tbl_point # フィールド名:point # name # gender # # 表示    :p_rank, name, gender, point # # select rank() over (order by [point] desc) as [p_rank], name, point from [tbl_point]; # # p_rank | name | gender | point # # 1 | hoge | 1 | 98 # 2   | fuga | 2 | 80 # 3  | poyo | 2 | 70 # 4  | boke | 1 | 60 # # ここまではできるのですが # # p_rank | mp_rank | wp_rank | name | gender | point # # 1 | 1 | | hoge | 1 | 98 # 2 | | 1 | fuga | 2 | 80 # 3  | | 2 | poyo | 2 | 70 # 4  | 2 | | boke | 1 | 60 # # gender毎のも表示するにはどうすればいいですか? # 'gender毎のも表示する' :- ランクの作成(LL_R,LL1_R,LL2_R), write('p_rank | mp_rank | wp_rank | name | gender | point\n\n'), append(L0,[[_point,_gender,_name]|R],LL_R), 性別ランクを得る(LL1_R,LL2_R,_name,_gender,_mp_rank), 表示する(L0,_point,_name,_gender,_mp_rank), R = []. ランクの作成(LL_R,LL1_R,LL2_R) :- ポイントランクの作成(LL_R), 男性ランクの作成(LL1_R), 女性ランクの作成(LL2_R). ポイントランクの作成(LL_R) :- findall([_point,_name,_gender],( tbl_point(_point,_name,_gender)), LL), rsort(LL,LL_R),!. 男性ランクの作成(LL1_R) :- findall([_point,_name],( tbl_point(_point,_name,1)), LL1), rsort(LL1,LL1_R). 女性ランクの作成(LL2_R) :- findall([_point,_name],( tbl_point(_point,_name,2)), LL2), rsort(LL2,LL2_R), 性別ランクを得る(LL1_R,LL2_R,_name,1,_rank) :- nth1(_rank,LL1_R,[_,_name]),!. 性別ランクを得る(LL1_R,LL2_R,_name,2,_rank) :- nth1(_rank,LL2_R,[_,_name]),!. 表示する(L0,_point,_name,1,_mp_rank) :- length([_|L0],_p_rank), writef('%7l|%9c|%9c|%6c|%8c|%6r\n',[_p_rank,_mp_rank,' ',_name,1,_point]),!. 表示する(L0,_point,_name,2,_wp_rank) :- length([_|L0],_p_rank), writef('%7l|%9c|%9c|%6c|%8c|%6r\n',[_p_rank,' ',_wp_rank,_name,2,_point]),!. rsort(L1,L2) :- sort(L1,L3), reverse(L3,L2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1316769778/153 # # if select * from t where id=1 # then update t set foo=bar where id=1 # # これをSQLで表現したいのですが可能でしょうか? # # 'if select * from t where id=1 then update t set foo=bar where id=1' :- '1要素のupdate'(t,id1,'1',foo,bar). '1要素のupdate'(_テーブル名,_鍵属性名,_鍵値,_置換属性名,_置換する値) :- 組構造を得る(_テーブル名,_属性名ならび), 鍵値を設定された項を作る(_テーブル名,_属性ならび,_鍵属性名,_鍵値,_現在の組,P), 置換する値を設定された項を作る(_テーブル名,_属性ならび,_置換属性名,_置換する値,_置換する組,_置換する項), retract(_現在の項), '置換される組の変数部分だけ元の値に単一化する'(_現在の組,_置換する組), asserta(_置換する項). 組構造を得る(_テーブル名,_属性名ならび) :- findall([_属性番号,_属性名],( テーブル構造(_テーブル名,_属性番号,_属性名)), L1), sort(L1,L2), findall(_属性名,( member([_,_属性名],L2)), _属性名ならび). 置換する値を設定された項を作る(_テーブル名,_属性ならび,_置換属性名,_置換する値,_置換する組,_置換項) :- 置換する組(_属性名ならび,_置換する組), 置換する値を置換する組に設定(_属性名ならび,_置換属性名,_置換する値,_置換する組), _置換項 =.. [_テーブル名|_置換する組]. 鍵値を設定された項を作る(_テーブル名,_属性ならび,_鍵属性名,_鍵値,_現在の組,_現在の項) :- 現在の組(_属性名ならび,_現在の組), 鍵を現在の組に設定(_属性名ならび,_鍵属性名,_鍵値,_現在の組), _現在の項 =.. [_テーブル名|_現在の組]. 現在の組(_属性名ならび,_現在の組) :- length(_属性名ならび,Len), length(_現在の組,Len). 置換する組(_属性名ならび,_置換する組) :- length(_属性名ならび,Len), length(_置換する組,Len). 鍵を現在の組に設定(_属性名ならび,_鍵名,_鍵値,_現在の組) :- nth1(_鍵属性名の位置,_属性名ならび,_鍵属性名), nth1(_鍵属性名の位置,_現在の組,_鍵値),!. 置換する値を置換する組に設定(_属性名ならび,_置換属性名,_置換する値,_置換する組) :- nth1(_置換属性名の位置,_属性名ならび,_鍵属性名), nth1(_鍵属性名の位置,_置換する組,_鍵値),!. '置換する組の変数部分だけ元の値に単一化する'([],[]). '置換する組の変数部分だけ元の値に単一化する'([A|R1],[A|R2]) :- '置換する組の変数部分だけ元の値に単一化する'(R1,R2). '置換する組の変数部分だけ元の値に単一化する'([A|R1],[B|R2]) :- \+(A = B), '置換する組の変数部分だけ元の値に単一化する'(R1,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1316769778/147 # # 特定のidが持つintカラムから最も近いかつ小さい数字を持つidを求めたいのですが、 # # select id from t1 where int_col < (select int_col from t1 where id=特定のid) order by int_col desc # でできたのですが # もっとよいSQLありませんか? # # '特定のidが持つintカラムから最も近いかつ小さい数字を持つidを求める'(_id,_id_2) :- t1(_id,_int_col), findmax([_int_col_x,_id_x],( t1(_id_x,_int_col_x), _int_col_x < _int_col), [_int_col_2,_id_2]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/968 # # # テーブル A: フィールド t, r # テーブル B: フィールド p, t # # テーブル B から p の値を指定して t の値を読み込みたいです。 # これだけなら select t from B where p = hoge で済むと思います。 # # さらに条件を追加して、テーブルAにおいて t の値がそれに等しいようなレコードの数が最小なものを選ぶにはどのようにすればよいでしょうか? # # 例えば # テーブルAが (0, 1), (0, 2), (0, 3), (1, 1), (1, 2) # テーブルBが (0, 0), (0, 1), (1, 0), (1, 1), ... # となっていたら # (0), (1) # ではなく # (1) # だけを得たいです。 # # 'テーブル A: フィールド t, r テーブル B: フィールド p, t テーブル B から p の値を指定して t の値を読み込み テーブルAにおいて t の値がそれに等しいようなレコードの数が最小なものを選ぶ'(_p,_t) :- findall([Count,_t],( 'B'(_p,_t), count('A'(_t,_r),Count)), L), min(L,[Count,_]), member([Count,_t],L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/941 # # DBMS : Mysql # # 説明 # データは10万件あると想定します。 # 挿入する際に一つのワードを二つのカラムに大して重複チェックを行いたいです。 # どちらか片方にそのワードが含まれていたらcountで0を返す結果が欲しいです。 # # select count(*) from table where colA = 'ワード' OR colB = 'ワード' # これだと現在2秒程度かかるので高速化したいです。 # # よろしくお願いします。 # # '挿入する際に一つのワードを二つのカラムに大して重複チェックを行いたいです。どちらか片方にそのワードが含まれていたらcountで0を返す結果が欲しい'(_ワード,_colA,_colB) :- 'どちらか片方にそのワードが含まれていたらcountで0を返す結果が欲しい'(_ワード,_colA,_colB), assertz(table(_colA,_colB)). 'どちらか片方にそのワードが含まれていたらcountで0を返す結果が欲しい'(_ワード,_colA,_colB) :- count(( table(_colA,_colB), どちらかに片方にワードが存在(_ワード,_colA,_colB,Count)), 0). どちらかに片方にワードが存在(_ワード,_ワード,_) :- !. どちらかに片方にワードが存在(_ワード,_,_ワード) :- !. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/924 # # # 外部結合したテーブルに内部結合ってできます? # 例 # A 契約テーブル # B 顧客テーブル # C コードテーブル # # パターン1 # select # A.key # B.bangou # C.code # from # A.key = B.key(+) # B.code_key = C.code_key # # Bが存在しない場合 B.bangou、C.codeはNULLでとれてほしい # 無理でしょうか? # '外部結合したテーブルに内部結合'(_A_key,_B_bango,_c_code) :- 契約テーブル(_A_key), 顧客テーブル_1(_B_key,_B_code_key,_B_bango), _A_key = _B_key, コードテーブル_1(_c_code_key,_c_code), _B_code_key = _c_code_key. 顧客テーブル_1(_B_key,_B_code_key,_B_bango) :- 顧客テーブル(_B_key,_B_code_key,_B_bango),!. 顧客テーブル_1(_B_key,[],[]). コードテーブル_1(_c_code_key,_c_code) :- コードテーブル(_c_code_key,_c_code). コードテーブル_1([],[]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/890 # # 初心者ですが失礼いたします。 # ID | DATA | TIME # --+------ # 1 | aaa | 01:02 # 2 | bbb | 03:42 # 1 | ccc | 02:11 # 3 | bbb | 01:32 # # というデータがあるとしまして # タイムが早い順に並べ替えて重複するIDを除外(この場合は1) # するにはどのようなクエリを書けばよいのでしょうか? # # select * from table ORDER BY `time` DESC # でタイム順には並べることができていますが重複するID(人物) # を除外したいのです。 # # % findsetof/3 % findmin/3 % を参照してください。 'タイムが早い順に並べ替えて重複するIDを除外する'(_ID,_DATA,_TIME) :- findsetof(_ID,( テーブル(_ID,_DATA,_TIME)), L1), append(_,[_ID|_],L1), findmax([_TIME,_ID,_DATA],( テーブル(_ID,_DATA,_TIME)), [_TIME,_ID,_DATA]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/666 # # id id2 hoge # 1 1 a # 2 1 b # 3 1 c # 4 1 d # 5 2 a # 6 2 b # # こんなテーブルにselect * from test group by id2とやると # 4 1 d # 6 2 b # # が出ますが最初に登録した # 1 1 a # 5 2 b # # と出したいのですがどうしたらいいでしょうか? # # test(1,1,a). test(2,1,b). test(3,1,c). test(4,1,d). test(5,2,a). test(6,2,b). 'testテーブル上の、id2をキーにグループ参照をしてキー値を持つ最初の組のみを取り出す'(_id1,_id2,_hoge) :- 'testテーブル上の、id2をキーにグループ参照をして'(_キーならび), 'testテーブル上の、キー値を持つ最初の組のみを取り出す'(_キーならび,_id1,_id2,_hoge). 'testテーブル上の、id2をキーにグループ参照をして'(_キーならび) :- setof(_id2,[_id1,_id2,_hoge] ^ test(_id1,_id2,_hoge),_キーならび). 'testテーブル上の、キー値を持つ最初の組のみを取り出す'([_キー|R],_id1,_id2,_hoge) :- 'testテーブル上の、最初の組のみを取り出す'(_キー,_id1,_id2,_hoge). 'testテーブル上の、キー値を持つ最初の組のみを取り出す'([_|R],_id1,_id2,_hoge) :- 'testテーブル上の、キー値を持つ最初の組のみを取り出す'(R,_id1,_id2,_hoge). 'testテーブル上の、最初の組のみを取り出す'(_id2,_id1,_id2,_hoge) :- once(test(_id1,_id2,_hoge)). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/538 # # select *, tableid=1 from test # みたいに全てのカラムに加えてtableid=1を加えたものを取得したいのですが # どういうSQLかけばいいのでしょう? # *はidとnameが入ってるとしたらこんな感じのものを期待してます # # ++++++++++++++++++++ # + id + name + .tableid .+ # ++++++++++++++++++++ # + 1 .+ .加藤 +   1   + # ++++++++++++++++++++ # + 2 .+ .伊藤 +   1   + # ++++++++++++++++++++ # + 3 .+ .佐藤 +   1   + # ++++++++++++++++++++ # # 'select *, tableid=1 from test みたいに全てのカラムに加えてtableid=1を加えたものを取得する'(X) :- count(テーブル構造(_テーブル,_,_項目名),_項目数), length(L,_項目数), P =.. [_テーブル|L], call(P), append(L,['tableid=1'],X). % 以下のサイトは # 出典 :: SQL質疑応答スレ 11問目 #520 # SQLiteを使っています。 # # 顧客A(顧客idは100)さんの最新の購入物を表示したいのですが、 # select 顧客.顧客名, 購入物.顧客名 from 顧客 natural join 購入物 where 顧客id=100 order by 購入日 desc limit 1; # # っていま書いていますが、無駄が多い気がします。 # これを手直していただきたいのですが、よろしくお願いします。 # # 顧客(100,'A'). 購入物(100,'ORACLE Ver3.0','19840331'). 購入物(100,'Prolog-KABA','19841201'). '顧客A(顧客idは100)さんの最新の購入物を表示する'(_id,_顧客名,_最新の購入物) :- 顧客(_id,_顧客名), setof([_購入日,_購入物],[_購入日,_購入物] ^ 購入物(_id,_購入物,_購入日),LL), last(LL,[_,_最新の購入物]). ?- '顧客A(顧客idは100)さんの最新の購入物を表示する'(100,_顧客名,_最新の購入物). _顧客名 = 'A', _最新の購入分 = 'Prolog-KABA'. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/483 # # 全校学生健康診断表で # 身長の高い人50人を選ぶ場合 # select 学生ID, 学生名, 学生身長 from 健康診断表 order by 学生身長 desc limit 50 # とかでいいと思いますが # その次の50人を選ぶ場合はどうしたらいいのでしょうか? # # 身長の高い人50人づつ選ぶ場合 :- findall([_学生身長,_学生ID,_学生名],( 健康診断表(_学生ID,_学生名,_学生身長)), LL1), sort(LL1,LL2), reverse(LL2,LL3), 身長の高い人50人を選ぶ(LL3). 身長の高い人50人を選ぶ(LL) :- length(LL0,50), append(LL0,LL2,LL), append(_,[[_学生身長,_学生ID,_学生名]|R],LL0), writef('%t,%t,%t\n',[_学生ID,_学生名,_学生身長]), R = []. 身長の高い人50人を選ぶ(LL) :- length(LL0,50), append(LL0,LL2,LL), 身長の高い人50人を選ぶ(LL2). 身長の高い人50人を選ぶ(LL) :- append(_,[[_学生身長,_学生ID,_学生名]|R],LL), writef('%t,%t,%t\n',[_学生ID,_学生名,_学生身長]), R = []. 身長の高い人50人を選ぶ([]). % 以下のサイトは # 問4 # # 以下のプログラムを作成せよ. # # 入力 # 正整数n,ならびにn個の名前と電話番号の組,および文字列. # ただし,いずれの入力文字列も長さ20以下と仮定して良い. # 処理 # 構造体型配列で電話帳を作成し,名前をキーとして, # 文字列がselectionのときは選択ソート,文字列がbubbleのときは # バブルソートをする. # 出力 # 名前をキーとして辞書順にソートされた電話帳.同名の人は,どの順序に # 出力してもよい. # # 実行例 # 人数 > 2 # 0人目:名前 > bbb # 電話番号 > 111 # 1人目:名前 > aaa # 電話番号 > 222 # # 文字列 > selection # # aaa, 222 # bbb, 111 # # 実行例 # 人数 > 5 # 0人目:名前 > Taro # 電話番号 > 090-111-1111 # 1人目:名前 > Hanako # 電話番号 > 090-222-2222 # 2人目:名前 > Ichiro # 電話番号 > 090-333-3333 # 3人目:名前 > Jiro # 電話番号 > 090-444-4444 # 4人目:名前 > Hanayo # 電話番号 > 090-555-5555 # # 文字列 > bubble # # Hanako, 090-222-2222 # Hanayo, 090-555-5555 # Ichiro, 090-333-3333 # Jiro, 090-444-4444 # Taro, 090-111-1111 プログラム :- 入力(_正整数n,_n個の名前ならび,_電話番号の組,_および文字列), 処理(_文字列,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組), 出力(_名前をキーとして整列されたn個の名前と電話番号の組). 入力(_正整数n,_n個の名前ならび,_電話番号の組,_および文字列) :- '正整数n,ならびにn個の名前と電話番号の組,および文字列.ただし,いずれの入力文字列も長さ20以下と仮定して良い.'(_正整数n,_n個の名前ならび,_電話番号の組,_および文字列). '正整数n,ならびにn個の名前と電話番号の組,および文字列.ただし,いずれの入力文字列も長さ20以下と仮定して良い.'(_正整数n,_n個の名前ならび電話番号の組,_および文字列) :- 正整数nの入力(_正整数n), n個の名前と電話番号の組の入力(_正整数n,_n個の名前と電話番号の組), および文字列の入力(_文字列). '正整数nの入力'(_正の整数n) :- write('正の整数を入力してください : '), get_integer(_正の整数n), _正の整数n > 0,!. n個の名前と電話番号の組の入力(_正整数n,_n個の名前と電話番号の組) :- length(_n個の名前と電話番号の組,_正整数n), findall([_名前,_電話番号],( append(L0,[_|_],_n個の名前と電話番号の組), length([_|L0],_人目), writef('%t人目 : ',[_人目]), 名前の入力(_名前), 電話番号の入力(_電話番号)), _n個の名前と電話番号の組). 名前の入力(_名前) :- write('名前を入力してください : '), get_line(_名前). 電話番号の入力(_電話番号) :- write('電話番号を入力してください : '), get_line(_電話番号). および文字列の入力(_文字列) :- write('selection or bubble : '), get_line(_文字列). 処理(_文字列,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組) :- '名前をキーとして,文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをする.'.(_文字列,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組). '名前をキーとして,文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをする.'(selection,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組) :- 選択ソート(_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組). '名前をキーとして,文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをする.'(bubble,_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組) :- バブルソート(_n個の名前と電話番号の組,_名前をキーとして整列されたn個の名前と電話番号の組). 出力(_名前をキーとして整列されたn個の名前と電話番号の組) :- '名前をキーとして辞書順にソートされた電話帳.同名の人は,どの順序に出力してもよい.'(_名前をキーとして整列されたn個の名前と電話番号の組). '名前をキーとして辞書順にソートされた電話帳.同名の人は,どの順序に出力してもよい.'(_名前をキーとして整列されたn個の名前と電話番号の組) :- append(_,[[_名前,_電話番号]|R],_名前をキーとして整列されたn個の名前と電話番号の組), writef('%t, %t\n',[_名前,_電話番号]), R = []. 選択ソート([A],[A]) :- !. 選択ソート(L1,[N|R2]) :- append(L0,[N|R],L1), \+((member(N1,L0),N1 @> N)), \+((member(N2,R),N2 @> N)), swap(L0,[N|R],R1), 選択ソート(R1,R2). swap([],[N|R],R) :- !. swap(L0,[N|R],R1) :- L0=[S|R0], append(R0,[S|R],R1). バブルソート(_対象ならび,_整列済みならび) :- 交換(_対象ならび,_対象ならびの一),!, バブルソート(_対象ならびの一,_整列済みならび). バブルソート(_整列済みならび,_整列済みならび). 交換([],[]) :- !,fail. 交換([A,B|R],[B,A|R]) :- A @> B,!. 交換([A|R1],[A|R2]) :- 交換(R1,R2). % 以下のサイトは # 問3 # 正整数n,n個の長さ20以下の文字列,および文字列sを読み込み, # 文字列sがselectionのときは選択ソート,文字列がbubbleのときは # バブルソートをして,文字列型配列を辞書順に出力するプログラムを作成せよ. # 文字列を入れ替えるのに,以下の関数swap()を用いてもよい. # # 実行例 # 整数 > 3 # 0番目の文字列 > b # 1番目の文字列 > c # 2番目の文字列 > a # 文字列 > bubble # a # b # c # # # 実行例 # 整数 > 7 # 0番目の文字列 > Blake # 1番目の文字列 > Leighton # 2番目の文字列 > Taylor # 3番目の文字列 > Jessica # 4番目の文字列 > Penn # 5番目の文字列 > Chace # 6番目の文字列 > Ed # 文字列 > selection # Blake # Chace # Ed # Jessica # Leighton # Penn # Taylor # '正整数n,n個の長さ20以下の文字列,および文字列sを読み込み,文字列sがselectionのときは選択ソート,文字列がbubbleのときはバブルソートをして,文字列型配列を辞書順に出力する' :- '正整数nの読み込み'(_正の整数n), 'n個の長さ20以下の文字列の読み込み'(_正の整数n,_n個の長さ20以下の文字列ならび), 'および文字列sを読み込み'(_文字列s), '文字列sがselectionのときは選択ソート,文字列がbubbleのときはバブルソートをして,文字列型配列を辞書順に出力する'(_文字列s,_n個の長さ20以下の文字列ならび). '正整数nの読み込み'(_正の整数n) :- write('正の整数を入力してください : '), get_integer(_正の整数n), _正の整数n > 0,!. 'n個の長さ20以下の文字列の読み込み'(_正の整数n,_n個の長さ20以下の文字列ならび) :- length(_n個の長さ20以下の文字列ならび,_正の整数n), findall(_文字列,( append(L0,[_|_],_n個の長さ20以下の文字列ならび), get_line(_文字列)), _n個の長さ20以下の文字列ならび). '文字列sがselectionのときは選択ソート,文字列がbubbleのときはバブルソートをして,文字列型配列を辞書順に出力する'(selection,_n個の長さ20以下の文字列ならび) :- 選択ソート(_n個の長さ20以下の文字列ならび,_辞書順に整列されたn個の長さ20以下の文字列ならび), 出力する(_辞書順に整列されたn個の長さ20以下の文字列ならび). 出力する(_辞書順に整列されたn個の長さ20以下の文字列ならび) :- append(_,[_文字列|R],_辞書順に整列されたn個の長さ20以下の文字列ならび), writef('%t\n',[_文字列]), R = []. 辞書順選択ソート([A],[A]) :- !. 辞書順選択ソート(L1,[_文字列|R2]) :- append(L0,[_文字列|R],L1), \+((member(文字列1,L0),辞書コード比較(_文字列,_文字列1))), \+((member(文字列2,R),辞書コード比較(_文字列,_文字列2))), swap(L0,[_文字列|R],R1), 辞書順選択ソート(R1,R2). swap([],[N|R],R) :- !. swap(L0,[N|R],R1) :- L0=[S|R0], append(R0,[S|R],R1). 辞書順バブルソート(_対象ならび,_整列済みならび) :- 辞書順交換(_対象ならび,_対象ならびの一),!, 辞書順バブルソート(_対象ならびの一,_整列済みならび). 辞書順バブルソート(_整列済みならび,_整列済みならび). 辞書順交換([],[]) :- !,fail. 辞書順交換([A,B|R],[B,A|R]) :- 辞書コード比較(A,B),!. 辞書順交換([A|R1],[A|R2]) :- 辞書順交換(R1,R2). 辞書コード比較(_文字列1,_文字列2) :- atom_to_codes(_文字列1,Codes1), 辞書順用にコード列を変換する(Codes1,_変換されたCodes1), atom_to_codes(_文字列2,Codes2), 辞書順用にコード列を変換する(Codes2,_変換されたCodes2), _変換されたCoode1 @> _変換されたCodes2,!. 辞書順用にコード列を変換する([],[]) :- !. 辞書順用にコード列を変換する([A|R1],[B|R2]) :- A >= 32, A =< 90, B is (A + 32) * 10, 辞書順用にコード列を変換する(R1,R2),!. 辞書順用にコード列を変換する([A|R1],[B|R2]) :- B is A * 10 + 1, 辞書順用にコード列を変換する(R1,R2),!. 辞書順用にコード列を変換する([A|R1],[B|R2]) :- B is A * 10, 辞書順用にコード列を変換する(R1,R2),!. % 以下のサイトは # 問2 # 正整数n,n個の実数,および文字列を読み込み,文字列がselectionのときは # 選択ソート,文字列がbubbleのときはバブルソートをして, # 使用したソートアルゴリズムと降順にソートされた実数型配列を # 出力するプログラムを作成せよ.以下のコードを穴埋めして,用いても良い. # # 実行例 # 整数 > 10 # 0番目の実数 > 3.3 # 1番目の実数 > 4.4 # 2番目の実数 > 2.2 # 3番目の実数 > 1.1 # 4番目の実数 > 0.0 # 5番目の実数 > 9.9 # 6番目の実数 > 8.8 # 7番目の実数 > 5.5 # 8番目の実数 > 7.7 # 9番目の実数 > 6.6 # 文字列 > selection # 選択ソート # 9.900000 # 8.800000 # 7.700000 # 6.600000 # 5.500000 # 4.400000 # 3.300000 # 2.200000 # 1.100000 # 0.000000 # # 実行例 # 整数 > 10 # 0番目の実数 > 3.3 # 1番目の実数 > 4.4 # 2番目の実数 > 2.2 # 3番目の実数 > 1.1 # 4番目の実数 > 0.0 # 5番目の実数 > 9.9 # 6番目の実数 > 8.8 # 7番目の実数 > 5.5 # 8番目の実数 > 7.7 # 9番目の実数 > 6.6 # 文字列 > bubble # バブルソート # 9.900000 # 8.800000 # 7.700000 # 6.600000 # 5.500000 # 4.400000 # 3.300000 # 2.200000 # 1.100000 # 0.000000 # '正整数n,n個の実数,および文字列を読み込み,文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをして,使用したソートアルゴリズムと降順にソートされた実数型配列を出力する' :- '正整数n,n個の実数,および文字列を読み込み'(_正整数n,_n個の実数ならび,_文字列), '文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをして'(_文字列,_n個の実数ならび,_降順に整列されたn個の実数ならび), '使用したソートアルゴリズムと降順にソートされた実数型配列を出力する'(_文字列,_降順に整列されたn個の実数ならび). '正整数n,n個の実数,および文字列を読み込み'(_正整数n,_n個の実数ならび,_文字列) :- '正整数nを読み込み'(_正の整数n), 'n個の実数を読み込み'(_正の整数n,_n個の実数ならび), '文字列を読み込み'(_文字列). '正整数nを読み込み'(_正の整数n) :- write('正の整数を入力してください : '), get_integer(_正の整数n), _正の整数n > 0,!. 'n個の実数を読み込み'(_正の整数n,_n個の実数ならび) :- length(_n個の実数ならび,_正の整数n), findall(_実数,( append(_,[_|_],__n個の実数ならび), 実数を読み込む(_実数)), _n個の実数ならび). 実数を読み込む(_実数) :- write('実数を入力してください : '), get_line(Line), 実数入力診断(Line,_実数),!. 実数を読み込む(_実数) :- 実数を読み込む(_実数). 実数入力診断(Line,_実数) :- atom_to_term(Line,_実数,_), number(_実数),!. 実数入力診断(Line,_実数) :- writef('入力された%tからは実数が得られません。再入力をお願いします。\n',[Line]), fail. '文字列を読み込み'(_文字列) :- get_line(_文字列). '文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをして'(selection,_n個の実数ならび,_降順に整列されたn個の実数ならび) :- 降順選択ソート(_n個の実数ならび,_降順整列されたn個の実数ならび),!. '文字列がselectionのときは選択ソート,文字列がbubbleのときはバブルソートをして'(bubble,_n個の実数ならび,_降順に整列されたn個の実数ならび) :- 降順バブルソート(_n個の実数ならび,_降順に整列されたn個の実数ならび),!. '使用したソートアルゴリズムと降順にソートされた実数型配列を出力する'(selection,_降順整列されたn個の実数ならび) :- listing(降順選択ソート/2), listing(降順swap/3), 出力する(_降順に整列されたn個の実数ならび). '使用したソートアルゴリズムと降順にソートされた実数型配列を出力する'(bubble,_降順に整列されたn個の実数ならび) :- listing(降順バブルソート/2), listing(降順交換/2), 出力する(_降順に整列されたn個の実数ならび). 出力する(_降順に整列されたn個の実数ならび) :- append(_,[_実数|R],_降順に整列されたn個の実数ならび), writef('%t\n',[_実数]), R = []. 降順選択ソート([],[]) :- !. 降順選択ソート([A],[A]) :- !. 降順選択ソート(L1,[N|R2]) :- append(L0,[N|R],L1), \+((member(N1,L0),N1 @< N)), \+((member(N2,R),N2 @< N)), swap(L0,[N|R],R1), 降順選択ソート(R1,R2). swap([],[N|R],R) :- !. swap(L0,[N|R],R1) :- L0=[S|R0], append(R0,[S|R],R1). 降順バブルソート(_対象ならび,_整列済みならび) :- 降順交換(_対象ならび,_対象ならびの一),!, 降順バブルソート(_対象ならびの一,_整列済みならび). 降順バブルソート(_整列済みならび,_整列済みならび). 降順交換([],[]) :- !,fail. 降順交換([A,B|R],[B,A|R]) :- A @< B,!. 降順交換([A|R1],[A|R2]) :- 交換(R1,R2). % 以下のサイトは # データ列中で一番小さい値を探し、1番目の要素と交換する。 # 次に、2番目以降のデータ列から一番小さい値を探し、2番目の要素と交換する。 # これを、データ列の最後まで繰り返す(厳密には、データ列の最後より1つ手前まで # の繰り返しでよい。一つ前まで交換済みであれば、最後(残り)は必ず最大値に # なるからである)。大小が入れ替わる降順の場合も同様の手法。 # 実装例 [編集] # for(i=0; idata[j])min = j ; # swap(data[i],data[min]) ; # } # 動作例 [編集] # 初期データ: 8 4 3 7 6 5 2 1  # 太字はソート完了した部分 # 1 4 3 7 6 5 2 8 (1回目のループ終了時) # 1 2 3 7 6 5 4 8 (2回目のループ終了時) # 1 2 3 7 6 5 4 8 (3回目のループ終了時) # 1 2 3 4 6 5 7 8 (4回目のループ終了時) # 1 2 3 4 5 6 7 8 (5回目のループ終了時) # この例では、一見して、この時点で既にソート完了したとわかる。 # しかしデータが多数の場合はそうはいかないし、アルゴリズムで # 「一見して」ソート完了か否か判断できない。アルゴリズム通りに最後まで # 処理する必要がある。 # 1 2 3 4 5 6 7 8 (6回目のループ終了時) # 1 2 3 4 5 6 7 8 (7回目のループ終了時) 選択ソート([],[]) :- !. 選択ソート([A],[A]) :- !. 選択ソート(L1,[N|R2]) :- append(L0,[N|R],L1), \+((member(N1,L0),N1 @< N)), \+((member(N2,R),N2 @< N)), swap(L0,[N|R],R1), 選択ソート(R1,R2). swap([],[N|R],R) :- !. swap(L0,[N|R],R1) :- L0=[S|R0], append(R0,[S|R],R1). % 以下のサイトは # # select(X, Ys, Zs) : リストYsからXを取り除いたリストがZs # リストYsからXを取り除いたリストがZs(X,Ys,Zs) :- append(L0,[X|R],Ys), append(L0,R,Ys). % 以下のサイトは # テーブル: # no comment id(テーブル名:テーブル) # 1 aaaaa 春 # 2 bbbbb 夏 # 3 ccccc 春 # 4 ddddd 春 # : # # 欲しい結果: # no comment id count(*) # 3 ccccc 春 2 # # # idが春のものの数を集計したく、 # select *,count(*) from baka group by id where id = '春'; # でそれは可能なんですが、selectで取れる他の結果(commentとか)は、noが3のものを表示したいんです # % 別々に計算するつもりで、定義する。 テーブル(1,aaaaa,春). テーブル(2,bbbbb,夏). テーブル(3,ccccc,春). テーブル(4,ddddd,春). 節を取得時に集約値を併記する(_no,_comment,_id,_度数) :- テーブル(_no,_comment,_id), count(テーブル(_,_,_id)),_度数). count(P,C) :- findall(1,P,L), length(L,C). ?- 節を取得時に集約値を併記する(_no,_comment,春,_度数). _no = 1, _comment = aaaaa, _度数 = 3; _no = 3, _comment = ccccc, _度数 = 3; _no = 4, _comment = ddddd, _度数 = 3; false. % 以下のサイトは ならびの全分割(_ならび,_全分割されたならび) :- reverse(_ならび,_反転されたならび), ならびの全分割(_反転されたならび,[],_全分割されたならび). ならびの全分割([],_全分割,_全分割). ならびの全分割([_要素_1|_残り要素ならび],_組み上がる全分割,_全分割) :- '_要素_1を除いた全分割から_全分割ならび_2を取り出して組み上がる全分割を_全分割ならび_2とする'(_分割ならび_2,_組み上がる全分割,_全分割ならび_2), ならびの全分割(_残り要素ならび,[[_要素_1|_分割ならび_2]|_全分割ならび_2],_全分割). ならびの全分割([_要素|_残り要素ならび],_全分割_1,_全分割) :- '_残り要素ならびによる_全分割_1の組み上げが完成したら_要素だけのならびを先頭に付加する'(_要素,_残り要素ならび,_全分割_1,_全分割). '_要素_1を除いた全分割から_全分割ならび_2を取り出して組み上がる全分割を_全分割ならび_2とする'(_分割ならび_2,_組み上がる全分割,_全分割ならび_2) :- select(_分割ならび_2,_組み上がる全分割,_全分割ならび_2). '_残り要素ならびによる_全分割_1の組み上げが完成したら_要素だけのならびを先頭に付加する'(_要素,_残り要素ならび,_全分割_1,_全分割) :- ならびの全分割(_残り要素ならび,[[_要素]|_全分割_1],_全分割). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/119 # # SQL初心者で申し訳ありませんが、以下のテーブルでid1を元に、val1とval2のデータを取得したいのですが # どのようにselectをすればよいでしょうか? # # # ・tabel1 # int id1 # int id2 # text val1 # # ・table2 # int id2 # text val2 # # 'id1を元に、val1とval2のデータを取得したいのですが'(_id1,_id2,_val1,_val2) :- table1(_id1,_id2,_val1), table2(_id2,_val2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/97 # # select * from table1 where col1 in (select colx, coly from table2); # # 的な書き方は無い? # ↓ってするしかない? # # select * from table1 where col1 in (select colx from table2) or col1 in (select coly from table2) ; # # 'select * from table1 where col1 in (select colx from table2) or col1 in (select coly from table2)'(L1) :- テーブルの選択(table1,[col1],[_col1],L1,P1), テーブルの選択(table2,[colx,coly],[_colx,_coly],L2,P2), P1, P2, 選択条件(_col1,_colx,_coly). 選択条件(X,X,_) :- !. 選択条件(X,_,X) :- !. %%% テーブルが生成される時に定義される %%% テーブル構造(table1,1,col1). テーブル構造(table2,1,colx). テーブル構造(table2,2,coly). %%% 汎用述語 %%% テーブルの選択(_テーブル名,_鍵名ならび,_鍵変数ならび,L,P) :- findall(_,テーブル構造(_テーブル名,_,_),L), P =.. [_テーブル名|L], 鍵変数の指定(_テーブル名,L,_鍵名ならび,_鍵変数ならび). 鍵変数の指定(_テーブル名,L,[],[]) :- !. 鍵変数の指定(_テーブル名,L,[_鍵名|R1],[_鍵変数|R2]) :- テーブル構造(_テーブル名,_位置,_鍵名), list_nth(_位置,L,_鍵変数), 鍵変数の指定(_テーブル名,R1,R2,L). % 以下のサイトは # 出典::MySQL 総合 Part19 #173 # 質問させてください # selectしたデータを一部だけ別のテーブルに入れる方法ってありますか? # # 例:insert into table2 (aaa,bbb,ccc) select aaa as aaa,bbb as bbb,ccc as ccc from table1 # この場合table1のデータがすべてtable2に入るのでaaaだけ別のデータを入れたいと思っています。 # よろしくお願いします。 # # :- dynamic(table2/3). 海に接していない都道府県名([栃木県,群馬県,埼玉県,山梨県,長野県,岐阜県,滋賀県,奈良県]). table1(東京都,1000,aa). table1(埼玉県,2000,ab). table1(新潟県,3000,ac). table1(奈良県,2000,ad). selectしたデータを一部だけ別のテーブルに入れる方法 :- 海に接していない都道府県名(_海に接していない都道府県名ならび), selectしたデータを一部だけ別のテーブルに入れる方法(_海に接していない都道府県名ならび) :- forall(( table1の海に接している都道府県名を海に接していない都道府県名に置き換える(_海に接していない都道府県名ならび,_都道府県名の二,_bbb,_ccc), assertz(table2(_都道府県名の二,_bbb,_ccc))). table1の海に接している都道府県名を海に接していない都道府県名に置き換える(_海に接していない都道府県名ならび,_都道府県名の二,_bbb,_ccc) :- table1(_都道府県名の一,_bbb,_ccc), 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二). 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の一) :- 都道府県名の一が海に接していない場合はそのまま(_海に接していない都道府県名ならび,_都道府県名の一),!. 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二) :- 'table2に未出の都道府県名を_海に接していない都道府県名ならび から得る'(_海に接していない都道府県名ならび,_都道府県名の二),!. 都道府県名の一が海に接していない場合はそのまま(_海に接していない都道府県名ならび,_都道府県名の一) :- member(_都道府県名の一,_海に接していない都道府県名ならび),!. 'table2に未出の都道府県名を_海に接していない都道府県名ならび から得る'(_海に接していない都道府県名ならび,_都道府県名の二) :- 海に接していない都道府県名から_aaaを一つ選択する(_海に接していない都道府県名ならび,R,_aaa), 'table2に未出の都道府県名を_海に接していない都道府県名ならび から得る'(_海に接していない都道府県名ならび,R,_aaa,_都道府県名の二). 海に接していない都道府県名から_aaaを一つ選択する(_海に接していない都道府県名ならび,R,_aaa) :- 乱数を得る(_海に接していない都道府県名ならび,_乱数), nth1(_乱数,_海に接していない都道府県名ならび,_aaa), select(_aaa,_海に接していない都道府県名ならび,R). 乱数を得る(_海に接していない都道府県名ならび,_乱数) :- length(_海の接していない都道府県名ならび,_要素数), _要素数 > 0, _乱数 is random(_要素数) + 1, 'table2に未出の都道府県名を_海に接していない都道府県名ならび から得る'(_海に接していない都道府県名ならび,R,_都道府県名の二,_都道府県名の二) :- table2にその都道府県名は未出である(_都道府県名の二),!. 'table2に未出の都道府県名を_海に接していない都道府県名ならび から得る'(_海に接していない都道府県名ならび,R,_都道府県名の一,_都道府県名の二) :- 新しい都道府県名の生成(R,_都道府県名の一,_都道府県名の二). table2にその都道府県名は未出である(_都道府県名の二) :- \+(table2(_都道府県名の二,_,_)). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/15 # # select id, info_date from t_information order by info_date desc; # というクエリで、 # +----+---------------------+ # | id | info_date | # +----+---------------------+ # | 18 | 2011-03-03 17:00:00 | # | 17 | 2011-03-03 15:00:00 | # | 16 | 2011-03-01 10:00:00 | # | 4 | 2011-01-13 14:00:00 | # | 3 | 2011-01-13 07:00:00 | # | 2 | 2011-01-13 03:00:00 | # | 1 | 2011-01-13 00:00:00 | # | 15 | 2011-01-12 00:00:00 | # +----+---------------------+ # というデータの場合に # info_dateを基準に目的idの次のidを取得したいです。 # 例えば目的idが15とすると、1を取得したいです。 # # mysqlです。 # よろしくおねがいします。 # t_information(18,'2011-03-03 17:00:00'). t_information(17,'2011-03-03 15:00:00'). t_information(16,'2011-03-01 10:00:00'). t_information( 4,'2011-01-13 14:00:00'). t_information( 3,'2011-01-13 07:00:00'). t_information( 2,'2011-01-13 03:00:00'). t_information( 1,'2011-01-13 00:00:00'). t_information(15,'2011-01-12 00:00:00'). 'キー値を基準に目的idの次のidを取得する'(_キー値,_id) :- findmin([_info_date,_id],( t_information(_id,_info_date), _info_date @> _キー値), [_info_date,_id]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/8 # # よくある質問3 # # (問) # ID HOGE # 01 A # 01 B # 01 C # 02 A # 03 B # # HOGEをAもBもCも持っている、ID:01だけ取り出すにはどうすればよかですか # # (答1) # SELECT id # FROM TableName # WHERE hoge in ('A','B','C') # GROUP BY id # HAVING count(DISTINCT hoge) = 3 # ; # # (答2) # select * # from TableName T1 # where not exists (select * #          from (values 'A', 'B', 'C') T2 (HOGE) #          where not exists (select * #                   from TableName T3 #                   where T1.ID = T3.ID #                   and T2.HOGE = T3.HOGE #                   ) #          ) # ; # ※valuesの部分(Table Value Constructor)はDBMSによって文法がかなり違うので注意 # # 'HOGEをAもBもCも持っている、ID:01だけ取り出す'(L,_ID) :- findsetof(_ID,'TableName'(_ID,_)), 関係の割り算(_ID,L). 関係の割り算(_,[]):- !. 関係の割り算(_ID,[_HOGE|R]) :- 'TableName'(_ID,_HOGE), 関係の割り算(_ID,R). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/6 # # よくある質問1 # # (問) # ID | DATE     | DATA # --+----------+----- # 1 | 2007-11-11 | aaa # 2 | 2007-11-11 | bbb # 1 | 2007-11-10 | ccc # 3 | 2007-11-12 | ddd # 3 | 2007-11-11 | eee # 4 | 2007-11-10 | fff # 1 | 2007-11-12 | ggg # # このようなテーブルから、下記のように # # 1 | 2007-11-12 | ggg # 3 | 2007-11-12 | ddd # 2 | 2007-11-11 | bbb # 4 | 2007-11-10 | fff # # 各idに対して最新の1件だけ抽出するSQLの書き方を教えてください。 # # (答) # select A.ID, #     A.DATE, #     A.DATA # from TableName A #    inner join #    (select ID, max(DATE) as MAX_DATE #     from TableName #     group by ID #    ) B #    on A.ID = B.ID #    and A.DATE = B.MAX_DATE # ; # 'TableName'(1,'2007-11-11',aaa). 'TableName'(2,'2007-11-11',bbb). 'TableName'(1,'2007-11-10',ccc). 'TableName'(3,'2007-11-12',ddd). 'TableName'(3,'2007-11-11',eee). 'TableName'(4,'2007-11-10',fff). 'TableName'(1,'2007-11-12',ggg). '各idに対して最新の1件だけ抽出する'(_ID,_DATE,_DATA) :- findsetof(_ID,'TableName'(_ID,_,_),L1), append(_,[_ID|_],L1), findmax([_DATE,_ID,_DATA],( 'TableName'(_ID,_DATE,_DATA)), [_DATE,_ID,_DATA]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/923 # # 初歩的ですみません、相関副問合せでinの仕組みを教えてください。 # # in句の使いかたとして、 # select * from テーブル where フィールド1 in (値1,値2,値3) # みたいな使い方は素直に読めるのですが、 # # # 社員テーブル syain # id | name | busyoid | # ------------------ # 1  | yamada |100 | # 2  | satou |100 | # 3  | suzuki |200 | # # 部所テーブル busyo # busyoid | busyomei | # ------------------ # 100 | soumu | # 200 | eigyo | # # の2つのテーブルで、総務所属の人のみ抽出するとき、 # # select * from syain where 'soumu' in (select busyomei from busyo where busyo.busyoid = syain.busyoid) # # で答えが出るとき、where 'soumu' in(select文)のin句の使い方はどう理解すれば良いのでしょうか。 # 'select * from syain where ''soumu'' in (select busyomei from busyo where busyo.busyoid = syain.busyoid) をどう理解すればよいか'(_id,_name,_bushoid) :- 社員テーブル(_id,_name,_busyoid), findall(_busyomei,部署テーブル(_busyoid,_busyomei),L), member(soumu,L). 社員テーブル(1,yamada,100). 社員テーブル(2,satou,100). 社員テーブル(3,suzuki,200). 部所テーブル(100,soumu). 部所テーブル(200,eigyo). テーブル構造(社員テーブル,1,id). テーブル構造(社員テーブル,2,name). テーブル構造(社員テーブル,3,busyoid). テーブル構造(部所テーブル,1,busyoid). テーブル構造(部所テーブル,2,busyomei). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/773 # # sqlite3を使用しています。 # 並び変えたデータの100番目以降を消したいのですが方法が見つかりません。 # どなたか分かる方がいましたらよろしくお願いします。 # # delete from TableName where KEY_COLUMN in (select KEY_COLUMN from TableName order by ORDER_COLUMN limit -1 offset 100); # '定義節のN番目以降をすべて削除する'(N番目,_述語名/_アリティ) :- 定義節をならびに写し取る(_述語名/_アリティ,_定義節ならび), 先頭からN番目の節までを切り取る(N番目,_定義節ならび,_先頭からN番目までの定義節ならび), 一旦述語定義を解消する(_述語名/_アリティ), 述語を定義し直す(_先頭からN番目までの定義節ならび),!. 定義節をならびに写し取る(_述語名/_アリティ,_定義節ならび) :- length(L,_アリティ), P =.. [_述語名|L], findall([(P :- Q),Varlist],( clause_with_names(P,Q,Varlist)), _定義節ならび),!. 先頭からN番目の節までを切り取る(N番目,_定義節ならび,_先頭からN番目までの定義節ならび) :- length(_先頭からN番目までの定義節ならび,N番目), append(_先頭からN番目までの定義節ならび,_,_定義節ならび),!. 一旦述語定義を解消する(_述語名/_アリティ) :- abolish(_述語名/_アリティ). 述語を定義し直す(先頭からN番目までの定義節ならび) :- append(_,[[(P :- Q),Varlist]|R],_先頭からN番目までの定義節ならび), assertz_with_names((P :- Q),Varlist), R = []. % 以下のサイトは 和暦西暦変換(_和暦,_西暦) :- 西暦が整数の時は西暦から和暦を得る(_和暦,_西暦). 和暦西暦変換(_和暦,_西暦) :- 和暦が文字列の時は和暦から西暦を得る(_西暦,_和暦). 西暦が整数の時は西暦から和暦を得る(_西暦,_和暦) :- 西暦が整数の時は(_西暦), 西暦から和暦を得る(_西暦,_和暦). 西暦が整数の時は(_西暦) :- integer(_西暦). 西暦から和暦を得る(_和暦,_西暦) :- 西暦から年間と年を得る(_西暦,_年間,_年), 和暦年文字列(_年間,_年,_和暦). 西暦から年間と年を得る(_西暦,_年間,_年) :- 年間(_年間,_元年,_最終年), between(_元年,_最終年,_西暦), _年 is _西暦 - _元年 + 1. 和暦が文字列の時は和暦から西暦を得る(_和暦,_西暦) :- 和暦が文字列の時は(_和暦), 和暦の年と元年の西暦を抽出(_和暦,_年間,_年,_元年), _西暦 is _元年 + _年 - 1. 和暦が文字列の時は(_和暦) :- atom(_和暦). 和暦の年と元年の西暦を抽出(_和暦,_年間,_年,_元年) :- sub_atom(_和暦,_,_,_,_年間,S2,年,L1,L2,L3), 年間(_年間,_元年,_最終年), 漢数字アラビア数字対応(L2,_年). 和暦年文字列(_年間,_年,_和暦年) :- _年 =< 10, nth1(_年,[元,二,三,四,五,六,七,八,九,十],A), concat_atom([_年間,A,年],_和暦年),!. 和暦年文字列(_年間,_年,_和暦年) :- _年 >= 11, Div is _年 // 10, Mod is (_年 mod 10) + 1, nth1(Div,['',二,三,四,五,六,七,八,九],A), nth1(Mod,['',一,二,三,四,五,六,七,八,九],B), concat_atom([_年間,A,十,B,年],_和暦年),!. 漢数字アラビア数字対応('',0). 漢数字アラビア数字対応(元,1). 漢数字アラビア数字対応(一,1). 漢数字アラビア数字対応(二,2). 漢数字アラビア数字対応(三,3). 漢数字アラビア数字対応(四,4). 漢数字アラビア数字対応(五,5). 漢数字アラビア数字対応(六,6). 漢数字アラビア数字対応(七,7). 漢数字アラビア数字対応(八,8). 漢数字アラビア数字対応(九,9). 漢数字アラビア数字対応([A,十,B],N) :- 漢数字アラビア数字対応(A,N1), 漢数字アラビア数字対応(B,N2), N is N1 * 10 + N2,!. 漢数字アラビア数字対応([A,十],N) :- 漢数字アラビア数字対応(A,N1), N is N1 * 10,!. 漢数字アラビア数字対応([十,B],N) :- 漢数字アラビア数字対応(B,N2), N is 10 + N2,!. 漢数字アラビア数字対応([十],10) :- !. 漢数字アラビア数字対応([A],N) :- 漢数字アラビア数字対応(A,N). 年間(大化,645,650). 年間(白雉,650,654). 年間(朱鳥,686,687). 年間(大宝,701,704). 年間(慶雲,704,708). 年間(和銅,708,715). 年間(霊亀,715,717). 年間(養老,717,724). 年間(神亀,724,729). 年間(天平,729,749). 年間(天平感宝,749,749). 年間(天平勝宝,749,757). 年間(天平宝字,757,765). 年間(天平神護,765,767). 年間(神護景雲,767,770). 年間(宝亀,770,780). 年間(天応,781,782). 年間(延暦,782,806). 年間(大同,806,810). 年間(弘仁,810,824). 年間(天長,824,834). 年間(承和,834,848). 年間(嘉祥,848,851). 年間(仁寿,851,854). 年間(斉衡,854,857). 年間(天安,857,859). 年間(貞観,859,877). 年間(元慶,877,885). 年間(仁和,885,889). 年間(寛平,889,898). 年間(昌泰,898,901). 年間(延喜,901,923). 年間(延長,923,931). 年間(承平,931,938). 年間(天慶,938,947). 年間(天暦,947,957). 年間(天徳,957,961). 年間(応和,961,964). 年間(康保,964,968). 年間(安和,968,970). 年間(天禄,970,973). 年間(天延,973,976). 年間(貞元,976,978). 年間(天元,978,983). 年間(永観,983,985). 年間(寛和,985,987). 年間(永延,987,989). 年間(永祚,989,990). 年間(正暦,990,995). 年間(長徳,995,999). 年間(長保,999,1004). 年間(寛弘,1004,1012). 年間(長和,1012,1017). 年間(寛仁,1017,1021). 年間(治安,1021,1024). 年間(万寿,1024,1028). 年間(長元,1028,1037). 年間(長暦,1037,1040). 年間(長久,1040,1044). 年間(寛徳,1044,1046). 年間(永承,1046,1053). 年間(天喜,1053,1058). 年間(康平,1058,1065). 年間(治暦,1065,1069). 年間(延久,1069,1074). 年間(承保,1074,1077). 年間(承暦,1077,1081). 年間(永保,1081,1084). 年間(応徳,1084,1087). 年間(寛治,1087,1094). 年間(嘉保,1094,1096). 年間(永長,1096,1097). 年間(承徳,1097,1099). 年間(康和,1099,1104). 年間(長治,1104,1106). 年間(嘉承,1106,1108). 年間(天仁,1108,1110). 年間(天永,1110,1113). 年間(永久,1113,1118). 年間(元永,1118,1120). 年間(保安,1120,1124). 年間(天治,1124,1126). 年間(大治,1126,1131). 年間(天承,1131,1132). 年間(長承,1132,1135). 年間(保延,1135,1141). 年間(永治,1141,1142). 年間(康治,1142,1144). 年間(天養,1144,1145). 年間(久安,1145,1151). 年間(仁平,1151,1154). 年間(久寿,1154,1156). 年間(保元,1156,1159). 年間(平治,1159,1160). 年間(永暦,1160,1161). 年間(応保,1161,1163). 年間(長寛,1163,1165). 年間(永万,1165,1166). 年間(仁安,1166,1169). 年間(嘉応,1169,1171). 年間(承安,1171,1175). 年間(安元,1175,1177). 年間(治承,1177,1181). 年間(養和,1181,1182). 年間(寿永,1182,1185). 年間(文治,1185,1190). 年間(建久,1190,1199). 年間(正治,1199,1201). 年間(建仁,1201,1204). 年間(元久,1204,1206). 年間(建永,1206,1207). 年間(承元,1207,1211). 年間(建暦,1211,1213). 年間(建保,1213,1219). 年間(承久,1219,1222). 年間(貞応,1222,1224). 年間(元仁,1224,1225). 年間(嘉祿,1225,1227). 年間(安貞,1227,1229). 年間(寛喜,1229,1232). 年間(貞永,1232,1233). 年間(天福,1233,1234). 年間(文暦,1234,1235). 年間(嘉禎,1235,1238). 年間(暦仁,1238,1239). 年間(延応,1239,1240). 年間(仁治,1240,1243). 年間(寛元,1243,1247). 年間(宝治,1247,1249). 年間(建長,1249,1256). 年間(康元,1256,1257). 年間(正嘉,1257,1259). 年間(正元,1259,1260). 年間(文応,1260,1261). 年間(弘長,1261,1264). 年間(文永,1264,1275). 年間(建治,1275,1278). 年間(弘安,1278,1288). 年間(正応,1288,1293). 年間(永仁,1293,1299). 年間(正安,1299,1302). 年間(乾元,1302,1303). 年間(嘉元,1303,1306). 年間(徳治,1306,1308). 年間(延慶,1308,1311). 年間(応長,1311,1312). 年間(正和,1312,1317). 年間(文保,1317,1319). 年間(元応,1319,1321). 年間(元亨,1321,1324). 年間(正中,1324,1326). 年間(嘉暦,1326,1329). 年間(元徳,1329,1331). 年間(元弘,1331,1332). 年間(正慶,1332,1334). 年間(建武,1334,1338). 年間(暦応,1338,1342). 年間(康永,1342,1345). 年間(貞和,1345,1350). 年間(観応,1350,1352). 年間(文和,1352,1356). 年間(延文,1356,1361). 年間(康安,1361,1362). 年間(貞治,1362,1368). 年間(応安,1368,1375). 年間(永和,1375,1379). 年間(康暦,1379,1381). 年間(永徳,1381,1384). 年間(至徳,1384,1387). 年間(嘉慶,1387,1389). 年間(康応,1389,1390). 年間(明徳,1390,1394). 年間(応永,1394,1428). 年間(正長,1428,1429). 年間(永享,1429,1441). 年間(嘉吉,1441,1444). 年間(文安,1444,1449). 年間(宝徳,1449,1452). 年間(享徳,1452,1455). 年間(康正,1455,1457). 年間(長祿,1457,1460). 年間(寛正,1460,1466). 年間(文正,1466,1467). 年間(応仁,1467,1469). 年間(文明,1469,1487). 年間(長享,1487,1489). 年間(延徳,1489,1492). 年間(明応,1492,1501). 年間(文龜,1501,1504). 年間(永正,1504,1521). 年間(大永,1521,1528). 年間(享祿,1528,1532). 年間(天文,1532,1555). 年間(弘治,1555,1558). 年間(永祿,1558,1563). 年間(永禄,1564,1570). 年間(元龜,1570,1573). 年間(天正,1573,1592). 年間(文禄,1592,1596). 年間(慶長,1596,1615). 年間(元和,1615,1624). 年間(寛永,1624,1644). 年間(正保,1644,1648). 年間(慶安,1648,1652). 年間(承応,1652,1655). 年間(明暦,1655,1658). 年間(万治,1658,1661). 年間(寛文,1661,1673). 年間(延宝,1673,1681). 年間(天和,1681,1684). 年間(貞享,1684,1688). 年間(元禄,1688,1704). 年間(宝永,1704,1711). 年間(正徳,1711,1716). 年間(享保,1716,1736). 年間(元文,1736,1741). 年間(寛保,1741,1744). 年間(延享,1744,1748). 年間(寛延,1748,1751). 年間(宝暦,1751,1764). 年間(明和,1764,1772). 年間(安永,1772,1781). 年間(天明,1781,1789). 年間(寛政,1789,1801). 年間(享和,1801,1804). 年間(文化,1804,1818). 年間(文政,1818,1830). 年間(天保,1830,1844). 年間(弘化,1844,1848). 年間(嘉永,1848,1854). 年間(安政,1854,1860). 年間(万延,1860,1861). 年間(文久,1861,1864). 年間(元治,1864,1865). 年間(慶応,1865,1868). 年間(明治,1868,1912). 年間(大正,1912,1926). 年間(昭和,1926,1989). 年間(平成,1989,2016). findmin(A,B,C) :- findall(A,B,L), 最小値(L,C). 最小値(L,A) :- select(A,L,R), forall(member(B,R),B @>= A),!. sub_atom(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10) :- sub_atom(_1,_2,_3,_4,_6), sub_atom(_1,0,_2,_,_5), sub_atom(_1,_,_4,0,_7), atom_chars(_5,_8), atom_chars(_6,_9), atom_chars(_7,_10). % 以下のサイトは # # リストの要素を一つ選択する # # 8クイーンの部品として使われることで有名な述語である。 # # append/repeatの姿を持つ述語だが、使われたものが残り要素の中に戻ってくるところが面白い。 # ここでは、定義を二つ示す。後者の方が遅いが宣言的だ。 # リストの要素を一つ選択する(_選択要素,[_選択要素|_残り要素ならび],_残り要素ならび). リストの要素を一つ選択する(_選択要素,[_選択要素_1|R1],[_選択要素_1|R2]) :- リストの要素を一つ選択する(_選択要素,R1,R2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% リストの要素を一つ選択する(_選択要素,_選択ならび,_残りの要素ならび) :- append(L0,[_選択要素|R],_選択ならび), append(L0,R,_残りの要素ならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/669 # # MySql 5.1 です。 # select句の subquery で、カラムを2つ返したいのですが、 # これは不可能なのでしょうか? # 何か良い方法はないでしょうか? # # 同じ問い合わせを、2回書くのは なしということでお願いします。 # こんな感じで実現できたらベストです。 # # select # a.name , # b.date , # ( # select # c.foo_id, # c.bar_id # from # c # where # a.cond = c.cond # and b.date > c.date # order by c.date desc # limit 1 # ) # from # a, b # where # a.id = b.id # # # aTable # --------- # id,cond,name # # bTable # -------- # id,date # # cTable # ---------- # foo_id,bar_id,cond,date 'select句の subquery で、カラムを2つ返したい'(_name,_date,_foo_id,_bar_id) :- a(_id,_cond,_name), b(_id,_date), findmax([_date,_foo_id,_bar_id],( c(_foo_id,_bar_id,_cond,_c_date), _date > _c_date), [Max_date,_foo_id,_bar_id]). % 以下のサイトは # 出典: http://hibari.2ch.net/test/read.cgi/db/1279635842/127 # select文で100行ぐらい結果が返されるとき、 # 途中の20行目あたりからのみ取得するようなSQL文は # 記述可能ですか? # 述語参照で100行ぐらい結果が返されるとき、途中のn行目からのみ取得する(_述語参照,_n行目,_何行目 :: _n行目の解以降の解) :- _述語参照 =.. [_述語|_引数ならび], findall(_引数ならび,_述語参照,_解ならび), n行目以降だけの解をえる(_n行目,_解ならび,_何行目,_n行目の解以降の解). n行目以降だけの解を得る(_n行目,_解ならび,_何行目,_n行目の解以降の解) :- append(_読み捨てまたは読み終わりならび,[_n行目の解以降の解|_],_解ならび), length(_読み捨てまたは読み終わりならび,_読み捨てまたは読み終わり要素数), _読み捨てまたは読み終わり要素数 >= _n行目 - 1, _何行目 is _読み捨てまたは読み終わり要素数 + 1. % 以下のサイトは # 出典: http://hibari.2ch.net/test/read.cgi/db/1279635842/127 # select文で100行ぐらい結果が返されるとき、 # 途中の20行目あたりからのみ取得するようなSQL文は # 記述可能ですか? # 述語参照で100行ぐらい結果が返されるとき、途中のn行目からのみ取得する(_述語参照,_n行目,_何番目 :: _解) :- _述語参照 =.. [_述語|_引数ならび], findall(_引数ならび,_述語参照,_解ならび), n番目以降だけの解をえる(_n行目,_解ならび,_何番目,_解). n番目以降だけの解をえる(_n,_解ならび,_何番目,_解) :- n番目以降だけの(_n,_解ならび,_n個目の解以降の解ならび), 解を得る(_n個目の解以降の解ならび,_何番目,_解). n番目以降だけの(_n,_解ならび,_n個目の解以降の解ならび) :- _n_1 is _n - 1, length(L0,_n_1), append(L0,_n個目の解以降の解ならび,_解ならび). 解を得る(_n個目の解以降の解ならび,_何番目,_解) :- append(L1,[_解|_],_n個目の解以降の解ならび), 解の位置はL1の長さより1多い(L1,_何番目). 解の位置はL1の長さより1多い(L1,_何番目) :- length(L1,Len), _何番目 is Len + 1. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/627 # # mysql 5.0 (windows 7)です # 下記のようなテーブルで # amountの合計の最も多いidを取得するsql文がわかりません… # # select id, sum(amount) as "total" from orders # group by id order by total desc limit 1; # # とすれば一応取得できたのですが、別の方法はないでしょうか # 初歩的な質問ですみません… # # +------+------+--------+ # | id | name | amount | # +------+------+--------+ # | 1 | C1 | 3 | # | 1 | C2 | 10 | # | 2 | C2 | 5 | # | 2 | C3 | 10 | # | 3 | C3 | 2 | # +------+------+--------+ # 'amountの合計の最も多いidを取得する'(_最もaumout合計が多いid) :- find_sum_max([_id,_値],orders(_id,_,_値),[_最もamount合計が多いid,_最大合計値]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % _合計値 は任意の変数として、利用者が設定する find_sum_max([_鍵,_値],P,_合計値,_合計値の条件,[_鍵,_最大合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmax(_合計値,( append(_,[[_鍵,_合計値]|_],L), _合計値の条件), _最大合計値), append(_,[[_鍵,_最大合計値]|_],L). find_sum_min([_鍵,_値],P,_合計値,_合計値の条件,[_鍵,_最小合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmin(_合計値,( append(_,[[_鍵,_合計値]|_],L), _合計値の条件), _最小合計値), append(_,[[_鍵,_最小合計値]|_],L). find_sum_max([_鍵,_値],P,[_鍵,_最大合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmax(_合計値,append(_,[[_鍵,_合計値]|_],L),_最大合計値), append(_,[[_鍵,_最大合計値]|_],L). find_sum_min([_鍵,_値],P,[_鍵,_最小合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmin(_合計値,append(_,[[_鍵,_合計値]|_],L),_最小合計値), append(_,[[_鍵,_最小合計値]|_],L). 単一(A,P) :- findsetof(A,P,L),!, append(_,[A|_],L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/607 # # MySQLServer5.1(WinXP)です。 # # 下記のような3種類のテーブルがあります。 # これを集計して、指定したユーザーの指定月のアクセス日時と売上げ金額を表にしたいと思っています。 # # こんな感じに。 # # +--+--------+----------+-------+-----+ # | id | username| date   | access | sales | # +--+--------+----------+-------+-----+ # | 1 | admin | 2010-11-13 |   2 | 5000 | # | 1 | admin | 2010-11-14 |   2 | 5000 | # | 1 | admin | 2010-11-15 |  1 | 20000 | # +--+--------+----------+-------+-----+ # # # SELECT u.id AS id, u.username, DATE(a.created_at) AS date, COUNT(*) AS access, SUM(s.amount) AS sales # FROM sf_guard_user u INNER JOIN sales s ON u.username = s.user_id LEFT JOIN access_log a ON u.username = a.user_id # WHERE (u.username = 'admin' AND a.created_at > '2010-11-01 00:00:00' AND a.created_at < '2010-11-30 23:59:59') GROUP BY date ORDER BY a.created_at; # とやってみたのですがダメでした;; # # # ■ユーザー情報テーブル # mysql> select id,username from user; # +--+---------+ # | id | username | # +--+---------+ # | 1 | admin   | # +--+---------+ # # ■アクセスログテーブル # mysql> select * from access_log; # +--+-------+--------+------------------+ # | id | user_id | ip     | created_at      | # +--+-------+--------+------------------+ # | 1 | admin  | 127.0.0.1 | 2010-11-13 21:56:54 | # | 2 | admin  | 127.0.0.1 | 2010-11-13 21:56:54 | # | 3 | admin  | 127.0.0.1 | 2010-11-14 21:56:54 | # | 4 | admin  | 127.0.0.1 | 2010-11-14 21:56:54 | # | 5 | admin  | 127.0.0.1 | 2010-11-15 21:56:54 | # +--+-------+--------+------------------+ # # ■売上げ金額テーブル # mysql> select * from sales; # +--+-------+------+------------------+ # | id | user_id | amount| created_at      | # +--+-------+------+------------------+ # | 1 | admin  |  5000 | 2010-11-13 21:56:54 | # | 2 | admin  |  5000 | 2010-11-14 21:56:54 | # | 3 | admin  |  5000 | 2010-11-15 21:56:54 | # | 4 | admin  |  5000 | 2010-11-15 21:56:54 | # +--+-------+------+------------------+ # # '下記のような3種類のテーブルがあります。これを集計して、指定したユーザーの指定月のアクセス日時と売上げ金額を表にしたいと思っています。'(_username) :- user(_id,_username), アクセスログテーブル_date(_username,_アクセスログ_dateならび), 売上げ金額テーブル_date(_username,_売上金額テーブル_dateならび), 共通部分(_アクセスログ_dateならび,_売上金額テーブル_dateならび,_date_共通部分), write('+--+-------+--------+------------------+ \n'), write('| id | user_id | amount| created_at      | \n'), write('+--+-------+------+------------------+ \n), append(L0,[_date|R],_date_共通部分), length(L0,Len0), _id is Len0 + 1, count(( access_log(_,_user_id,_ip,_create_at), sub_atom(_create_at,0,10,_,_create_at)), _access), findsum(_amount,( sales(_,_user_id,_amount,_create_at), sub_atom(_create_at,0,10,_,_create_at)), _sales), write_formatted('| %t | %t | %t | %t | %t |\n',[_id,_username,_date,_access,_sales]), R = [], write('+--+-------+------+------------------+\n'). アクセスログテーブル_date(_user_id,_dateならび) :- findsetof(_date,( access_log(_,_user_id,_,_created_at), sub_atom(_create_at,0,10,_,_date)), _dateならび). 売上げ金額テーブル_date(_user_id,_dateならび) :- findsetof(_date,( sales(_,_user_id,_amount,_created_at), sub_atom(_create_at,0,10,_,_date)), _dateならび). % 以下のサイトは 順列(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). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1268979408/557 # # JMeterで何とか以下のHTMLの『二番目の』optionを拾いたいんだけど、どーも上手くいきません。 # <select name="select$item1" onchange="javascript:dummry();" id="select_item1"> # <option selected="selected" value="0">(none)</option> # <option value="1">item1</option> # <option value="2">item2</option> # <option value="3">item2</option> # </select> # ※optionの行にはいくつかタブが入っています。 # # 「id="select_item1">([.\r\n\t\f]*)option value="([1-9]*)"」と書けば拾ってくれると思ったんだけどダメでした。 # 何か忘れている箇所がありましたら、是非アドバイスをお願いします。 # # ちなみに(おそらくnameに$が入っているせいだと思いますが)HTMLリンクパーサは動きません(涙 # # '『二番目の』optionを拾いたい'(_htmlファイル,_二番目のoption) :- get_lines(Lines), '『二番目の』option'([],Lines,_二番目のoption). '『二番目の』option'([_],[_行|R],_二番目のoption) :- 'SPLIT'(_行,['>',''|_],L), last(L0,_二番目のoption),!. '『二番目の』option'(L,[_行|R],_二番目のoption) :- 'SPLIT'(_行,['>','',L), '『二番目の』option'([_|L],R,_二番目のoption). '『二番目の』option'(L,[_行|R],_二番目のoption) :- '『二番目の』option'(L,R,_二番目のoption). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/500 # # No-色 # レコード1 001,赤 # レコード2 002,赤 # レコード3 003,青 # レコード4 004,青 # レコード5, 005,赤 # レコード6, 006,黒 # # このデータで、 『select 色,count(色 from テーブル group by 色 』とした時 # 最大レコード数(この場合、赤の5)を取得したいのですが・・・ # 定義された節数のもっとも多い色は(_色,_度数) :- findsetof(_色,テーブル(_No,_色),L1), findall([_度数,_色],( member(_色,L1), count(テーブル(_,_色),度数)), L2), findmax(_度数,member([_度数,_],L2),_最大度数), append(_,[[_度数,_色]|R],L2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/490 # # SQLite3を使用しています。 # select distinct(hoge) # でhogeのユニークな値一覧が取得できますが、 # この結果の数を得る方法はないでしょうか? # # よろしくお願いします。 # # hogeのユニークな値のカウント(_テーブル,_解の数) :- hogeのユニークな値一覧を取得する(_テーブル,_値一覧), length(_値一覧,_解の数). hogeのユニークな値一覧を取得する(_テーブル,_値一覧) :- atom(_テーブル), テーブル構造(_テーブル/N,Nth,hoge), length(L,N), P =.. [_テーブル|L]), finsetof(X,( call(P), list_nth(Nth,L,X)), _値一覧),!. hogeのユニークな値一覧を取得する(_テーブル/N,_値一覧) :- テーブル構造(_テーブル/N,Nth,hoge), length(L,N), P =.. [_テーブル|L]), finsetof(X,( call(P), list_nth(Nth,L,X)), _値一覧),!. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/500 # # MYSQLなんですけど # # date      data # 2010/01/01 hoge1 # 2010/01/05 hoge2 # # みたいなテーブルから # # 2010/01/01 hoge1 # 2010/01/02 NULL # 2010/01/03 NULL # 2010/01/04 NULL # 2010/01/05 hoge2 # # のような結果の出せるSQLを求めてます。 # # select * from table between date '2010/01/01' and '2010/01/05' # # とするとデータのある2レコードしか出ないのですが、 # データがない部分も日付を出しつつ、デフォルトのデータないよっていう文字列を出せると助かります。 # # お助けください! # 'データがない部分も日付を出しつつ、デフォルトのデータないよっていう文字列を出す'(_日付下限,_日付上限) :- 入力された日付を年、月、日整数に変換(_日付下限,_年下限整数,_月下限整数,_日下限整数), 入力された日付を年、月、日整数に変換(_日付上限,_年上限整数,_月上限整数,_日上限整数), 日付の生成(_年下限整数,_月下限整数,_日下限整数,_年整数,_月整数,_日整数,_年上限整数,_月上限整数,_日上限整数), swritef(_date,'%4r/%2r/%2r',[_年整数,_月整数,_日整数]), 生成日付のtableの組を表示する(_date), (_年整数,_月整数,_日整数) = (_年上限整数,_月上限整数,_日上限整数). 入力された日付を年、月、日整数に変換(_日付文字列,_年整数,_月整数,_日整数) :- split(_日付文字列,['/'],[_年整数,_月整数,_日整数]). 生成日付のtableの組を表示する(_date) :- table(_date,_data), write_formatted('%t %t\n',[_date,_data]),!. 生成日付のtableの組を表示する(_生成された日付) :- \+(table(_date,_)), writef('%t %t\n',[_date,'NULL']),!. 日付の生成(_年整数,_月整数,_日整数,_年整数,_月整数,_日整数,_年上限整数,_月上限整数,_日上限整数), (_年整数,_月整数,_日整数) @=< (_年上限整数,_月上限整数,_日上限整数). 日付の生成(_年下限整数,_月下限整数,_日下限整数,_年整数,_月整数,_日整数,_年上限整数,_月上限整数,_日上限整数) :- (_年整数,_月整数,_日整数) @=< (_年上限整数,_月上限整数,_日上限整数), 翌日(_年整数,_月整数,_日整数,_翌日の年整数,_翌日の月整数,_翌日の日整数), 日付の生成(翌日の年整数,_翌日の月整数,_翌日の日整数,_年整数,_月整数,_日整数,_年上限整数,_月上限整数,_日上限整数). 翌日(_翌日の年整数,1,31,_翌日の年整数,2,1) :- !. 翌日(_翌日の年整数,3,31,_翌日の年整数,4,1) :- !. 翌日(_翌日の年整数,4,30,_翌日の年整数,5,1) :- !. 翌日(_翌日の年整数,5,31,_翌日の年整数,6,1) :- !. 翌日(_翌日の年整数,6,30,_翌日の年整数,7,1) :- !. 翌日(_翌日の年整数,7,31,_翌日の年整数,8,1) :- !. 翌日(_翌日の年整数,8,31,_翌日の年整数,9,1) :- !. 翌日(_翌日の年整数,9,30,_翌日の年整数,10,1) :- !. 翌日(_翌日の年整数,10,31,_翌日の年整数,11,1) :- !. 翌日(_翌日の年整数,11,30,_翌日の年整数,12,1) :- !. 翌日(_翌日の年整数,2,28,_翌日の年整数,3,1) :- \+(うるう年(_翌日の年整数)),!. 翌日(_翌日の年整数,2,29,_翌日の年整数,3,1) :- うるう年(_翌日の年整数),!. 翌日(_年整数,12,31,_翌日の年整数,1,1) :- _翌日の年整数 is _年整数 + 1,!. 翌日(_翌日の年整数,_翌日の月整数,_日整数,_翌日の年整数,_翌日の月整数,_翌日の日整数) :- _翌日の日整数 is _日整数 + 1,!. % 以下のサイトは % ***** tag_select / 2 ***** tag_select(NAME,OptionList) :- tag_select_option(OptionList,OptionList_2), tag(select([name=NAME],OptionList_2)),!. tag_select_option([],[]) :- !. tag_select_option([[V,A]|R1],[option([value=V2],[A])|R2]) :- concat(['"',V,'"'],V2), tag_select_option(R1,R2),!. tag_select_option([A|R1],[option([],[A])|R2]) :- not(atomic(A)), tag_select_option(R1,R2),!. tag_select_option([A|R1],[option([],[A])|R2]) :- atomic(A), tag_select_option(R1,R2). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/777 # # ・A, B, C, D・・・列があり、全て文字型(レコードは数値のみ)。 # A, Bがプライマリーキー # ・以下の条件を満たすA, Bの値 # Cが'04', '08', '09'のいずれかの行の中で、 # Dの値が最小のレコードのA, Bの組み合わせのうち、 # Bの値が最小のレコードすべてのA, B # ・説明 # 自分でsqlを作成すると、同じSELECT文が何度も出てきてしまいます。 # もっと重複のない文にできないのでしょうか? # select A, MIN(B) as B from # ( # (select A, B, D from foo where C in ('04', '08', '09')) T1 # inner join # ( # select A, MIN(D) as D from foo where C in ('04', '08', '09') # group by A # ) T2 # on T2.A = T1.A and T2.D = T1.D # ) T0 # group by A # # % ここでは要素をA,B,C,Dに限って考えることとする。 'Cが''04'', ''08'', ''09''のいずれかの行の中で、 Dの値が最小のレコードのA, Bの組み合わせのうち、 Bの値が最小のレコードすべてのA, B'(A,B) :- findmin([D,B],( foo(A,B,C,D),member(C,['04','08','09'])), L), foo(A,B,C,D), member([D,B],L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/455 # # 質問です。 # where句が膨大な数の条件式による論理和(OR)で構成されているselect文において、 # 得られた各レコードがどの条件式によるものかを判断したい場合どのようにするべきですか? # # 例えば下のようなテーブル(t)に対して # id name sex age # 0 tanaka male 25 # 1 yamada female 18 # 2 suzuki male 16 # # select name from t where age < 20 or sex = 'male'; # # を発行した場合すべてのnameが得られますが、それぞれのレコードがどの条件式によって得られたものかを判断したいと考えています。 # # '膨大な数の条件式による論理和(OR)で構成されているselect文において、得られた各レコードがどの条件式によるものかを判断したい'(_id,_name,_sex,_age,_条件式) :- t(_id,_name,_sex,_age), 条件(_id,_name,_sex,_age,_条件式). 条件式(_id,_name,_sex,_age,age < 20) :- _age < 20,!. 条件式(_id,_name,_sex,_age,sex = male) :- _sex = male,!. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/609 # # postgres8.4を使ってます。 # レコード数が3件以上あるものを取得したいのですが # どう書けばよいでしょうか。 # # やりたいことのイメージはこんな感じです。 # select recordCD from Table where recordCD in (select recordCD from Table where count(recordCD) > 3); # % これだとrecodCDが件数分出力されてしまうので、一件のみの出力に変更した recordCDの位置を得る(_引数の数,_位置番号) :- 'テーブル構造'('Table',_引数の数,_位置番号,recordCD). レコード数が3件以上あるものを取得する(_recordCD) :- recordCDの位置を得る(_引数の数,_位置番号), functor(Q,'Table',_引数の数), arg(_位置番号,Q,_recordCD), findsetof(_recordCD,call(Q),L1), member(_recordCD,L1), count(Q,Count), Count >= 3. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/609 # # postgres8.4を使ってます。 # レコード数が3件以上あるものを取得したいのですが # どう書けばよいでしょうか。 # # やりたいことのイメージはこんな感じです。 # select recordCD from Table where recordCD in (select recordCD from Table where count(recordCD) > 3); # % これだとrecodCDが件数分出力されてしまうので、一件のみの出力に変更した recordCDの位置を得る(_引数の数,_位置番号) :- 'テーブル構造'('Table',_引数の数,_位置番号,recordCD). レコード数が3件以上あるものを取得する(_recordCD) :- recordCDの位置を得る(_引数の数,_位置番号), functor(Q,'Table',_引数の数), arg(_位置番号,Q,_recordCD), findsetof(_recordCD,call(Q),L1), member(_recordCD,L1), count(Q,Count), Count >= 3. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1274791771/177 # # 質問させてください。 # # ・DBMS名とバージョン # MySQL 5.0.27-1 # # ・テーブルデータ # DATE    | DATA # ------------+---------- # 2010-06-01 | aaa # 2010-06-02 | bbb # 2010-06-03 | ccc # 2010-06-04 | ddd # 2010-06-05 | eee # 2010-06-06 | fff # 2010-06-07 | ggg # # ・欲しい結果 # 最新3件を昇順で。 # DATE    | DATA # ------------+---------- # 2010-06-05 | eee # 2010-06-06 | fff # 2010-06-07 | ggg # # ・説明 # select DATE, DATA from TABLE order by DATE desc limit 3; # とすれば、最新3件を降順で取得できますが、 # できれば降順でなく昇順で最新3件を取得したいです。 # # 'DATEの最新3件を昇順で取得する'(L) :- findsort([DATE],テーブル(DATE,DATA),L1), length(L,3), append(_,L,L1). findsort(_鍵ならび,P,_解ならび) :- P =.. [F|L1], append(_鍵ならび,L1,L2), findall(L2,P,L3), sort(L3,L4), findall(L1,member(L2,L4),_解ならび). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/960 # # ID|A|B|C| # --------- # 1 |1|2|3| # 2 |3|4|5| # 3 |7|8|9| (テーブルFOO) # # select FOO.ID,FOO.C from FOO,(select 1 AS EXPR) AS A # where FOO.A = A.EXPR or FOO.B = A.EXPR or FOO.C = A.EXPR; # # こんなかんじで得たCの内容を1のところにセットして # 該当するIDとCを全てリストアップするSQLはどう書けばよいでしょうか? # MySQL 5.0.67です。ストアドの作成権限はないです。 # # 'A,B,Cいずれかに1がある行の1のところにCをセットした行'(ID,A1,B1,C) :-     'FOO'(ID,A,B,C),     '1のところをCの値に置換'(A,B,C,A1,B1). '1のところをCの値に置換'(A,B,1,A,B) :- !. '1のところをCの値に置換'(1,1,C,C,C) :- !. '1のところをCの値に置換'(1,B,C,C,B) :- !. '1のところをCの値に置換'(A,1,C,A,C) :- !. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 'A,B,Cいずれかに1がある行の1のところにCをセットした行'(ID,A1,B1,C) :-     'FOO'(ID,A,B,C),     '1のところをCの値に置換'(A,B,C,A1,B1). '1のところをCの値に置換'(A,B,1,A,B) :- !. '1のところをCの値に置換'(1,B,C,C,B1) :- '1のところをCの値に置換の一'(C,B,C,C,B1),!. '1のところをCの値に置換'(A,1,C,A1,C) :- '1のところをCの値に置換の一'(A,C,C,A1,C),!. '1のところをCの値に置換の一'(1,B,C,C,B1) :- '1のところをCの値に置換の一'(C,B,C,C,B1),!. '1のところをCの値に置換の一'(A,1,C,A1,C) :- '1のところをCの値に置換の一'(A,C,C,A1,C),!. '1のところをCの値に置換の一'(A,B,C,A,B). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/823 # # mysql 5.1.38 # # table inputdaka # code int # inputdate date # data1 int # data2 int # # 指定された日(その日が存在しなければ直前の日付)及びその前日の # データを得る # # select inputdate,data1,data2 # from inputdaka # where code= 9999 # and # inputdate <= '2010-04-10' # order by inputdate desc limit 2; # # mysqlで、こう書きましたが、limitが使えないRDBでは # どうなるんですか? # '指定された日(その日が存在しなければ直前の日付)及びその前日のデータを得る'(_指定された日,_code,_inputdate,_data1,_data2) :- inputdaka(_code,_指定された日,_data1,_data2), _inputdate = _指定された日,!. '指定された日(その日が存在しなければ直前の日付)及びその前日のデータを得る'(_指定された日,_code,_inputdate,_data1,_data2) :- 前日(_指定された日,_前日), inputdaka(_code,_前日,_data1,_data2), _inputdate = _前日,!. '指定された日(その日が存在しなければ直前の日付)及びその前日のデータを得る'(_指定された日,_code,_inputdate,_data1,_data2) :- 前日(_指定された日,_前日), 前日(_前日,_前々日), inputdaka(_code,_前々日,_data1,_data2), _inputdate = _前々日,!. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/599 # # 以下のSQLで最新日の2000円以上の売上があった商品を抽出しているんですが、 # SELECT * FROM SALES WHERE uriage >= 2000 AND date = (select max(date) from SALES) # 「その商品の前回売上があった日の売上額」と「前回の売上と比べてどれだけ増えたのかの増加率」 # を出したい場合どうしたらいいでしょう? # # 商品ID(id) | 日付(date) | 売上額(uriage) | 前回売上額 | 売上増加率 # 3 | 1267714800 | 2500 | ????? | ????? # 4 | 1267714800 | 2800 | ????? | ????? # # [日付の形式はunixtimeで、データ登録の際は日付だけ変更させ、時間と秒は常に統一させています] # [mysql 5.1] # 前回売上との比較売上表(_年/_月/_日) :-     findall(_商品ID,(売上(_商品ID,_日付,_),localtime(_日付,_年,_月,_日,_,_,_,_)),_売上のあった商品IDならび), sort(_売上のあった商品IDならび     member(_商品ID2,_売上のあった商品IDならび),     当日の売上金額計(_商品ID2,_年/_月/_日,_売上金額計),     前回売上があった日(_商品ID2,_日付,_前回売上があった日),     前回売上があった日の売上金額計(_商品ID2,_前回売上があった日,_前回売上があった日の売上金額計),     売上行表示(_商品ID2,_年/_月/_日,_売上金額計,_前回売上があった日の売上金額計),     fail. 前回売上との比較売上表(_,_,_). 前回売上があった日(_商品ID,_日付,_前回売上があった日) :-     localtime(_日付,_年1,_月1,_日1,_,_,_,_),     findmax(_年2/_月2/_日2,(売上(_商品ID,_日付2,_),localtime(_日付2,_年2,_月2,_日2,_,_,_,_),_年1/_月1,_日1 @> _年2/_月2/_日2),_前回売上があった日). 前回売上があった日の売上金額計(_商品ID,_年/_月/_日,_売上金額計) :-     findsum(_売上金額,(売上(_商品ID,_日付2,_売上金額),localtime(_日付2,_年,_月,_日,_,_,_,_)),_売上金額計). 当日の売上金額計(_商品ID,_年/_月/_日,_売上金額計) :-     findsum(_売上金額,(売上(_商品ID,_日付,_売上金額),localtime(_日付,_年,_月,_日,_,_,_,_)),_売上金額計). 売上行表示(_商品ID,_年/_月/_日,_売上金額計,0.0) :-     write_formatted('%8d | %2d/%2d/%2d | %12.0f\n',[_商品ID2,_年/_月/_日,_売上金額計]),!. 売上行表示(_商品ID,_年/_月/_日,_売上金額計,_前回売上金額計) :-     _売上増加率 is _売上金額計 / _前回売上のあった日の売上金額計,     write_formatted('%8d | %2d/%2d/%2d | %12.0f | %12.0f | %4.1f\n',[_商品ID,_年/_月/_日,_売上金額計,_前回売上金額計,_売上増加率]),!. % 以下のサイトは # 出典 :: 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/55 # # [1] 授業単元:プログラム言語論 # [2] 問題文(含コード&リンク): # # 設問1.C言語、またはC++言語で、割り算を計算するdev(int x,int y)関数(*)を作成しなさい。 # ただし、不変表明(assert)を使って、0で除算を実行した場合にエラーを出力するようにすること。 # (*)関数devは、int型の返値を持ち、x/yを計算するものとする。 :- op(700,xfx,は). 関数定義(div(X,Y),Z) :- div(X,Y,Z). div(X,Y,Z) :- length(L1,X), length(L2,Y), div(L1,L2,DIV,MOD), length(DIV,Z). div(_,[],_,_) :- write('0除算エラー\n'),!. div(L1,L2,[_|D],MOD) :- append(L2,L3,L1), div(L3,L2,D,MOD). div(L1,L2,[],L1) :- \+(append(L2,L3,L1)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% findavg(_集約項,_項,_算術平均) :- findall(_集約項,_項,_値ならび), '加算'(_値ならび,_合計値), length(_値ならび,_ならびの長さ), _算術平均 is _合計値 / _ならびの長さ,!. 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), L = 0.0e+00,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 行列の転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S) . 加算_1([],S,S) :- !. 加算_1([A|R],Y,S) :- ならび(A), ならび(Y), !, ならび加算(A,Y,Z), 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,I), integer(I), Z is I + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,F), real(F), Z is F + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), 加算_1(R,Y,S),!. 加算_1([A|R],Y,S) :- A1 は A, Z is A1 + Y, 加算_1(R,Z,S). 加算_1(A,Y,S) :- とからりすと(A,L), !, 加算_1(L,Y,S) . 加算_2([],[]) :- !. 加算_2([L|R],[S|R2]) :- 加算(L,S), 加算_2(R,R2). 加算の変数に零をおく([]) :- !. 加算の変数に零をおく([A|R]) :- 変数(A), A = 0.0e+00, 加算の変数に零をおく(R),!. とからりすと(A,[A]) :- atomic(A),!. とからりすと(A と B,C) :- とからりすと(A,A1), とからりすと(B,B1), append(A1,B1,C). 変数(_変数) :- var(_変数). ならび([_|_]). _項 は (_ネットワーク :: _式) :- _ネットワーク :: _項 は _式, ! . _評価項 は N : L :- M は N, L1 は L, list_nth(M,L1,_評価項), ! . _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail) . _評価値 は [X|{P}] :- findall(X,P,_評価値), ! . _評価項 は ` _値 :- !, _評価項 = _値, ! . _項 は _式 :- var(_式), _項 = _式, ! . _項 は _式 :- error_protect(一時関数定義(_式,_項),fail) . _項 は _式 :- atom(_式), member(_式,[minint,maxint,cputtime,time,csize,cused,dbsize,dbused,gsize,gused,noptrs,ptrsued,ssize,sused,tsize,tused]), !, _項 is _式, ! . _項 は _式 :- 二項組込み関数(_式), 二項組込み関数の評価(_式,_項) . _項 は _式 :- 二項組込み関数(_式), !, fail . _項 は _式 :- functor(_式,Functor,1), arg(1,_式,Arg), Y は Arg, functor(_式_1,Functor,1), arg(1,_式_1,Y), member(Functor,[atom,real,integer,var,float,list]), !, error_protect(_式_1,fail), _項 = Y, ! . _項 は _式 :- atom(_式), error_protect(get_global(_式,_項),fail), ! . _項 は _式 :- real(_式), _項 = _式, ! . _項 は _式 :- real(_式), !, fail . _項 は _式 :- list(_式), findall(X,(member(U,_式) , X は U),_項) . _項 は _式 :- list(_式), !, fail. _項 は _erlang_module : _erlang関数 :- erlang関数評価(_erlang_module : _erlang関数,_項),!. _項 は _式 :- 関数定義(_式,_項),!. _項 は _式 :- functor(_式,_関数,_次数), function(_関数,_次数), findall(Arg,(for(1,N,_次数) , arg(N,_式,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), _式の二 =.. [_関数|L2], error_protect(_項 is _式の二,fail) . _項 は _評価関数 :- error_protect(_項 is _評価関数,fail),!. _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail),!. _項 は _評価項 :- 述語評価が可能(_評価項,_関数,_次数,_次数足す一), _評価項 =.. _評価項の項分解ならび, findall(Arg,(for(1,N,_次数) , arg(N,_評価項,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), append(L2,[_],_変数を付加した引数ならび), _解付き評価項 =.. [_関数|_変数を付加した引数ならび], error_protect(_解付き評価項,fail), arg(_次数足す一,_解付き評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), error_protect(_評価項,fail), arg(Arg,_評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), \+(error_protect(_評価項,fail)), _評価項 = _項,!. _項 は _式 :- atomic(_式), \+(述語評価が可能(_式,_関数,_次数,_次数足す一)), _項 = _式,!. 述語評価が可能(_評価項,_関数,_次数,_次数足す一) :- functor(_評価項,_関数,_次数), _次数足す一 is _次数 + 1, \+(predicate_type(_関数,_次数足す一,undefined)),!. 関数評価に於いて引数部分の関数評価([],[]). 関数評価に於いて引数部分の関数評価([L|R1],[L2|R2]) :- list(L), !, 関数評価に於いて引数部分の関数評価(L,L2), 関数評価に於いて引数部分の関数評価(R1,R2), ! . 関数評価に於いて引数部分の関数評価([F|R1],[F|R2]) :- \+(error_protect(F2 は F,fail)), !, 関数評価に於いて引数部分の関数評価(R1,R2) . 関数評価に於いて引数部分の関数評価([F|R1],[F2|R2]) :- error_protect(F2 は F,fail), 関数評価に於いて引数部分の関数評価(R1,R2) . erlang関数評価(os : cmd(Command),_項) :- erlang :: (os : cmd(Command) -> _項_1), _項 は string2atom(_項_1),!. erlang関数評価(_erlang_module : _erlang関数,_項) :- erlang :: (_erlang_module : _erlang関数 -> _項),!. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, number(_値の一), _値の二 は _項の二, number(_値の二), _値 is _値の一 + _値の二, !. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 + _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, list(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),LY), concat_list(LY,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atom(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),L), concat_atom(L,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 * _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(` _値,_値) :- !. 関数定義(@ _式,_値) :- _値 は _式,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _値の二 >= 0.0e+00, _四捨五入後の値 is floor(_値の二 + 0.5) * 1.0,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 is ceil(_値の二 - 0.5),!. 関数定義(切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二) * 1.0,!. 関数定義(切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二),!. 関数定義(十円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 10 + 0.5) * 10,!. 関数定義(十円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は trunc(_値の二 / 10) * 10,!. 関数定義(十円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 10) * 10,!. 関数定義(百円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 100 + 0.5) * 100,!. 関数定義(百円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 100) * 100,!. 関数定義(百円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二 / 100) * 100,!. 関数定義(整数化(_値),_整数化された値) :- _値の二 は _値, _整数化された値 is trunc(_値の二),!. 関数定義(char_code(_項),_値) :- ( atom(_項), atomic_length(_項,1), char_code(_項,_値) ; integer(_項), char_code(_値,_項) ; 複合項(_項), _項の一 は _項, _値 は char_code(_項の一) ), !. 関数定義($ _大域変数名,_値) :- atom(_大域変数名), get_global(_大域変数名,_値の一), _値 は _値の一,!. 関数定義(S,E) :- functor(S,select,1), to(S,E),!. 関数定義(setq(A,B),E) :- atom(A), B1 は B, set_global(A,B1), E = B1,!. 関数定義(++ A,X) :- A1 は A, list(A1), 加算(A1,X),!. 関数定義(A ++ B,X) :- C is B / A, X = A + C + B,!. 関数定義(car(A),E) :- A1 は A, A1 = [E|_],!. 関数定義(cdr(A),E) :- A1 は A, A1 = [_|E],!. 関数定義(cons(A,B),E) :- A1 は A, B1 は B, E = [A1|B1],!. 関数定義(length(A),E) :- A1 は A, list(A1), length(A1,E),!. 関数定義(decode(A,B,C,D),E) :- A1 は A, B1 は B, A1 = B1, E は C,!. 関数定義(decode(A,B,C,D),E) :- E は D,!. 関数定義(decompcons(A),E) :- A1 は A, decompcons(A1,E),!. 関数定義(substr(A,B,C),E) :- 関数定義(subatomic(A,B,C),E),!. 関数定義(subatomic(A,B,C),E) :- A1 は A, B1 は B, C1 は C, subatomic(A1,B1,C1,E),!. 関数定義(concat(A),E) :- A1 は A, concat(A1,E),!. 関数定義(concat(A,B),E) :- A1 は A, B1 は B, concat(A1,B1,E),!. 関数定義(append(A,B),E) :- A1 は A, B1 は B, append(A1,B1,E),!. 関数定義(reverse(A),E) :- A1 は A, reverse(A1,E),!. 関数定義(string2atom(A),E) :- A2 は A, flat(A2,B), atom_codes(E,B),!. 関数定義(P,E) :- functor(P,greatest,Arg), P =.. [greatest|L], findall(B,(member(A,L) , B は A),L2), max(L2,E),!. 関数定義(P,E) :- functor(P,least,Arg), P =.. [least|L], findall(B,(member(A,L) , B は A),L2), min(L2,E),!. 関数定義(cel(_列数,_行数,_行列),_解) :- _関数評価された行数 は _行数, _関数評価された列数 は _列数, list_nth(_関数評価された行数,_行列,_行), list_nth(_関数評価された列数,_行,_解),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/291 # # [1] 授業単元:コンピュータリテラシー # [2] 問題文(含コード&リンク):問題文と参考は以下です #   http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9806.txt # ・試験の過程を記録 # 1,番号、得点を入力したあと平均点を計算 # 2,番号順と得点順に並べ替え(ifを使いどちらか選択できるようにする) # 3,番号、得点、平均との差を出力 # 以上のプログラムを作成 成績を記録する :- write('番号と得点をスペースで区切って一行で入力してください\n'), get_line(_行), 成績を記録する(_行). 成績を記録する(end_of_file) :- !. 成績を記録する(_行) :- split(_行,[' '],[_番号,_得点]), assertz(成績(_番号,_得点)), get_line(_次の行), 成績を記録する(_次の行). 平均点(_平均点) :- findavg(_得点,成績(_,_得点),_平均点). 番号順に並べ直し(_番号順成績ならび) :- findall([_番号,_得点],成績(_番号,_得点),_成績ならび), quicksort(_成績ならび,_番号順成績ならび). 得点順に並べ直し(_得点順成績ならび) :- findall([_得点,番号],成績(_番号,_得点),_得点・番号成績ならび), quicksort(_得点・番号成績ならび,_整列した得点・番号ならび), 項目位置を元に戻す(_整列した得点・番号ならび,_得点順成績ならび). 項目位置を元に戻す([],[]). 項目位置を元に戻す([[A,B]|R1],[[B,A]|R2]) :- 項目位置を元に戻す(R1,R2). 番号、得点、平均との差の出力 :- 平均点(_平均点), write('番号 得点 平均との差\n'), 成績(_番号,_得点), _平均との差 is _得点 - _平均点, write_formatted('%t %t %t\n',[_番号,_得点,_平均との差]), fail. 番号、得点、平均との差の出力. quicksort([],[]) :- !. quicksort([X|Xs],Ys) :- partition(Xs,X,Littles,Gigs), quicksort(Littles,Ls), quicksort(Bigs,Bs), append(Ls,[X|Bs],Ys). partition([],Y,[],[]) :- !. partition([X|Xs],Y,[X|Ls],Bs) :- X @=< Y,partition(Xs,Y,Ls,Bs). partition([X|Xs],Y,Ls,[X|Bs]) :- X @> Y,partition(Xs,Y,Ls,Bs). %%%%%%%% findavg/3 加算/2 他 %%%%%%%%%%%%%%%%%%%% :- op(A,B,は). findavg(_集約項,_項,_算術平均) :- findall(_集約項,_項,_値ならび), '加算'(_値ならび,_合計値), length(_値ならび,_ならびの長さ), _算術平均 is _合計値 / _ならびの長さ,!. 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), L = 0.0e+00,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 行列の転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S) . 加算_1([],S,S) :- !. 加算_1([A|R],Y,S) :- ならび(A), ならび(Y), !, ならび加算(A,Y,Z), 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,I), integer(I), Z is I + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,F), real(F), Z is F + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), 加算_1(R,Y,S),!. 加算_1([A|R],Y,S) :- A1 は A, Z is A1 + Y, 加算_1(R,Z,S). 加算_1(A,Y,S) :- とからりすと(A,L), !, 加算_1(L,Y,S) . 加算_2([],[]) :- !. 加算_2([L|R],[S|R2]) :- 加算(L,S), 加算_2(R,R2). 加算の変数に零をおく([]) :- !. 加算の変数に零をおく([A|R]) :- 変数(A), A = 0.0e+00, 加算の変数に零をおく(R),!. とからりすと(A,[A]) :- atomic(A),!. とからりすと(A と B,C) :- とからりすと(A,A1), とからりすと(B,B1), append(A1,B1,C). 変数(_変数) :- var(_変数). ならび([_|_]). _項 は (_ネットワーク :: _式) :- _ネットワーク :: _項 は _式, ! . _評価項 は N : L :- M は N, L1 は L, list_nth(M,L1,_評価項), ! . _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail) . _評価値 は [X|{P}] :- findall(X,P,_評価値), ! . _評価項 は ` _値 :- !, _評価項 = _値, ! . _項 は _式 :- var(_式), _項 = _式, ! . _項 は _式 :- error_protect(一時関数定義(_式,_項),fail) . _項 は _式 :- atom(_式), member(_式,[minint,maxint,cputtime,time,csize,cused,dbsize,dbused,gsize,gused,noptrs,ptrsued,ssize,sused,tsize,tused]), !, _項 is _式, ! . _項 は _式 :- 二項組込み関数(_式), 二項組込み関数の評価(_式,_項) . _項 は _式 :- 二項組込み関数(_式), !, fail . _項 は _式 :- functor(_式,Functor,1), arg(1,_式,Arg), Y は Arg, functor(_式_1,Functor,1), arg(1,_式_1,Y), member(Functor,[atom,real,integer,var,float,list]), !, error_protect(_式_1,fail), _項 = Y, ! . _項 は _式 :- atom(_式), error_protect(get_global(_式,_項),fail), ! . _項 は _式 :- real(_式), _項 = _式, ! . _項 は _式 :- real(_式), !, fail . _項 は _式 :- list(_式), findall(X,(member(U,_式) , X は U),_項) . _項 は _式 :- list(_式), !, fail. _項 は _erlang_module : _erlang関数 :- erlang関数評価(_erlang_module : _erlang関数,_項),!. _項 は _式 :- 関数定義(_式,_項),!. _項 は _式 :- functor(_式,_関数,_次数), function(_関数,_次数), findall(Arg,(for(1,N,_次数) , arg(N,_式,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), _式の二 =.. [_関数|L2], error_protect(_項 is _式の二,fail) . _項 は _評価関数 :- error_protect(_項 is _評価関数,fail),!. _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail),!. _項 は _評価項 :- 述語評価が可能(_評価項,_関数,_次数,_次数足す一), _評価項 =.. _評価項の項分解ならび, findall(Arg,(for(1,N,_次数) , arg(N,_評価項,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), append(L2,[_],_変数を付加した引数ならび), _解付き評価項 =.. [_関数|_変数を付加した引数ならび], error_protect(_解付き評価項,fail), arg(_次数足す一,_解付き評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), error_protect(_評価項,fail), arg(Arg,_評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), \+(error_protect(_評価項,fail)), _評価項 = _項,!. _項 は _式 :- atomic(_式), \+(述語評価が可能(_式,_関数,_次数,_次数足す一)), _項 = _式,!. 述語評価が可能(_評価項,_関数,_次数,_次数足す一) :- functor(_評価項,_関数,_次数), _次数足す一 is _次数 + 1, \+(predicate_type(_関数,_次数足す一,undefined)),!. 関数評価に於いて引数部分の関数評価([],[]). 関数評価に於いて引数部分の関数評価([L|R1],[L2|R2]) :- list(L), !, 関数評価に於いて引数部分の関数評価(L,L2), 関数評価に於いて引数部分の関数評価(R1,R2), ! . 関数評価に於いて引数部分の関数評価([F|R1],[F|R2]) :- \+(error_protect(F2 は F,fail)), !, 関数評価に於いて引数部分の関数評価(R1,R2) . 関数評価に於いて引数部分の関数評価([F|R1],[F2|R2]) :- error_protect(F2 は F,fail), 関数評価に於いて引数部分の関数評価(R1,R2) . erlang関数評価(os : cmd(Command),_項) :- erlang :: (os : cmd(Command) -> _項_1), _項 は string2atom(_項_1),!. erlang関数評価(_erlang_module : _erlang関数,_項) :- erlang :: (_erlang_module : _erlang関数 -> _項),!. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, number(_値の一), _値の二 は _項の二, number(_値の二), _値 is _値の一 + _値の二, !. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 + _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, list(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),LY), concat_list(LY,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atom(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),L), concat_atom(L,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 * _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(` _値,_値) :- !. 関数定義(@ _式,_値) :- _値 は _式,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _値の二 >= 0.0e+00, _四捨五入後の値 is floor(_値の二 + 0.5) * 1.0,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 is ceil(_値の二 - 0.5),!. 関数定義(切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二) * 1.0,!. 関数定義(切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二),!. 関数定義(十円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 10 + 0.5) * 10,!. 関数定義(十円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は trunc(_値の二 / 10) * 10,!. 関数定義(十円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 10) * 10,!. 関数定義(百円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 100 + 0.5) * 100,!. 関数定義(百円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 100) * 100,!. 関数定義(百円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二 / 100) * 100,!. 関数定義(整数化(_値),_整数化された値) :- _値の二 は _値, _整数化された値 is trunc(_値の二),!. 関数定義(char_code(_項),_値) :- ( atom(_項), atomic_length(_項,1), char_code(_項,_値) ; integer(_項), char_code(_値,_項) ; 複合項(_項), _項の一 は _項, _値 は char_code(_項の一) ), !. 関数定義($ _大域変数名,_値) :- atom(_大域変数名), get_global(_大域変数名,_値の一), _値 は _値の一,!. 関数定義(S,E) :- functor(S,select,1), to(S,E),!. 関数定義(setq(A,B),E) :- atom(A), B1 は B, set_global(A,B1), E = B1,!. 関数定義(++ A,X) :- A1 は A, list(A1), 加算(A1,X),!. 関数定義(A ++ B,X) :- C is B / A, X = A + C + B,!. 関数定義(car(A),E) :- A1 は A, A1 = [E|_],!. 関数定義(cdr(A),E) :- A1 は A, A1 = [_|E],!. 関数定義(cons(A,B),E) :- A1 は A, B1 は B, E = [A1|B1],!. 関数定義(length(A),E) :- A1 は A, list(A1), length(A1,E),!. 関数定義(decode(A,B,C,D),E) :- A1 は A, B1 は B, A1 = B1, E は C,!. 関数定義(decode(A,B,C,D),E) :- E は D,!. 関数定義(decompcons(A),E) :- A1 は A, decompcons(A1,E),!. 関数定義(substr(A,B,C),E) :- 関数定義(subatomic(A,B,C),E),!. 関数定義(subatomic(A,B,C),E) :- A1 は A, B1 は B, C1 は C, subatomic(A1,B1,C1,E),!. 関数定義(concat(A),E) :- A1 は A, concat(A1,E),!. 関数定義(concat(A,B),E) :- A1 は A, B1 は B, concat(A1,B1,E),!. 関数定義(append(A,B),E) :- A1 は A, B1 は B, append(A1,B1,E),!. 関数定義(reverse(A),E) :- A1 は A, reverse(A1,E),!. 関数定義(string2atom(A),E) :- A2 は A, flat(A2,B), atom_codes(E,B),!. 関数定義(P,E) :- functor(P,greatest,Arg), P =.. [greatest|L], findall(B,(member(A,L) , B は A),L2), max(L2,E),!. 関数定義(P,E) :- functor(P,least,Arg), P =.. [least|L], findall(B,(member(A,L) , B は A),L2), min(L2,E),!. 関数定義(cel(_列数,_行数,_行列),_解) :- _関数評価された行数 は _行数, _関数評価された列数 は _列数, list_nth(_関数評価された行数,_行列,_行), list_nth(_関数評価された列数,_行,_解),!. % 以下のサイトは 'エラトステネスの篩とは、古代数学者が素数判定法の一種で、 古代数学者エラトステネスが考案したことが記されているためこの名がある。 2以上N以下の順序数の集合から素数と解ったものの倍数を篩に掛けるように 削除していって、すべての要素を検査し終わるまで、すなわち 素数以外の要素がなくなるまでこれを繰り返す。こうして素数集合得るものである。 述語名はこれ以後、"エラトステネスの篩(篩は素数の倍数で篩に掛けるものとする)"と 簡約する'(_Nまで,_素数ならび) :- '2以上N以下の順序数集合'(_Nまで,_2以上N以下のの順序数ならび), 'エラトステネスの篩(篩は素数の倍数で篩に掛けるものとする)'(_2以上N以下の順序数ならび,_素数ならび). 'エラトステネスの篩(篩は素数の倍数で篩に掛けるものとする)'([],[]) :- !. 'エラトステネスの篩(篩は素数の倍数で篩に掛けるものとする)'([A|R1],[A|R2]) :- 篩は素数の倍数で篩に掛けるものとする(R1,A,L), 'エラトステネスの篩(篩は素数の倍数で篩に掛けるものとする)'(L,R2). 篩は素数の倍数で篩に掛けるものとする(R1,A,L) :- findall(B,( member(B,R1), \+(0 is B mod A)), L). '2から始める順序数集合'(_Nまで,_2からNまでの順序数ならび) :- findall(M,between(2,_Nまで,M),_2からNまでの順序数ならび). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% mからnの範囲の素数(_m,_n,_mから_nの範囲の素数ならび) :- n以下の素数(_n,_n以下の素数ならび), findall(_素数,( member(_素数,_n以下の素数ならび), _素数 >= _m), _mから_nの範囲の素数ならび). n以下の素数(_n以下,_素数ならび) :- findall(_数,( between(2,_n以下,_数)), _2以上_n以下の数ならび), エラトステネスの篩(_2以上_n以下の数ならび,_素数ならび). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% エラトステネスの篩([],[]) :- !. エラトステネスの篩([_ある素数|R1],[_ある素数|R2]) :- ある素数の倍数を篩に掛ける(_ある素数,_ある素数,[_ある素数|R1],L), エラトステネスの篩(L,R2). ある素数の倍数を篩に掛ける(_,_,[],[]). ある素数の倍数を篩に掛ける(_ある素数の倍数,_ある素数,[_ある素数の倍数|R1],R2) :- _ある素数の倍数_2 is _ある素数の倍数 + _ある素数, ある素数の倍数を篩に掛ける(_ある素数の倍数_2,_ある素数,R1,R2),!. ある素数の倍数を篩に掛ける(_ある素数の倍数_1,_ある素数,[_数|R1],R2) :- _ある素数の倍数_1 < _数, _ある素数の倍数_2 is _ある素数の倍数_1 + _ある素数, ある素数の倍数を篩に掛ける(_ある素数の倍数_2,_ある素数,[_数|R1],R2),!. ある素数の倍数を篩に掛ける(_ある素数の倍数,_ある素数,[_ある素数の倍数ではない数|R1],[_ある素数の倍数ではない数|R2]) :- ある素数の倍数を篩に掛ける(_ある素数の倍数,_ある素数,R1,R2),!. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% エラトステネスの篩([],[]) :- !. エラトステネスの篩([_素数|R1],[_素数|R2]) :- last([_素数|R1],_R1の最終数), 素数の倍数を篩に掛ける(_R1の最終数,_素数,R1,L), エラトステネスの篩(L,R2). 素数の倍数を篩に掛ける(_R1の最終数,_素数,R1,L) :- findall(U,( 素数の倍数を取る(_R1の最終数,_素数,2,U), ( U > _R1の最終数,!,fail; \+(member(U,R1)))), L). 素数の倍数を得る(M,N,X) :- X is M * N. 素数の倍数を得る(M,N,X) :- N_2 is N + 1, 素数の倍数を得る(M,N_2,X). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% エラトステネスの篩([],[]) :- !. エラトステネスの篩([A|R1],[A|R2]) :- エラトステネスの篩(A,R1,L), エラトステネスの篩(L,R2) . エラトステネスの篩(_,_,[],[]) :- !. エラトステネスの篩(N,[A|R1],R2) :- '_要素がNの倍数の時篩に掛かる'(N,A,R1,R2),!. エラトステネスの篩(N,[_|R1],[A|R2]) :- '_要素がNの倍数でない時は残る'(N,R1,R2). '_要素がNの倍数の時篩に掛かる'(N,A,R1,R2) :- 0 is A mod N, エラトステネスの篩(N,R1,R2). '_要素がNのでない時は残る'(N,R1,R2) :- エラトステネスの篩(N,R1,R2) . %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% エラトステネスの篩([],[]) :- !. エラトステネスの篩([A|R1],[A|R2]) :- A_2 is A + A, エラトステネスの篩(A,A_2,R1,L), エラトステネスの篩(L,R2) . エラトステネスの篩(N,N_1,L1,L2) :- select(N_1,L1,L3), N_2 is N_1 + N, エラトステネスの篩(N_2,L3,L2). エラトステネスの篩(N,N_1,L1,L2) :- N_2 is N_1 + N, エラトステネスの篩(N_2,L1,L2) . %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% n以下の素数(_n以下,_素数ならび) :- findall(_数,( between(2,_n以下,_数)), _2以上_n以下の数ならび), Max is truncate(sqrt(_n以下)), エラトステネスの篩(Max,_2以上_n以下の数ならび,_素数ならび). エラトステネスの篩(_,[],[]) :- !. エラトステネスの篩(Max,[A|R1],[A|R2]) :- 或る数の倍数を削除する(Max,A,R1,L), エラトステネスの篩(Max,L,R2). 或る数の倍数を削除する(Max,A,L1,L) :- findall(U,( member(B,L1), 或る数の倍数と一致しない(Max,A,B)), L). 或る数の倍数と一致しない(Max,_或る数,B) :- 或る数の倍数を生成する(_或る数,_倍数), ( _倍数 > Max, B = _倍数,! ; _倍数 > Max,!,fail). 或る数の倍数を生成する(_或る数,_倍数) :- 或る数の倍数を生成する(2,_或る数,_倍数). 或る数の倍数を生成する(N,_或る数,_倍数) :- _倍数 is _ある数 * (N + 1). 或る数の倍数を生成する(N,_或る数,_倍数) :- N_2 is N + 1, 或る数の倍数を生成する(N_2,_或る数,_倍数). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% エラトステネスの篩([],[]) :- !. エラトステネスの篩([A|R1],[A|R2]) :- エラトステネスの篩(A,R1,L), エラトステネスの篩(L,R2). エラトステネスの篩(_,[],[]) :- !. エラトステネスの篩(N,[A|R1],R2) :- 0 is A mod N, エラトステネスの篩(N,R1,R2),!. エラトステネスの篩(N,[A|R1],[A|R2]) :- エラトステネスの篩(N,R1,R2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% エラトステネスの篩([],[]) :- !. エラトステネスの篩([A|R1],[A|R2]) :- 'R1から、Aの倍数である要素を篩い落とし、Aの倍数ではない要素だけを残す'(R1,A,L), エラトステネスの篩(L,R2). 'R1から、Aの倍数である要素を篩い落とし、Aの倍数ではない要素だけを残す'(R1,A,L) :- findall(B,( member(B,R1), \+(0 is B mod A)), L). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% エラトステネスの篩([],[]) :- !. エラトステネスの篩([A|R1],[A|R2]) :- findall(B,(member(B,R1),\+(0 is B mod A)),L), エラトステネスの篩(L,R2). % 以下のサイトは %% TECHINIQUES OF PROLOG PROGRAMMING by T. Van Le, ph D. %% topo_sort(Graph,List) :- createq(Graph,Queue), t_sort(Graph,Queue,List). createq(G,Q-Qt) :- setof(X,minimal(X,G),L), append(L,Qt,Q). minimal(X,G) :- member(X:Y,G), not(member(A:X,G)). t_sort([],[]-[],[]) :- !. t_sort(G,[X|Q]-Qt,[X|L]) :- find_successors(X,G,G1,Qt-Qs), t_sort(G1,Q-Qs,L). find_successors(X,G,G1,Q-Qt) :- select(X:Y,G,G2),!, (member(A:Y,G2),!, Q = Q1; Q = [Y|Q1]), find_successors(X,G2,G1,Q1-Qt). find_successors(_,G,G,Q-Q). select(H,[H|T],T). select(X,[H|T],[T|T1]) :- select(X,T,T1). graph([ics:is1,dma:ps2,dma:se1,dsa:ps2,dsa:se1, dsa:co1,is1:is2,is1:ps2,is1:se1,co1:co2,is2:pm, is2:is3,ps2:is3,co2:os,pm:cp,is3:cp,os:cp]). ?- graph(G),topo_sort(G,L). L = [dma,dsa,ics,co1,is1,co2,is2,ps2,se1,os,pm,is3,cp] -> % 以下のサイトは %% TECHINIQUES OF PROLOG PROGRAMMING by T. Van Le, ph D. %% selection_sort([],[]). selection_sort(L,[H|T]) :- least(H,L,R), selection_sort(R,T). least(X,L,R) :- select(X,L,R), smaller(X,R). smaller(_,[]). smaller(X,[H|T]) :- X =< H, smaller(X,T). select(H,[H|T],T). select(X,[H|T],[T|T1]) :- select(X,T,T1). % 以下のサイトは %% TECHINIQUES OF PROLOG PROGRAMMING by T. Van Le, ph D. %% permutation_sort(L,L1) :- permutation(L,L1), ordered(L1). ordered([]). ordered([X]). ordered([X,Y|R]) :- X =< Y, ordered([Y,R]). permutation([],[]). permutation(L,[H|T]) :- select(H,L,R), permutation(R,T). select(H,[H|T],T). select(X,[H|T],[T|T1]) :- select(X,T,T1). % 以下のサイトは % http://pc12.2ch.net/test/read.cgi/tech/1232627790/588 % 【 課題 】車、新幹線、飛行機の3つの交通手段を考える。 % 距離と、所要時間の最大限度(許容最長時間)を指定したとき、許容最長時間内に % 目的地に到着可能で、かつ、費用が一番安い交通手段を調べて表示しなさい。 % ただし、距離(km)と許容最長時間(h) は浮動小数点数としてキーボードから与える。 % 許容最長時間内に到着できる手段がない場合は、「不可能です」と表示する。 % それぞれの時速、料金、利用規定は % 車 : 60km/h、20 円/km、 % 新幹線 : 200km/h、50 円/km、距離が50km以上のときに利用可能 % 飛行機 : 1000km/h、35 円/km、距離が400km以上のときに利用可能 待機・乗降の合計 % で1 時間にかかるとする。 % :- op(250,xf,km). :- op(250,xf,h). :- op(250,xf,円). 交通手段(車). 交通手段(新幹線). 交通手段(飛行機). 時速(車,60 km / h). 時速(新幹線,200 km / h). 時速(飛行機,1000 km / h). 料金(車,20 円 / km). 料金(新幹線,50 円 / km). 料金(飛行機,35 円 / km). 利用規定(新幹線,_距離 km) :- _距離 >= 50. 利用規定(飛行機,_距離 km) :- _距離 >= 400. 利用規定(車,_距離 km) :- _距離 >= 0. 付加的な所要時間(飛行機,'待機・乗降の合計',1 h). 付加的な所要時間(車,なし,0 h). 付加的な所要時間(新幹線,なし,0 h). '許容最長時間内に目的地に到着可能で、かつ、費用が一番安い交通手段'(_距離 km,_許容最長時間 h,_交通手段) :- '許容最長時間内に目的地に到達可能で、'(_距離 km,_許容最長時間 h,_費用_交通手段ならび), 'かつ、費用が一番安い交通手段'(_費用_交通手段ならび,_交通手段),!. '許容最長時間内に目的地に到着可能で、かつ、費用が一番安い交通手段'(_,_,'不可能です'). '許容最長時間内に目的地に到達可能で、'(_距離 km,_許容最長時間 h,_費用_交通手段ならび) :- findall([_費用,_交通手段],( 許容時間内に到達可能な交通手段の費用(_距離 km,_許容最長時間 h,_交通手段,_費用)),_費用_交通手段ならび). 'かつ、費用が一番安い交通手段'(_費用_交通手段ならび,_交通手段) :- 一番安い(_費用_交通手段ならび,_費用,_交通手段),!. 許容時間内に到達可能な交通手段の費用(_距離 km,_許容最長時間 h,_交通手段,_費用) :- 許容時間内に到達可能な交通手段の(_距離 km,_許容最長時間 h,_交通手段), 費用(_交通手段,_距離 km,_費用). 許容時間内に到達可能な交通手段の(_距離 km,_許容最長時間 h,_交通手段) :- 交通手段(_交通手段), 許容時間内に到達可能(_交通手段,_距離 km,_許容最長時間 h). 費用(_交通手段,_距離 km,_費用) :- 料金(_交通手段,_料金 円 / km), _費用 is _料金 * _距離. 許容時間内に到達可能(_交通手段,_距離 km,_許容最長時間 h) :- 利用規定に適合する交通手段を使っての(_交通手段,_距離 km), 到達時間が(_交通手段,_距離 km,_到達時間 h), 許容最長時間内にある(_到達時間 h,_許容最長時間 h). 利用規定に適合する交通手段を使っての(_交通手段,_距離 km) :- 利用規定(_交通手段,_距離 km). 到達時間が(_交通手段,_距離 km,_到達時間 h) :- 時速(_交通手段,_時速 km / h), 付加的な所要時間(_交通手段,_,_付加的な所要時間 h), _到達時間 is (_距離 / _時速) + _付加的な所要時間. 許容最長時間内にある(_到達時間 h,_許容最長時間 h) :- _到達時間 =< _許容最長時間. 一番安い(_価格_交通手段ならび,_一番安い価格,_交通手段) :- select([_一番安い価格,_交通手段],_価格_交通手段ならび,_残り価格_交通手段ならび), forall(member([_価格,_],_残り価格_交通手段ならび),_価格 @>= _一番安い価格). % 以下のサイトは % <<問題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).