このディレクトリの索引

% 以下のサイトは # 出典 :: CodeIQ q1565 # 【問題】 # できるだけ多くの人数で、肩車をしようと思います。 #      # # 肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。 # # # 【例】 # 一行ごとに、身長と体重のセットが与えられます。次の例は、5人の身長と体重を表しています。 # 166 71 # 178 84 # 176 94 # 174 85 # 174 65 # # # この中から肩車をする人間を選ぶと、身長と体重が # (166, 71) # (174, 85) # (176, 94) # の3人が最大人数になります。 # # ※身長と体重共に、上の人が下の人“より小さい”場合に肩車が許されるとしていますので、 #  (174, 85)の上に(174, 65)が乗ることはできません。 'できるだけ多くの人数で、肩車をしようと思います。      肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_最大人数) :- 身長と体重のセットを得る(_身長と体重のセット), 'できるだけ多くの人数で、肩車をしようと思います。'(_身長と体重のセット,_最大人数). 身長と体重のセットを得る(_身長と体重のセット) :- 行を得る(_行,_終了状態), 身長と体重のセットを得る(_終了状態,_行,_身長と体重のセット). 身長と体重のセットを得る(入力終了,_,[]) :- !. 身長と体重のセットを得る(_,_行,_身長体重ならび) :- 入力終了になるまで行入力を続ける(_,_行,_身長体重ならび). 入力終了になるまで行入力を続ける(_,_行,[[_身長,_体重]|_残りの行ならび]) :- read_term_from_atom(_行,(_身長,_体重),[]), 行を得る(_次の行,_終了状態), 身長と体重のセットを得る(_終了状態,_次の行,_残りの行ならび). 'できるだけ多くの人数で、肩車をしようと思います。'(_人間ならび,_最大人数) :- findall(_肩車人数,( 肩車人数(_人間ならび,_肩車人数)),_肩車人数ならび), max_list(_肩車人数ならび,_最大人数). 肩車人数(_人間ならび,_肩車人数) :- select(_取りだされた人間,_人間ならび,_残りの人間ならび), 肩車を重ねる(_取りだされた人間,_残りの人間ならび,_肩車重ね), length(_肩車重ね,_肩車人数). 肩車を重ねる(_自分,_人間ならび,[_自分|_肩車重ね]) :- 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね). 肩車を重ねる(_一番上の人間,_,[_一番上の人間]). 上の人を選択できる限り選択する(_自分,_人間ならび,_肩車重ね) :- select(_上の人間,_人間ならび,_残りの人間ならび), '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'(_上の人間,_自分), 肩車を重ねる(_上の人間,_残りの人間ならび,_肩車重ね). '肩車できる条件は、自分より上の人間の、「身長」と「体重」の値両方が、自分より小さい場合に限ります。'([_上の人間の身長,_上の人間の体重],[_自分の身長,_自分の体重]) :- _上の人間の身長 @< _自分の身長, _上の人間の体重 @< _自分の体重. 行を得る(_行,_終了状態) :- get_char(_文字), 行を得る(_文字,_文字ならび,_終了状態), atomic_list_concat(_文字ならび,_行). 行を得る(_入力文字,[],_終了状態) :- 入力文字が改行文字またはend_of_fileの時停止する(_入力文字,_終了状態),!. 行を得る(_文字,_行ならび,_終了状態) :- 行を得るために文字入力を続ける(_文字,_行ならび,_終了状態). 入力文字が改行文字またはend_of_fileの時停止する('\n',改行終了). 入力文字が改行文字またはend_of_fileの時停止する(end_of_file,入力終了). 行を得るために文字入力を続ける(_文字,[_文字|_残りの文字ならび],_終了状態) :- get_char(_次の文字), 行を得る(_次の文字,_残りの文字ならび,_終了状態). % 以下のサイトは # 出典 :: CodeIQ q1533 # # 中学数学のひとつの山ともいえる、因数分解。 # 数学を嫌いになるきっかけとなってしまった人も多いのではないでしょうか? # そんな因数分解を、プログラミングで解いてみましょう! # # ■問題 # 二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 # これを(ax+b)(cx+d)の形に因数分解し、a, b, c, dの値を出力してください。 # # # ■例 # 【入力】 # 4, -23, 15 # 【出力】 # 4, -3, 1, -5 # # つまり、4x2-23x+15=(4x-3)(x-5)という因数分解を行った結果を出力するプログラムです。 # (出力は、順番を入れ替えた1, -5, 4, -3でも正解となりますが、いずれか一方を出力するものとします。) # なお、α、β、γとして与えられる数字は互いに素な整数であるものとします。 # ※出力エラーの表記は、エラーとわかる何らかの出力で構いません。(※2015年4月20日13:30追記) # # # 最低限、以下のテストデータで正しい出力が得られることを確認してください。 # # 【テストデータ1:入力】 # 3, 10, 3 # 【出力】 # 1, 3, 3, 1 または 3, 1, 1, 3 # # 【テストデータ2:入力】 # 6, -1, -15 # 【出力】 # 2, 3, 3, -5 または 3, -5, 2, 3 # # 【テストデータ3:入力】 # 12, -1, -6 # 【出力】 # 3, 2, 4, -3 または 4, -3, 3, 2 # # 【テストデータ4:入力】 # 3, -8, 4 # 【出力】 # 1, -2, 3, -2 または 3, -2, 1, -2 # # 【テストデータ5:入力】 # 3, 5, 7 # 【出力】 # エラー # '二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 これを(ax+b)(cx+d)の形に因数分解し、a, b, c, dの値を出力してください。'(_α,_β,_γ,_a,_b,_c,_d) :- findall([_a,_b,_c,_d], '二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 これを(ax+b)(cx+d)の形に因数分解し、'(_α,_β,_γ,_a,_b,_c,_d),_解ならび), 重複解を取り除く(_解ならび,_a,_b,_c,_d). '二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 これを(ax+b)(cx+d)の形に因数分解し、'(_α,_β,_γ,_a,_b,_c,_d) :- '_a,_b,_c,_dの候補を得る'(_α,_γ,_a,_b,_c,_d), _β is _a * _d + _b * _c. '_a,_b,_c,_dの候補を得る'(_α,_γ,_a,_b,_c,_d) :- '_a,_c候補'(_α,_a,_c), '_b,_d候補'(_γ,_b,_d). '_a,_c候補'(_α,_a,_c) :- 因数に分解する(_α,_a,_c) . '_b,_d候補'(_γ,_b,_d) :- 因数に分解する(_γ,_b,_d) . 因数に分解する(A,B,C) :- 'Aの絶対値からB_1候補を得る'(A,_正のA,B_1), '因数B_1,C_1を得る'(_正のA,B_1,C_1), 符号の組合せ(A,B_1,C_1,B,C). 'Aの絶対値からB_1候補を得る'(A,_正のA,B_1) :- _正のA is abs(A), between(1,_正のA,B_1). '因数B_1,C_1を得る'(_正のA,B_1,C_1) :- 0 is _正のA mod B_1, C_1 is _正のA // B_1. 符号の組合せ(A,B_1,C_1,B,C) :- 'Aが正の時は二数の符号は同じになる'(A,B_1,C_1,B,C). 符号の組合せ(A,B_1,C_1,B,C) :- 'Aが負の時は二数の符号は異なる'(A,B_1,C_1,B,C). 'Aが正の時は二数の符号は同じになる'(A,B_1,C_1,B,C) :- A > 0, 二数の符号は同じになる(A,B_1,C_1,B,C). 二数の符号は同じになる(A,B,C,B,C). 二数の符号は同じになる(A,B_1,C_1,B,C) :- B is B_1 * -1, C is C_1 * -1. 'Aが負の時は二数の符号は異なる'(A,B_1,C_1,B,C) :- A < 0, 二数の符号は異なる(A,B_1,C_1,B,C). 二数の符号は異なる(A,B_1,C,B,C) :- B is B_1 * -1. 二数の符号は異なる(A,B,C_1,B,C) :- C is C_1 * -1. 重複解を取り除く(_解ならび,_a,_b,_c,_d) :- append(L0,[[_a,_b,_c,_d]|_],_解ならび), \+(member([_c,_d,_a,_b],L0)). % 以下のサイトは # 出典 :: CodeIQ q1533 # # 中学数学のひとつの山ともいえる、因数分解。 # 数学を嫌いになるきっかけとなってしまった人も多いのではないでしょうか? # そんな因数分解を、プログラミングで解いてみましょう! # # ■問題 # 二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 # これを(ax+b)(cx+d)の形に因数分解し、a, b, c, dの値を出力してください。 # # # ■例 # 【入力】 # 4, -23, 15 # 【出力】 # 4, -3, 1, -5 # # つまり、4x2-23x+15=(4x-3)(x-5)という因数分解を行った結果を出力するプログラムです。 # (出力は、順番を入れ替えた1, -5, 4, -3でも正解となりますが、いずれか一方を出力するものとします。) # なお、α、β、γとして与えられる数字は互いに素な整数であるものとします。 # ※出力エラーの表記は、エラーとわかる何らかの出力で構いません。(※2015年4月20日13:30追記) # # # 最低限、以下のテストデータで正しい出力が得られることを確認してください。 # # 【テストデータ1:入力】 # 3, 10, 3 # 【出力】 # 1, 3, 3, 1 または 3, 1, 1, 3 # # 【テストデータ2:入力】 # 6, -1, -15 # 【出力】 # 2, 3, 3, -5 または 3, -5, 2, 3 # # 【テストデータ3:入力】 # 12, -1, -6 # 【出力】 # 3, 2, 4, -3 または 4, -3, 3, 2 # # 【テストデータ4:入力】 # 3, -8, 4 # 【出力】 # 1, -2, 3, -2 または 3, -2, 1, -2 # # 【テストデータ5:入力】 # 3, 5, 7 # 【出力】 # エラー # '二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 これを(ax+b)(cx+d)の形に因数分解し、a, b, c, dの値を出力してください。'(_α,_β,_γ,_a,_b,_c,_d) :- findall([_a,_b,_c,_d], '二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 これを(ax+b)(cx+d)の形に因数分解し、'(_α,_β,_γ,_a,_b,_c,_d),_解ならび), 重複解を取り除く(_解ならび,_a,_b,_c,_d). '二次式αx2+βx+γにおいて、係数α、β、γの値が与えられます。 これを(ax+b)(cx+d)の形に因数分解し、'(_α,_β,_γ,_a,_b,_c,_d) :- 検査範囲の確定(_α,_γ,S_1,E_1,S_2,E_2), '_a,_b,_c,_dの候補を得る'(_α,_γ,S_1,E_1,S_2,E_2,_a,_b,_c,_d), _β is _a * _d + _c * _b. '_a,_b,_c,_dの候補を得る'(_α,_γ,S_1,E_1,S_2,E_2,_a,_b,_c,_d) :- '_a,_c候補'(_α,S_1,E_1,_a,_c), '_b,_d候補'(_γ,S_2,E_2,_b,_d). '_a,_c候補'(_α,S_1,E_1,_a,_c) :- between(S_1,E_1,_a), between(S_1,E_1,_c), _α is _a * _c. '_b,_d候補'(_γ,S_2,E_2,_b,_d) :- between(S_2,E_2,_b), between(S_2,E_2,_d), _γ is _b * _d. 検査範囲の確定(_α,_γ,S_1,E_1,S_2,E_2) :- '_αの検査範囲'(_α,S_1,E_1), '_γの検査範囲'(_γ,S_2,E_2). '_αの検査範囲'(_α,S_1,E_1) :- E_1 is abs(_α), S_1 is -1 * E_1. '_γの検査範囲'(_γ,S_2,E_2) :- E_2 is abs(_γ), S_2 is -1 * E_2. 重複解を取り除く(_解ならび,_a,_b,_c,_d) :- append(L0,[[_a,_b,_c,_d]|_],_解ならび), \+(member([_c,_d,_a,_b],L0)), '_a,_cと_b,_dにそれぞれ-1を掛ける'(_a,_b,_c,_d,_a_1,_b_1,_c_1,_d_1), \+(member([_a_1,_b_1,_c_1,_d_1],L0)). '_a,_cと_b,_dにそれぞれ-1を掛ける'(_a,_b,_c,_d,_a_1,_b_1,_c_1,_d_1) :- _a_1 is _a * -1, _b_1 is _b * -1, _c_1 is _c * -1, _d_1 is _d * -1. % 以下のサイトは # 出典 :: CodeIQ q1365 # # 成績の分布などを表すのに使われる度数分布表。 # ひと目で全体の散らばり具合がわかって便利です。 # # 【問題】 # 今回は素数の度数分布表を作ってみます。 # 入力として2つの正の整数が与えられます。 # 一つ目は分布させる素数の最大値、二つ目は区切りの大きさです。 # 例えば、30と5が与えられたとき、30までの素数を5で区切って出力します。 # 30までの素数は2, 3, 5, 7, 11, 13, 17, 19, 23, 29ですので、 # 出力内容は以下のようになります。 # 01-05:*** # 06-10:* # 11-15:** # 16-20:** # 21-25:* # 26-30:* # 同様に、40と7が与えられると、以下のように出力されます。 # 01-07:**** # 08-14:** # 15-21:** # 22-28:* # 29-35:** # 36-42:* # 上記のように出力するプログラムを作成してください。 # なお、最低限、以下の入力に対して正常に動作することを確認してください。 # 入力1:100 15 # 入力2:1200 25 # 入力3:12345 789 # '今回は素数の度数分布表を作ってみます。'(_最大値,_区切り) :- 素数の度数分布表(_最大値,_区切り,_度数分布表), 度数分布図として表示する(_度数分布表). 素数の度数分布表(_最大値,_区切り,_度数分布表) :- 素数を生成する(_最大値,_素数ならび), 素数の度数分布表(_素数ならび,_区切り,_最大値,_度数分布表). 素数を生成する(_最大値,_素数ならび) :- findall(_自然数,between(2,_最大値,_自然数),L), エラトステネスの篩(L,_素数ならび). エラトステネスの篩([],[]) :- !. エラトステネスの篩([M|R1],[M|R2]) :- エラトステネスの篩(M,R1,L), エラトステネスの篩(L,R2). エラトステネスの篩(M,R1,L) :- findall(N,( member(N,R1), \+(0 is N mod M)),L). 素数の度数分布表(_素数ならび,_区切り,_最大値,_度数分布表) :- findall([_範囲下限,_範囲上限,_度数],( 素数の度数分布(_素数ならび,_最大値,_区切り,1,_区切り,_範囲下限,_範囲上限,_度数)),_度数分布表). 素数の度数分布(_素数ならび,_最大値,_区切り,_範囲下限,_範囲上限,_範囲下限,_範囲上限,_度数) :- 範囲と度数を得る(_素数ならび,_最大値,_範囲下限,_範囲上限,_度数). 素数の度数分布(_素数ならび,_最大値,_区切り,_範囲下限_1,_範囲上限_1,_範囲下限,_範囲上限,_度数) :- '範囲をずらしながら、素数の度数分布を得る'(_素数ならび,_最大値,_区切り,_範囲下限_1,_範囲上限_1,_範囲下限,_範囲上限,_度数). 範囲と度数を得る(_素数ならび,_最大値,_範囲下限,_範囲上限,_度数) :- _範囲下限 =< _最大値, 度数((between(_範囲下限,_範囲上限,_素数),member(_素数,_素数ならび)),_度数). '範囲をずらしながら、素数の度数分布を得る'(_素数ならび,_最大値,_区切り,_範囲下限_1,_範囲上限_1,_範囲下限,_範囲上限,_度数) :- _範囲下限_1 =< _最大値, 次の範囲を確定する(_区切り,_範囲下限_1,_範囲上限_1,_次の範囲下限,_次の範囲上限), 素数の度数分布(_素数ならび,_最大値,_区切り,_次の範囲下限,_次の範囲上限,_範囲下限,_範囲上限,_度数). 次の範囲を確定する(_区切り,_範囲下限_1,_範囲上限_1,_次の範囲下限,_次の範囲上限) :- _次の範囲下限 is _範囲下限_1 + _区切り, _次の範囲上限 is _範囲上限_1 + _区切り. 度数(_目標,_度数) :- findall(_,_目標,L), length(L,_度数). 度数分布図として表示する(_度数分布表) :- 範囲の下限値と上限値のそれぞれの最大値の桁数を得る(_度数分布表,_範囲下限の表示桁数,_範囲上限の表示桁数), 範囲毎に柱を表示する(_度数分布表,_範囲下限の表示桁数,_範囲上限の表示桁数). 範囲の下限値と上限値のそれぞれの最大値の桁数を得る(_度数分布表,_範囲下限の表示桁数,_範囲上限の表示桁数) :- 範囲下限値の最大値の桁数を得る(_度数分布表,_範囲下限の表示桁数), 範囲上限値の最大値の桁数を得る(_度数分布表,_範囲上限の表示桁数). 範囲下限値の最大値の桁数を得る(_度数分布表,_範囲下限の表示桁数) :- findall(_桁数,範囲下限値の桁数(_度数分布表,_桁数),L), max_list(L,_範囲下限の表示桁数). 範囲下限値の桁数(_度数分布表,_下限桁数) :- member([_範囲下限,_,_],_度数分布表), number_chars(_範囲下限,Chars), length(Chars,_下限桁数). 範囲上限値の最大値の桁数を得る(_度数分布表,_範囲の表示桁数) :- findall(_桁数,範囲上限値の桁数(_度数分布表,_桁数),L), max_list(L,_範囲の表示桁数). 範囲上限値の桁数(_度数分布表,_上限桁数) :- member([_,_範囲上限,_],_度数分布表), number_chars(_範囲上限,Chars), length(Chars,_上限桁数). 範囲毎に柱を表示する(_度数分布表,_範囲下限の表示桁数,_範囲上限の表示桁数) :- forall( member([_範囲下限,_範囲上限,_度数],_度数分布表), 柱を表示する(_範囲下限の表示桁数,_範囲上限の表示桁数,_範囲下限,_範囲上限,_度数)). 柱を表示する(_範囲下限の表示桁数,_範囲上限の表示桁数,_範囲下限,_範囲上限,_度数) :- ヘッドゼロサプライで範囲を表現する(_範囲下限の表示桁数,_範囲上限の表示桁数,_範囲下限,_範囲上限,_範囲表現文字列), 星文字列(_度数,_星文字列), writef('%t:%t\n',[_範囲表現文字列,_星文字列]). ヘッドゼロサプライで範囲を表現する(_範囲下限の表示桁数,_範囲上限の表示桁数,_範囲下限,_範囲上限,_範囲表現文字列) :- ヘッドゼロサプライ(_範囲下限の表示桁数,_範囲下限,_表示範囲下限), ヘッドゼロサプライ(_範囲上限の表示桁数,_範囲上限,_表示範囲上限), atomic_list_concat([_表示範囲下限,'-',_表示範囲上限],_範囲表現文字列). ヘッドゼロサプライ(_桁数,_数値,_ヘッドゼロサプライ数値表現) :- ヘッドゼロサプライを構成する枠を作る(_桁数,_ヘッドゼロサプライされたリスト), 数値を文字のリスト変換してその頭部にゼロを埋める(_数値,_ヘッドゼロサプライされたリスト), 文字リストを文字列に変換(_ヘッドゼロサプライされたリスト,_ヘッドゼロサプライ数値表現). ヘッドゼロサプライを構成する枠を作る(_桁数,_ヘッドゼロサプライされたリスト) :- length(_ヘッドゼロサプライされたリスト,_桁数). 数値を文字のリスト変換してその頭部にゼロを埋める(_数値,_ヘッドゼロサプライされたリスト) :- number_chars(_数値,_数字のリスト), append(_頭部の枠リスト,_数字のリスト,_ヘッドゼロサプライされたリスト), 全ての要素が同じ(_頭部の枠リスト,'0'). 全ての要素が同じ([],_). 全ての要素が同じ([V|R],V) :- 全ての要素が同じ(R,V). 星文字列(_度数,_星文字列) :- findall(*,between(1,_度数,_),L), atomic_list_concat(L,_星文字列). 文字リストを文字列に変換(_ヘッドゼロサプライされたリスト,_ヘッドゼロサプライ数値表現) :- atom_chars(_ヘッドゼロサプライ数値表現,_ヘッドゼロサプライされたリスト). % 以下のサイトは # 出典 :: CodeIQ q1385 言語不問:通分と約分を実装しよう # # 小学生が分数を学ぶときに、最初に躓くのが「通分」です。 # # 分母の異なる分数の足し算や引き算を行うとき、先に通分を行っておく必要があります。 # # また、計算した結果、「約分」できる場合は、可能な限り簡単な分数にしないと正解になりません。 # # 【問題】 # # では、入力される二つの分数について足し算を行った時に、 # # 正しい答えを出力するプログラムを作り、 # # 問1〜問5の標準入力に対して、出力内容を答えてください。 # # ※分母が1の時には整数として出力してください。 # # ■例 # # 例1) # # 【標準入力】 # # 5/6 # # 1/10 # # 【標準出力】 # # 14/15 # # 例2) # # 【標準入力】 # # 1/3 # # 2/3 # # 【標準出力】 # # 1 # # ■問1〜5 # # 問1) # # 1/3 # # 2/7 # # 問2) # # 2/8 # # 3/5 # # 問3) # # 3/10 # # 1/6 # # 問4) # # 3/4 # # 5/8 # # 問5) # # 2/5 # # 2/3 # # 【解答方法】 # # 解答用テキストファイルanswer_q1385.txtをダウンロードし、必要事項をご記入ください。 # # 必須事項がすべて記入されていることをご確認いただいた後、テキストファイルのままアップロードしてください。 # # 【注意】 # # ・ご提出いただいたプログラムは個別に実行テストを行いますので、 # #  解答用テキストファイルに書かれた解答が正解していても最高評価になるとは限りません。 # # ・プログラミング言語は不問ですが、古すぎる実行環境・特殊な設備を要する実行環境では採点できない場合がございます。 # # ・使用する言語は1解答につき必ず1種類でお願いします。 # #  どうしても複数の言語を用いる場合は、解答に「メインの言語名」を明記してください。 # '問1〜問5の標準入力に対して、出力内容を答えてください。 ■問1〜5 問1) 1/3 2/7 問2) 2/8 3/5 問3) 3/10 1/6 問4) 3/4 5/8 問5) 2/5 2/3' :- between(1,5,N), '入力される二つの分数について足し算を行った時に、正しい答えを出力する', N = 5. '入力される二つの分数について足し算を行った時に、正しい答えを出力する' :- 入力される二つの分数(_分子_1 / _分母_1,_分子_2 / _分母_2), 分数の加算(_分子_1 / _分母_1,_分子_2 / _分母_2,_加算された分子 / _加算された分母), 約分(_加算された分子 / _加算された分母,_約分された分子 / _約分された分母), 答えを出力する(_約分された分子 / _約分された分母). 分数の加算(_分子_1 / _分母_1,_分子_2 / _分母_2,_加算された分子 / _通分された分母) :- 通分(_分子_1 / _分母_1,_分子_2 / _分母_2,_通分された分子_1 / _通分された分母,_通分された分子_2 / _通分された分母), _加算された分子 is _通分された分子_1 + _通分された分子_2,!. 入力される二つの分数(_分子_1 / _分母_1,_分子_2 / _分母_2) :- 入力される分数(_分子_1 / _分母_1), 入力される分数(_分子_2 / _分母_2). 入力される分数(_分子_1 / _分母_1) :- 行入力(_行), read_term_from_atom(_行,_分子 / _分母,[]). 行入力(_行) :- get_char(_先読み文字), 行ならびを得る(_先読み文字,_行ならび), atom_chars(_行,_行ならび). 行ならびを得る('\n',[]). 行ならびを得る(_先読み文字,[_先読み文字|R]) :- get_char(_次の文字), 行ならびを得る(_次の文字,R). 答えを出力する(_約分された分子 / _約分された分母) :- writef('%t\n',[_約分された分子 / _約分された分母]). 約分(_分子 / _分母,X) :- 最大公約数で分子分母を割って約分する(_分子,_分母,_分子_1,_分母_1), 負数の場合のマイナス符号は分子側に付ける(_分子_1,_分母_1,_分子_2,_分母_2), 分母が1の時は整数に変形(_分子_2,_分母_2,X). 最大公約数で分子分母を割って約分する(_分子_1,_分母_1,_分子,_分母) :- 最大公約数(_分子_1,_分母_1,_最大公約数), _分子 is _分子_1 // _最大公約数, _分母 is _分母_1 // _最大公約数. 負数の場合のマイナス符号は分子側に付ける(_分子_1,_分母_1,_分子,_分母) :- 分母が負数だったら分子分母ともに符号を反転する(_分子_1,_分母_1,_分子,_分母),!. 負数の場合のマイナス符号は分子側に付ける(_分子,_分母,_分子,_分母). 分母が負数だったら分子分母ともに符号を反転する(_分子_1,_分母_1,_分子,_分母) :- _分母_1 =< 0, _分子 is _分子_1 * -1, _分母 is _分母_1 * -1. 分母が1の時は整数に変形(_分子,1,_分子) :- !. 分母が1の時は整数に変形(_分子,1.0,_分子) :- !. 分母が1の時は整数に変形(_分子,_分母,_分子 / _分母). 通分(_分子_1 / _分母_1,_分子_2 / _分母_2,_通分された分子_1 / _最小公倍数,_通分された分子_2 / _最小公倍数) :- 最小公倍数([_分母_1,_分母_2],_最小公倍数), _通分された分子_1 is _分子_1 * (_最小公倍数 // _分母_1), _通分された分子_2 is _分子_2 * (_最小公倍数 // _分母_2). 最大公約数([_整数],_整数). 最大公約数([_整数|R],_最大公約数) :- 最大公約数(R,_最大公約数_2), 二つの整数の最大公約数(_整数,_最大公約数_2,_最大公約数). 二つの整数の最大公約数(M,N,X) :- 二つの整数の絶対値をとる(M,N,M_2,N_2), 最大公約数をユークリッドの互除法で求める(M_2,N_2,Y), 負数解の可能性も探る(M,M_2,N,N_2,Y,X). 負数解の可能性も探る(M,M_2,N,N_2,Y,X) :- setof(X,[M,M_2,N,N_2,Y,X] ^ 負数解の可能性(M,M_2,N,N_2,Y,X),L), member(X,L). 負数解の可能性(M,M_2,_,_,Y,X) :- X is Y * (M // M_2). 負数解の可能性(_,_,N,N_2,Y,X) :- X is Y * (N // N_2). 二つの整数の絶対値をとる(M,N,M_2,N_2) :- M_2 is abs(M), N_2 is abs(N). 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 最小公倍数(_整数ならび,_最小公倍数) :- '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'(_整数ならび,_最小公倍数). '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'([_整数],_整数). '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'([_整数|R],_最小公倍数) :- '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'(R,_最小公倍数_1), 二つの整数の最小公倍数(_整数,_最小公倍数_1,_最小公倍数). 二つの整数の最小公倍数(A,B,X) :- 二つの整数の最大公約数(A,B,_最大公約数), setof(X,[X,A,B,_最大公約数] ^ (X is A * B // _最大公約数),L), member(X,L). % 以下のサイトは # 出典 :: 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. % 以下のサイトは # 出典 :: CodeIQ q1346 # # あるとき、マシューは美人な双子と出会った。お姉さん、妹さん、実に美しいのだ!この2人、双子でありつつ、とても仲が良い。仲が良すぎて、同じタイミングで話すという特技がある。 # # 姉&妹 「あ。マシューだ。」 # マシュー「いかにもマシューだ。」 # 姉&妹 「双子ならではのクイズを出してもいい?」 # マシュー「え、あ、いいよ。」 # 姉&妹 「1000以下の双子素数をすべて出力せよ。」 # マシュー「・・・え?」 # 姉&妹 「1000以下の双子素数をすべて出力せよ。」 # # なんだかとんでもないクイズに巻き込まれてしまった!プログラムを書いて答えてほしい。 # # 解き方だが、 (3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力して欲しい。 # '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する' :- '1000以下の素数ならびを小さい順に得る'(_1000以下の素数ならび), '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の素数ならび). '1000以下の素数ならびを小さい順に得る'(_1000以下の素数ならび) :- findall(M,between(2,1000,M),_小さい順に並んだ2から1000までの整数ならび), '1000以下の素数ならびを小さい順に得る'(_小さい順に並んだ2から1000までの整数ならび,_1000以下の素数ならび). '1000以下の素数ならびを小さい順に得る'([],[]) :- !. '1000以下の素数ならびを小さい順に得る'([_確定した素数|R1],[_確定した素数|R2]) :- 'R1の中の_確定した素数で割り切れないものだけを残し篩に掛ける'(_確定した素数,R1,R2). 'R1の中の_確定した素数で割り切れないものだけを残し篩に掛ける'(_確定した素数,R1,R2) :- 'R1の中の_確定した素数で割り切れないものだけを残す'(_確定した素数,R1,_残ったならび), '1000以下の素数ならびを小さい順に得る'(_残ったならび,R2). 'R1の中の_確定した素数で割り切れないものだけを残す'(_確定した素数,R1,_残ったならび) :- findall(_確定した素数で割り切れないもの,'R1の中で_確定した素数で割り切れないもの'(R1,_確定した素数,_確定した素数で割り切れないもの),_残ったならび). 'R1の中で_確定した素数で割り切れないもの'(R1,_確定した素数,_確定した素数で割り切れないもの) :- member(_確定した素数で割り切れないもの,R1), \+(0 is _確定した素数で割り切れないもの mod _確定した素数). '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の素数ならび) :- '1000以下の双子素数のすべてを'(_1000以下の素数ならび,_1000以下の双子素数ならび), '(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の双子素数ならび). '1000以下の双子素数のすべてを'(_1000以下の素数ならび,_1000以下の双子素数ならび) :- findall([_1,_2],'1000以下の双子素数の'(_1000以下の素数ならび,_1,_2),_1000以下の双子素数ならび). '1000以下の双子素数の'(_1000以下の素数ならび,_1,_2) :- append(_,[_1,_2|_],_1000以下の素数ならび), 2 is _2 - _1. '(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の双子素数ならび) :- 小さい数の組み合わせから順番に(_1000以下の双子素数ならび,_1,_2,R), 'カンマ区切りで標準出力する'(R,_1,_2), R = []. 小さい数の組み合わせから順番に(_1000以下の双子素数ならび,_1,_2,R) :- append(_,[[_1,_2]|R],_1000以下の双子素数ならび). 'カンマ区切りで標準出力する'(R,_1,_2) :- 'Rが[]の時は_1,_2出力後カンマは省略して改行する'(R,_1,_2). 'カンマ区切りで標準出力する'(R,_1,_2) :- 'Rが[]でない時は_1,_2出力後カンマを出力する'(R,_1,_2). 'Rが[]の時は_1,_2出力後カンマは省略して改行する'([],_1,_2) :- writef('(%t,%t)\n',[_1,_2]). 'Rが[]でない時は_1,_2出力後カンマを出力する'([_|_],_1,_2) :- writef('(%t,%t), ',[_1,_2]). :- '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する',halt. % 以下のサイトは # 出典 :: CodeIQ q1346 # # あるとき、マシューは美人な双子と出会った。お姉さん、妹さん、実に美しいのだ!この2人、双子でありつつ、とても仲が良い。仲が良すぎて、同じタイミングで話すという特技がある。 # # 姉&妹 「あ。マシューだ。」 # マシュー「いかにもマシューだ。」 # 姉&妹 「双子ならではのクイズを出してもいい?」 # マシュー「え、あ、いいよ。」 # 姉&妹 「1000以下の双子素数をすべて出力せよ。」 # マシュー「・・・え?」 # 姉&妹 「1000以下の双子素数をすべて出力せよ。」 # # なんだかとんでもないクイズに巻き込まれてしまった!プログラムを書いて答えてほしい。 # # 解き方だが、 (3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力して欲しい。 # '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する' :- '1000以下の素数ならびを小さい順に得る'(_1000以下の素数ならび), '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の素数ならび). '1000以下の素数ならびを小さい順に得る'(_1000以下の素数ならび) :- findall(M,between(2,1000,M),_小さい順に並んだ2から1000までの整数ならび), エラトステネスの篩(_小さい順に並んだ2から1000までの整数ならび,_1000以下の素数ならび). エラトステネスの篩([],[]) :- !. エラトステネスの篩([_確定した素数|R1],[_確定した素数|R2]) :- 'R1の中の_確定した素数で割り切れないものだけを残し篩に掛ける'(_確定した素数,R1,R2). 'R1の中の_確定した素数で割り切れないものだけを残し篩に掛ける'(_確定した素数,R1,R2) :- 'R1の中の_確定した素数で割り切れないものだけを残す'(_確定した素数,R1,_残ったならび), エラトステネスの篩(_残ったならび,R2). 'R1の中の_確定した素数で割り切れないものだけを残す'(_確定した素数,R1,_残ったならび) :- findall(_確定した素数で割り切れないもの,( 'R1の中で_確定した素数で割り切れないもの'(R1,_確定した素数,_確定した素数で割り切れないもの)),_残ったならび). 'R1の中で_確定した素数で割り切れないもの'(R1,_確定した素数,_確定した素数で割り切れないもの) :- member(_確定した素数で割り切れないもの,R1), \+(0 is _確定した素数で割り切れないもの mod _確定した素数). '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の素数ならび) :- '1000以下の双子素数のすべてを'(_1000以下の素数ならび,_1000以下の双子素数ならび), '(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の双子素数ならび). '1000以下の双子素数のすべてを'(_1000以下の素数ならび,_1000以下の双子素数ならび) :- findall([_1,_2],'1000以下の双子素数の'(_1000以下の素数ならび,_1,_2),_1000以下の双子素数ならび). '1000以下の双子素数の'(_1000以下の素数ならび,_1,_2) :- append(_,[_1,_2|_],_1000以下の素数ならび), 2 is _2 - _1. '(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する'(_1000以下の双子素数ならび) :- 小さい数の組み合わせから順番に(_1000以下の双子素数ならび,_1,_2,R), 'カンマ区切りで標準出力する'(R,_1,_2), R = []. 小さい数の組み合わせから順番に(_1000以下の双子素数ならび,_1,_2,R) :- append(_,[[_1,_2]|R],_1000以下の双子素数ならび). 'カンマ区切りで標準出力する'(R,_1,_2) :- 'Rが[]の時は_1,_2出力後カンマは省略して改行して終わる'(R,_1,_2),!. 'カンマ区切りで標準出力する'(_,_1,_2) :- writef('(%t,%t), ',[_1,_2]). 'Rが[]の時は_1,_2出力後カンマは省略して改行して終わる'([],_1,_2) :- writef('(%t,%t)\n',[_1,_2]). :- '1000以下の双子素数のすべてを(3, 5), (5, 7), (11, 13),などのように小さい数の組み合わせから順番にカンマ区切りで標準出力する',halt. % 以下のサイトは # 指数表記を使わずに整数を素因数分解することを考えます。 # つまり、「72=2×2×2×3×3」のように表現します。 # このときに使う『×』の数は4つです。 # # ここで、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなるものを考えます。 # 上の72の例であれば、各桁の和は7+2で「9」ですが、『×』の数は「4」なので不適です。 # # この条件を満たすものとしては、「110=2×5×11」や「210=2×3×5×7」、 # 「512=2×2×2×2×2×2×2×2×2」などがあります。 # # では、4桁の整数で上記の条件を満たす数をすべて求めてください。 # # プログラミング言語は不問です。 # お好きな言語で計算してください。 # # 【解答方法】 # 解答用テキストファイルをダウンロードしてください。 # # 解答用テキストファイルを完成させ、アップロードしてください。 '指数表記を使わずに4桁の整数を素因数分解して、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなる整数を全て求める' :- findall(_4桁の数,( '4桁の数の各桁の合計'(_4桁の数,_乗算記号度数), 指数表記を使わず素因数分解を乗算記号で表現した場合の乗算記号度数(_4桁の数,_指数表記を使った素因数分解,_乗算記号度数)),L), writef('%t\n',[L]). '4桁の数の各桁の合計'(_4桁の数,_各桁の合計) :- between(1000,9999,_4桁の数), 各桁の合計(_4桁の数,0,_各桁の合計). 各桁の合計(0,_各桁の合計,_各桁の合計) :- !. 各桁の合計(N,_各桁の合計_1,_各桁の合計) :- M is N mod 10, N_1 is N // 10, _各桁の合計_2 is _各桁の合計_1 + M, 各桁の合計(N_1,_各桁の合計_2,_各桁の合計). 指数表記を使わず素因数分解を乗算記号で表現した場合の乗算記号度数(N,_指数表記を使った素因数分解,_乗算記号度数) :- 素因数分解(2,N,N,0,[],L), 素因数分解項構成(L,_指数表記を使った素因数分解,0,_乗算記号度数). 素因数分解(U,M,N,C,X,X) :- U > N // 2,!. 素因数分解(U,M,N,0,Y,X) :- member(J^_,Y), 0 is U mod J, U2 is U + 2, 素因数分解(U2,N,N,0,Y,X),!. 素因数分解(2,M,N,0,Y,X) :- \+(0 is M mod 2), 素因数分解(3,N,N,0,Y,X),!. 素因数分解(2,M,N,C,Y,X) :- \+(0 is M mod 2), 素因数分解(3,N,N,0,[2^C|Y],X),!. 素因数分解(U,M,N,0,Y,X) :- \+(U=2), \+(0 is M mod U), U2 is U + 2, 素因数分解(U2,N,N,0,Y,X),!. 素因数分解(U,M,N,C,Y,X) :- \+(U=2), \+(0 is M mod U), U2 is U + 2, 素因数分解(U2,N,N,0,[U^C|Y],X),!. 素因数分解(U,M,N,C,Y,X) :- 0 is M mod U, C2 is C + 1, M1 is M // U, 素因数分解(U,M1,N,C2,Y,X). 素因数分解項構成([J^M],J^M,_乗算記号度数_1,_乗算記号度数) :- _乗算記号度数 is _乗算記号度数_1 + M -1,!. 素因数分解項構成([J^M|R1],B * J^M,_乗算記号度数_1,_乗算記号度数) :- _乗算記号度数_2 is _乗算記号度数_1 + M, 素因数分解項構成(R1,B,_乗算記号度数_2,_乗算記号度数). :- '指数表記を使わずに4桁の整数を素因数分解して、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなる整数を全て求める',halt. % 以下のサイトは # 指数表記を使わずに整数を素因数分解することを考えます。 # つまり、「72=2×2×2×3×3」のように表現します。 # このときに使う『×』の数は4つです。 # # ここで、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなるものを考えます。 # 上の72の例であれば、各桁の和は7+2で「9」ですが、『×』の数は「4」なので不適です。 # # この条件を満たすものとしては、「110=2×5×11」や「210=2×3×5×7」、 # 「512=2×2×2×2×2×2×2×2×2」などがあります。 # # では、4桁の整数で上記の条件を満たす数をすべて求めてください。 # # プログラミング言語は不問です。 # お好きな言語で計算してください。 # # 【解答方法】 # 解答用テキストファイルをダウンロードしてください。 # # 解答用テキストファイルを完成させ、アップロードしてください。 '指数表記を使わずに4桁の整数を素因数分解して、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなる整数を全て求める'(L) :- findall(N,( between(1000,9999,N), 各桁の合計(N,0,_乗算記号度数), 素因数分解(N,X,_乗算記号度数)),L). 各桁の合計(0,_各桁の合計,_各桁の合計) :- !. 各桁の合計(N,_各桁の合計_1,_各桁の合計) :- M is N mod 10, N_1 is N // 10, _各桁の合計_2 is _各桁の合計_1 + M, 各桁の合計(N_1,_各桁の合計_2,_各桁の合計). 素因数分解表示(N) :- 素因数分解(N,X,_乗算記号度数), writef('%t = %t\n乗算記号度数 = %t\n',[N,X,_乗算記号度数]). 素因数分解(N,X,_乗算記号度数) :- 素因数分解(2,N,N,0,[],L,0,_乗算記号度数_1), 素因数分解項構成(L,X,_乗算記号度数_1,_乗算記号度数). 素因数分解(U,M,N,C,X,X,_乗算記号度数,_乗算記号度数) :- U > N // 2,!. 素因数分解(U,M,N,0,Y,X,_乗算記号度数_1,_乗算記号度数) :- member(J^_,Y), 0 is U mod J, U2 is U + 2, 素因数分解(U2,N,N,0,Y,X,_乗算記号度数_1,_乗算記号度数),!. 素因数分解(2,M,N,0,Y,X,_乗算記号度数_1,_乗算記号度数) :- \+(0 is M mod 2), 素因数分解(3,N,N,0,Y,X,_乗算記号度数_1,_乗算記号度数),!. 素因数分解(2,M,N,C,Y,X,_乗算記号度数_1,_乗算記号度数) :- \+(0 is M mod 2), _乗算記号度数_2 is _乗算記号度数_1 + C - 1, 素因数分解(3,N,N,0,[2^C|Y],X,_乗算記号度数_2,_乗算記号度数),!. 素因数分解(U,M,N,0,Y,X,_乗算記号度数_1,_乗算記号度数) :- \+(U=2), \+(0 is M mod U), U2 is U + 2, 素因数分解(U2,N,N,0,Y,X,_乗算記号度数_1,_乗算記号度数),!. 素因数分解(U,M,N,C,Y,X,_乗算記号度数_1,_乗算記号度数) :- \+(U=2), \+(0 is M mod U), U2 is U + 2, _乗算記号度数_2 is _乗算記号度数_1 + C - 1, 素因数分解(U2,N,N,0,[U^C|Y],X,_乗算記号度数_2,_乗算記号度数),!. 素因数分解(U,M,N,C,Y,X,_乗算記号度数_1,_乗算記号度数) :- 0 is M mod U, C2 is C + 1, M1 is M // U, 素因数分解(U,M1,N,C2,Y,X,_乗算記号度数_1,_乗算記号度数). 素因数分解項構成([A],A,_乗算記号度数,_乗算記号度数) :- !. 素因数分解項構成([A|R1],B * A,_乗算記号度数_1,_乗算記号度数) :- _乗算記号度数_2 is _乗算記号度数_1 + 1, 素因数分解項構成(R1,B,_乗算記号度数_2,_乗算記号度数). % 以下のサイトは # 指数表記を使わずに整数を素因数分解することを考えます。 # つまり、「72=2×2×2×3×3」のように表現します。 # このときに使う『×』の数は4つです。 # # ここで、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなるものを考えます。 # 上の72の例であれば、各桁の和は7+2で「9」ですが、『×』の数は「4」なので不適です。 # # この条件を満たすものとしては、「110=2×5×11」や「210=2×3×5×7」、 # 「512=2×2×2×2×2×2×2×2×2」などがあります。 # # では、4桁の整数で上記の条件を満たす数をすべて求めてください。 # # プログラミング言語は不問です。 # お好きな言語で計算してください。 # # 【解答方法】 # 解答用テキストファイルをダウンロードしてください。 # # 解答用テキストファイルを完成させ、アップロードしてください。 '指数表記を使わずに4桁の整数を素因数分解して、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなる整数を全て求める'(_各桁の和と乗算記号度数の一致する4桁の数ならび) :- '9999以下の素数ならび'(_9999以下の素数ならび), findall(_4桁の数,( '4桁の数の各桁の合計'(_4桁の数,_乗算記号度数), 指数表記を使わず素因数分解を乗算記号で表現した場合の乗算記号度数(_4桁の数,_9999以下の素数ならび,_乗算記号度数)),_各桁の和と乗算記号度数の一致する4桁の数ならび). '9999以下の素数ならび'(_9999以下の素数ならび) :- findall(N,between(2,9999,N),_2以上9999以下の数リスト), エラトステネスの篩(_2以上9999以下の数リスト,_9999以下の素数ならび). エラトステネスの篩([],[]) :- !. エラトステネスの篩([M|R1],[M|R2]) :- 'R1の残りの数ならびの中で、Mで割り切れるものは篩い落とす'(M,R1,L), エラトステネスの篩(L,R2). 'R1の残りの数ならびの中で、Mで割り切れるものは篩い落とす'(M,R1,L) :- findall(N,( 'R1の残りの数ならびの中で'(R1,N), 'Mで割り切れるものは篩い落とす'(N,M)),L). 'R1の残りの数ならびの中で'(R1,N) :- member(N,R1). 'Mで割り切れるものは篩い落とす'(N,M) :- \+(0 is N mod M). '4桁の数の各桁の合計'(_4桁の数,_各桁の合計) :- between(1000,9999,_4桁の数), 各桁の合計(_4桁の数,0,_各桁の合計). 各桁の合計(0,_各桁の合計,_各桁の合計) :- !. 各桁の合計(N,_各桁の合計_1,_各桁の合計) :- '下位1桁を切り取って加算する'(N,_各桁の合計_1,_下位一桁を切り取った数,_各桁の合計_2), 各桁の合計(_下位一桁を切り取った数,_各桁の合計_2,_各桁の合計). '下位1桁を切り取って加算する'(N,_各桁の合計_1,_下位一桁を切り取った数,_各桁の合計_2) :- M is N mod 10, _下位一桁を切り取った数 is N // 10, _各桁の合計_2 is _各桁の合計_1 + M. 指数表記を使わず素因数分解を乗算記号で表現した場合の乗算記号度数(N,_素数ならび,_乗算記号度数) :- 素数で何回割り切れるか(N,_素数ならび,[],_素因数の数の合計を表すならび), 素因数の数の合計を表すならびから乗算記号度数を得る(_素因数の数の合計を表すならび,_乗算記号度数). 素数で何回割り切れるか(N,[],_何回,_何回). 素数で何回割り切れるか(N,[_素数|R],_何回_1,_何回) :- 一つの素数で割ることができる数を加算する(N,_素数,_何回_1,_何回_2), 素数で何回割り切れるか(N,R,_何回_2,_何回). 一つの素数で割ることができる数を加算する(N,_素数,_何回,_何回) :- 素数で割り切れなくなったらその素数は終了する(N,_素数),!. 一つの素数で割ることができる数を加算する(N,_素数,L1,L) :- 素数で割れるだけ割っていく(N,_素数,L1,N_1,L). 素数で割り切れなくなったらその素数は終了する(N,_素数) :- \+(0 is N mod _素数). 素数で割れるだけ割っていく(N,_素数,L1,N_1,L) :- N_1 is N // _素数, 一つの素数で割ることができる数を加算する(N_1,_素数,[_|L1],L). 素因数の数の合計を表すならびから乗算記号度数を得る([_|L],_乗算記号度数) :- length(L,_乗算記号度数). % 以下のサイトは # 指数表記を使わずに整数を素因数分解することを考えます。 # つまり、「72=2×2×2×3×3」のように表現します。 # このときに使う『×』の数は4つです。 # # ここで、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなるものを考えます。 # 上の72の例であれば、各桁の和は7+2で「9」ですが、『×』の数は「4」なので不適です。 # # この条件を満たすものとしては、「110=2×5×11」や「210=2×3×5×7」、 # 「512=2×2×2×2×2×2×2×2×2」などがあります。 # # では、4桁の整数で上記の条件を満たす数をすべて求めてください。 # # プログラミング言語は不問です。 # お好きな言語で計算してください。 # # 【解答方法】 # 解答用テキストファイルをダウンロードしてください。 # # 解答用テキストファイルを完成させ、アップロードしてください。 '指数表記を使わずに4桁の整数を素因数分解して、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなる整数を全て求める' :- findall(_4桁の数,( '4桁の数の各桁の合計'(_4桁の数,_乗算記号度数), 指数表記を使わず素因数分解を乗算記号で表現した場合の乗算記号度数(_4桁の数,_指数表記を使った素因数分解,_乗算記号度数)),L), writef('%t\n',[L]). '4桁の数の各桁の合計'(_4桁の数,_各桁の合計) :- between(1000,9999,_4桁の数), 各桁の合計(_4桁の数,0,_各桁の合計). 各桁の合計(0,_各桁の合計,_各桁の合計) :- !. 各桁の合計(N,_各桁の合計_1,_各桁の合計) :- M is N mod 10, N_1 is N // 10, _各桁の合計_2 is _各桁の合計_1 + M, 各桁の合計(N_1,_各桁の合計_2,_各桁の合計). 指数表記を使わず素因数分解を乗算記号で表現した場合の乗算記号度数(N,_指数表記を使った素因数分解,_乗算記号度数) :- 素因数分解(2,N,N,0,[],L), 素因数分解項構成(L,_指数表記を使った素因数分解,0,_乗算記号度数). 素因数分解(U,M,N,C,X,X) :- U > N // 2,!. 素因数分解(U,M,N,0,Y,X) :- member(J^_,Y), 0 is U mod J, U2 is U + 2, 素因数分解(U2,N,N,0,Y,X),!. 素因数分解(2,M,N,0,Y,X) :- \+(0 is M mod 2), 素因数分解(3,N,N,0,Y,X),!. 素因数分解(2,M,N,C,Y,X) :- \+(0 is M mod 2), 素因数分解(3,N,N,0,[2^C|Y],X),!. 素因数分解(U,M,N,0,Y,X) :- \+(U=2), \+(0 is M mod U), U2 is U + 2, 素因数分解(U2,N,N,0,Y,X),!. 素因数分解(U,M,N,C,Y,X) :- \+(U=2), \+(0 is M mod U), U2 is U + 2, 素因数分解(U2,N,N,0,[U^C|Y],X),!. 素因数分解(U,M,N,C,Y,X) :- 0 is M mod U, C2 is C + 1, M1 is M // U, 素因数分解(U,M1,N,C2,Y,X). 素因数分解項構成([J^M],J^M,_乗算記号度数_1,_乗算記号度数) :- _乗算記号度数 is _乗算記号度数_1 + M -1,!. 素因数分解項構成([J^M|R1],B * J^M,_乗算記号度数_1,_乗算記号度数) :- _乗算記号度数_2 is _乗算記号度数_1 + M, 素因数分解項構成(R1,B,_乗算記号度数_2,_乗算記号度数). :- '指数表記を使わずに4桁の整数を素因数分解して、元の数の「各桁の和」が「素因数分解した『×』の数」と等しくなる整数を全て求める',halt. % 以下のサイトは # 最近、マシューはポエマーな女子高生に恋をしている。彼女は詩人なんだが、パーコさんと言うんだ。 # # パーコ :「あらゆる物体、すなわち大空、星、大地、その王国などは、精神の最も小さいものにもおよばない。なぜなら、精神はそれらのすべてと自身とを認識するが、物体は何も認識しないからである。」 # # マシュー:「それは新しい詩かい?」 # # パーコ :「違う。パスカルの『パンセ』に記載された有名な一節。知らない人がいるんだ。」 # # マシュー:「Oh...ごめんよ。」 # # パーコ :「人間は自然の中では矮小な生き物にすぎないが、考えることによって宇宙を超える、というパスカルの考え方には実に共感するものがある。」 # # マシュー:「そうだなあ。確かに、マシューの肉体は小さいが、妄想だけはいつもビッグサイズだ!・・・さて、パーコ、デートに行かないか?」 # # パーコ :「うん、そうね。じゃあ、パスカルにちなんで、パスカルの三角形をプログラムで表示して欲しい。もちろん、数学の美しさを生かした記述の仕方をしてね。」 # # 以下の三角形が10行分のパスカルの三角形だ。こちらを再現して欲しい。 # # 1 # 1 1 # 1 2 1 # 1 3 3 1 # 1 4 6 4 1 # 1 5 10 10 5 1 # 1 6 15 20 15 6 1 # 1 7 21 35 35 21 7 1 # 1 8 28 56 70 56 28 8 1 # 1 9 36 84 126 126 84 36 9 1 # # 動作確認はideoneで行う。 # ideoneで正しく動作しない場合は不正解となりますので注意してくれよ。 # 言語は40種類以上サポートしているぞ。 # # ・使用した言語 # ・ソースコード # ・答え # の3つを合わせて記述して欲しい。 % 使用言語 SWI-Prolog % 以下、ソースコード :- op(400,xfx,だけ). :- op(300,xf,分). :- op(400,xfx,が真になる全ての場合). :- op(500,xfx,を). :- op(600,xf,に収集する). :- op(400,xfx,を結合して). :- op(600,xf,を得る). 行のずれを意味する空白文字列(' '). 項表示形式('%6c'). パスカルの三角形 :- パスカルの三角形([_,_,_,_,_,_,_,_,_,_],[1]),!. パスカルの三角形([_],_上の行) :- '第一引数(行数)が空になったら、最終行を表示して終了する'([],_上の行). パスカルの三角形([_|_行数],_上の行) :- パスカルの三角形の行を順に表示する([_|_行数],_上の行). '第一引数(行数)が空になったら、最終行を表示して終了する'([],_上の行) :- パスカルの三角形の上の行を表示([],_上の行). パスカルの三角形の行を順に表示する([_|_行数],_上の行) :- 'パスカルの三角形の上の行を表示した上、現在行を計算して生成する'(_行数,_上の行,_現在行), パスカルの三角形(_行数,_現在行). 'パスカルの三角形の上の行を表示した上、現在行を計算して生成する'(_行数,_上の行,_現在行) :- 上の行の二項の和(_上の行,_上の行の二項の和) が真になる全ての場合 _上の行の二項の和 を _両端の1が落ちた計算された行 に収集する, パスカルの三角形の上の行を表示(_行数,_上の行), 両端に1を付加して現在行を完成する(_両端の1が落ちた計算された行,_現在行). 上の行の二項の和(_上の行,_上の行の二項の和) :- append(_,[_左上の項,_右上の項|_],_上の行), _上の行の二項の和 is _左上の項 + _右上の項. パスカルの三角形の上の行を表示(_行数,_上の行) :- '_行数から行頭からの空白文字列の生成'(_行数,_行頭からの空白文字列), 上の行の数字表示文字列(_上の行,_上の行の数字表示文字列), 表示する('%t%t\n',[_行頭からの空白文字列,_上の行の数字表示文字列]). '_行数から行頭からの空白文字列の生成'(_行数,_行頭からの空白文字列) :- 行のずれを意味する空白文字列(_行のずれを意味する空白文字列), _行数 分 だけ _行のずれを意味する空白文字列 を _空白文字列ならび に収集する, _空白文字列ならび を結合して _行頭からの空白文字列 を得る. 上の行の数字表示文字列(_上の行,_上の行の数字表示文字列) :- 上の行の数字表示部分(_上の行,_上の行の数字表示部分), _上の行の数字表示部分 を結合して _上の行の数字表示文字列 を得る. 上の行の数字表示部分(_上の行,_上の行の数字表示部分) :- 項表示形式(_項表示形式), 上の行の項を数字文字列に変換(_上の行,_項表示形式,_上の行の数字文字列) が真になる全ての場合 _上の行の数字文字列 を _上の行の数字表示部分 に収集する. 上の行の項を数字文字列に変換(_上の行,_項表示形式,_上の行の数字文字列) :- member(_項,_上の行), swritef(_上の行の数字文字列,_項表示形式,[_項]). 両端に1を付加して現在行を完成する(_両端の1が落ちた計算された行,_現在行) :- append([1|_両端の1が落ちた計算された行],[1],_現在行). _行数 分 だけ _収集項 を _収集項ならび に収集する :- findall(_収集項,member(_,_行数),_収集項ならび). _目標 が真になる全ての場合 _収集項 を _収集項ならび に収集する :- findall(_収集項,_目標,_収集項ならび). L を結合して A を得る :- atomic_list_concat(L,A). 表示する(_表示形式項,_値ならび) :- writef(_表示形式項,_値ならび). :- nl,パスカルの三角形,nl,halt. % 以下、実行結果 # swipl -f temp1.pro 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1 % 以下のサイトは # # 20×20のボックスの中からある文字列を取り出すプログラムを書いて! # # かたやん印刷所では、いまの時代においてもグーテンベルグ印刷にこだわって印刷をしています。 # グーテンベルグ印刷とは、活版(活字を組み合わせて作った版)で印刷する方法です。(Wikipedia) # # かたやん印刷所の所長かたやんは、使った活字を元の場所に戻さないので、 # いつも活字を入れているボックスはぐちゃぐちゃで、 # ほしい活字をすぐに見つけ出すことができません。 # # そこで見かねた印刷所の副所長エミーは、活字を入れているボックスビデオで撮影し、 # 画像解析し、ボックスのどこにどの活字があるかを解析し、 # ほしい文字列の活字がどこにあるか瞬時にみつけだすプログラミングを作ることにしました。 # # 現状の状態のボックスは以下のようになっています。 # # # 6×6のボックスの中から"PRO, PROGRAMMER"という活字を探し出したいです。 # カンマやスペースは1つの活字としてカウントします。 # ですので、今回は文字13個、カンマ1個、スペース1個の合計15個の活字が必要です。 # 一度使った活字は2回使うことはできません。 # # 活字の場所は、(縦番号,横番号)で表すと以下のような順番で活字を取り出すことができます。 # 縦番号は上から下の方向に、横番号は左から右の方向に、1から数えます。 # 1,4 = P # 2,1 = R # 1,6 = O # 5,2 = , # 5,4 = space # 2,2 = P # 3,4 = R # 4,5 = O # 5,1 = G # 4,3 = R # 1,1 = A # 2,5 = M # 6,1 = M # 2,4 = E # 6,6 = R # # # 上記の例では、例えば"P"という文字が2回でてきますが、(1,4)と(2,2)にある"P"はどちらを先につかってもかまいません。 # また場所の特定は1つのみ記述すればよいです。すべての場所番号を書く必要はありません。 # # 画像解析したボックスのデータはCSVで出力されます。 # ボックスのデータを使ってほしい文字列を作るための活字の在り処を探しだしてください。 # # ■資料 # gutenberg.zip # zipファイルを解凍すると以下のファイルが入っています。 # # gutenberg.csv # このボックスから"STAY HUNGRY, STAY FOOLISH"という活字を取り出してください。 # 文字21個、カンマ1個、スペース3個で、合計25個の活字が必要です。 # # answer.txt # 解答用テキストファイルです。 # # ■解答方法 # 解答用テキストファイル(answer.txt)を完成させ、アップロードしてください。 # ※解答用テキストファイル(answer.txt)以外のファイル形式(zipなど)をアップロードした場合は評価対象外となります。 # '20×20のボックスの生成' :- open('gutenberg.csv',read,Instream), '20×20のボックスの生成'(Instream,_20掛ける20のボックス), close(Instream), assertz('20×20のボックス'(_20掛ける20のボックス)). '20×20のボックスの生成'(Instream,[]) :- at_end_of_stream(Instream),!. '20×20のボックスの生成'(Instream,[L|R]) :- get_line(Instream,Line), split(Line,['\t'],L), '20×20のボックスの生成'(Instream,R). '20×20のボックスの中からある文字列を取り出す'(_ある文字列,_20掛ける20のボックス) :- atom_chars(_ある文字列,_文字ならび), '20×20のボックスの中からある文字列を取り出す'(_文字ならび,_20掛ける20のボックス,L), 解の表示(L). '20×20のボックスの中からある文字列を取り出す'([],_20掛ける20のボックス,[]) :- !. '20×20のボックスの中からある文字列を取り出す'([_文字|_残り文字ならび],_20掛ける20のボックス_1,[[_文字,_行目,_列目]|R]) :- ある文字を取り出す(_文字,_20掛ける20のボックス_1,1,_列目,_20掛ける20のボックス_2), '20×20のボックスの中からある文字列を取り出す'(_残り文字ならび,_20掛ける20のボックス_2,R). ある文字を取り出す(_文字,[_行|R_1],_行目,_列目,[_行_2|R_1]) :- nth1(_列目,_行,_文字), 行を更新する(_行,_列目,_行_2),!. ある文字を取り出す(_文字,[_行|R_1],_行目,_列目,[_行|R_2]) :- _行目_2 is _行目 + 1, ある文字を取り出す(_文字,R_1,_行目_2,_列目,R_2). 行を更新する(_行,_列目,_行_2) :- length([_|L1],_列目), append(L1,[_|R],_行), append(L1,[''|R],_行_2),!. 解の表示(L) :- tell('ans.txt'), forall(member([_文字,_行目,_列目],L),writef('%t,%t,%t\n',[_文字,_行目,_列目])), told. 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). split('',_,[],[]) :- !. split(_文字列,_区切り文字列ならび,[_区切り文字列|R3],[_副文字列|R4]) :- 副文字列を切り出す(_文字列,_区切り文字列ならび,_区切り文字列,_副文字列,_残り文字列), split(_残り文字列,_区切り文字列ならび,R3,R4). 副文字列を切り出す(_文字列,_区切り文字列ならび,_区切り文字列,_副文字列,_残り文字列) :- 文字ならびとして切り出す(_文字列,_区切り文字列ならび,_区切り文字列,_切り出し文字ならび,_残り文字列), atomic_list_concat(_切り出し文字ならび,_副文字列),!. 文字ならびとして切り出す('',_,'',[],'') :- !. 文字ならびとして切り出す(_文字列,_区切り文字列ならび,_区切り文字列,[],_残り文字列) :- 文字列の先頭は区切り文字列である(_文字列,_区切り文字列ならび,_区切り文字列,_残り文字列),!. 文字ならびとして切り出す(_文字列,_区切り文字列ならび,_区切り文字列,[_文字|R4],_残り文字列) :- 一文字切り出す(_文字列,_文字,_残り文字列_2), 文字ならびとして切り出す(_残り文字列_2,_区切り文字列ならび,_区切り文字列,R4,_残り文字列). 文字列の先頭は区切り文字列である(_文字列,_区切り文字列ならび,_区切り文字列,_残り文字列) :- member(_区切り文字列,_区切り文字列ならび), atom_length(_区切り文字列,_長さ), sub_atom(_文字列,0,_長さ,_残り文字数,_区切り文字列), sub_atom(_文字列,_,_残り文字数,0,_残り文字列),!. 一文字切り出す(_文字列,_文字,_残り文字列_2) :- sub_atom(_文字列,0,1,_,_文字), sub_atom(_文字列,1,_,0,_残り文字列_2). :- '20×20のボックスの生成'(_CSVファイル). :- '20×20のボックス'(_20掛ける20のボックス), '20×20のボックスの中からある文字列を取り出す'(_ある文字列,_20掛ける20のボックス). % 以下のサイトは # # 20×20のボックスの中からある文字列を取り出すプログラムを書いて! # '20×20のボックスの中からある文字列を取り出す'(_20掛ける20のボックス,_行目,_列目,_ある文字列) :- '20×20のボックスの中から'(_20掛ける20のボックス), ある文字列を取り出す(_20掛ける20のボックス,_行目,_列目,_ある文字列). '20×20のボックスの中から'(_20掛ける20のボックス) :- length(_20掛ける20のボックス,20), forall( member(_20のボックス,_20掛ける20のボックス), '20のボックス'(_20のボックス)). '20のボックス'(_20のボックス) :- length(_20のボックス,20), forall( member(_ボックス,_20のボックス), ボックス(_ボックス)). ボックス([_|_]) :- !. ボックス([]). ある文字列を取り出す(_20掛ける20のボックス,_行目,_列目,_ある文字列) :- nth1(_行目,_20のボックス,_20掛ける20のボックス), nth1(_列目,_20のホックス,_ボックス), member(_ある文字列,_ボックス). % 以下のサイトは # # 20×20のボックスの中からある文字列を取り出すプログラムを書いて! # '20×20のボックスの中からある文字列を取り出す'(_20掛ける20のボックス,_行目,_列目,_ある文字列) :- _ボックス = [_|_], '20×20のボックス'(_20掛ける20のボックス), nth1(_行目,_20のボックス,_20掛ける20のボックス), nth1(_列目,_20のホックス,_ボックス), member(_ある文字列,_ボックス). '20×20のボックス'(_20掛ける20のボックス) :- length(_20掛ける20のボックス,20), forall(member(_20のボックス,_20掛ける20のボックス),length(_20のボックス,20)). % 以下のサイトは # # 20×20のボックスの中からある文字列を取り出すプログラムを書いて! # '20×20のボックスの中からある文字列を取り出す'(_20掛ける20のボックス,_行目,_列目,_ある文字列) :- '20×20のボックス'(_20掛ける20のボックス), nth1(_行目,_20のボックス,_20掛ける20のボックス), nth1(_列目,_20のホックス,_ボックス), member(_ある文字列,_ボックス). '20×20のボックス'(_20掛ける20のボックス) :- length(_20掛ける20のボックス,20), forall(member(_20のボックス,_20掛ける20のボックス),length(_20のボックス,20)). % 以下のサイトは # # 20×20のボックスの中からある文字列を取り出すプログラムを書いて! # '20×20のボックスの中からある文字列を取り出す'(_20掛ける20のボックス,_行目,_列目,_ある文字列) :- '20×20のボックス'(_20掛ける20のボックス), nth1(_行目,_20のボックス,_20掛ける20のボックス), nth1(_列目,_20のホックス,[_ある文字列]). '20×20のボックス'(_20掛ける20のボックス) :- length(_20掛ける20のボックス,20), forall(member(_20のボックス,_20掛ける20のボックス),length(_20のボックス,20)).