このディレクトリの索引

% 以下のサイトは # p=1231, q=4567を選びます。 # eに65537 # e^-1=d mod φ(n) のdを計算して求めます。 #     d=3988493 # となります。 # # 暗号化と複合化の手順 # 公開鍵:N = 1231 * 4567 # E = 65537 # d = 3988493 # 文字コード:「a〜z」=01〜26、「A〜Z」=27〜52、空白=53 # 文書:This Anser p(1231). % 素数1 q(4567). % 素数2 法とする数(5621977). % 法とする数 公開鍵(65537). % 公開鍵 秘密鍵(3988493). % 秘密鍵 'RSA暗号化'(_文書,_暗号文字コードならび) :- 文書を文字コードで数値化します(_文書,_文字コードならび), 'RSA方式によるコード暗号化'(_文字コードならび,_暗号文字コードならび). 'RSA復号化'(_暗号文字コードならび,_文書) :- 'RSA方式によるコード復号化'(_暗号文字コードならび,_文字コードならび), 文字コードならびから文書を復元します(_文字コードならび,_文書). 'RSA方式によるコード暗号化'(_文字コードならび,_暗号コードならび) :- 公開鍵(_公開鍵), 法とする数(_法とする数), findall(_暗号コード,( '_文字コードを_暗号コードに変換'(_文字コードならび,_公開鍵,_法とする数,_暗号コード)),_暗号コードならび). '_文字コードを_暗号コードに変換'(_文字コードならび,_公開鍵,_法とする数,_暗号コード) :- member(_文字コード,_文字コードならび), _暗号コード is _文字コード ^ _公開鍵 mod _法とする数. 'RSA方式によるコード復号化'(_暗号文字コードならび,_文字コードならび) :- 秘密鍵(_秘密鍵), 法とする数(_法とする数), findall(_文字コード,( '_暗号文字コードを_文字コードに復号する'(_暗号文字コードならび,_秘密鍵,_法とする数,_文字コード)),_文字コードならび). '_暗号文字コードを_文字コードに復号する'(_暗号文字コードならび,_秘密鍵,_法とする数,_文字コード) :- member(_暗号文字コード,_暗号文字コードならび), _文字コード is _暗号文字コード ^ _秘密鍵 mod _法とする数. 文書を文字コードで数値化します(_文書,_文字コードならび) :- findall(_文字コード,( sub_atom(_文書,_,1,_,_文字), 文字コード(_文字,_文字コード)), _文字コードならび). 暗号コードを暗号文に変換(_暗号コードならび,_暗号文) :- findall(_暗号文字,( member(_暗号コード,_暗号コードならび), 文字コード(_暗号文字,_暗号コード)),_暗号文字ならび), atom_chars(_暗号文,_暗号文字ならび). 文字コードならびから文書を復元します(_文字コードならび,_文書) :- findall(_文字,( member(_文字コード,_文字コードならび), 文字コード(_文字,_文字コード)),_文字ならび), atom_chars(_文書,_文字ならび). 文字コード(_文字,_コード) :- char_code(_文字,_コード). '秘密鍵の候補'(_素数p,_素数q,_公開鍵,_秘密鍵) :- '_素数p_1と_素数q_1の最小公倍数'(_素数p,_素数q,_素数p_1と_素数q_1の最小公倍数), '((_素数p_1と_素数q_1の最小公倍数 * N + 1) / _公開鍵) が整数となる秘密鍵候補を得る'(_素数p_1と_素数q_1の最小公倍数,_公開鍵,_秘密鍵). '((_素数p_1と_素数q_1の最小公倍数 * N + 1) / _公開鍵) が整数となる秘密鍵候補を得る'(_素数p_1と_素数q_1の最小公倍数,_公開鍵,_秘密鍵) :- between(1,9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,N), 0 is (_素数p_1と_素数q_1の最小公倍数 * N + 1) mod _公開鍵, _秘密鍵 is (_素数p_1と_素数q_1の最小公倍数 * N + 1) // _公開鍵. '_素数p_1と_素数q_1の最小公倍数'(_素数p,_素数q,_素数p_1と_素数q_1の最小公倍数) :- succ(_素数p_1,_素数p), succ(_素数q_1,_素数q), 最小公倍数(_素数p_1,_素数q_1,_素数p_1と_素数q_1の最小公倍数). 最小公倍数(_m,_n,_最小公倍数) :- Y is _m * _n, ユークリッドの互除法により最大公約数を得る(_m,_n,_最大公約数), _最小公倍数 is ( _m * _n ) // _最大公約数. 'ユークリッドの互除法により最大公約数を得る'(_m,_m,_m). 'ユークリッドの互除法により最大公約数を得る'(_m,_n,_最大公約数) :- _m > _n, _剰余 is _m mod _n, ユークリッドの互除法により最大公約数を得る(_m,_n,_剰余,_最大公約数). 'ユークリッドの互除法により最大公約数を得る'(_m,_n,_最大公約数) :- _m < _n, ユークリッドの互除法により最大公約数を得る(_n,_m,_最大公約数). ユークリッドの互除法により最大公約数を得る(_,_最大公約数,0,_最大公約数) :- !. ユークリッドの互除法により最大公約数を得る(_m,_n,_剰余,_最大公約数) :- 'ユークリッドの互除法により最大公約数を得る'(_n,_剰余,_最大公約数). % 以下のサイトは # 出典 :: C/C++の宿題片付けます 153代目 #344 # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # 1)帰納を使い、フィボナッチ数を表示するプログラミングを作れ。 # 例 0,1,1,2,3,5,8,13... # # 2)帰納を使い、インプットした数字nが偶数の場合は、 # 1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。 # ただし、nが奇数の場合は、-1と表示させる。 # # 3)帰納を使い、最大公約数を求めよ。 '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。ただし、nが偶数の場合は、-1と表示させる。'(_n) :- 'ただし、nが偶数の場合は、-1と表示させる。'(_n). '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。ただし、nが偶数の場合は、-1と表示させる。'(_n) :- 'インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(_n). 'ただし、nが偶数の場合は、-1と表示させる。'(_n) :- 偶数(_n). '-1と表示させる'. 偶数(_偶数) :- 0 is _偶数 mod 2. '-1と表示させる' :- writef('%w\n',[-1]). 'インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(_n) :- 奇数(_n), '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(1,_n,1). 奇数(_奇数) :- 1 is _奇数 mod 2. '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(_n,_n,_答え) :- 'その答えを表示する'(_答え),!. '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(N,_n,S1) :- 'インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を先頭から順に計算して行く'(N,_n,S1). 'その答えを表示する'(_答え) :- writef('%w\n',[_答え]). '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を先頭から順に計算して行く'(N,_n,S1) :- 'N_1に2を加えてN_2とした上で、N_2とM_1を掛けてM_2とする'(N_1,M_1,N_2,M_2), '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(N_2,_n,S2). 'N_1に2を加えてN_2とした上で、N_2とM_1を掛けてM_2とする'(N_1,M_1,N_2,M_2) :- N_2 is N_1 + 2, M_2 is M_1 * N_2. % 以下のサイトは # 出典 :: C/C++の宿題片付けます 153代目 #344 # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # 1)帰納を使い、フィボナッチ数を表示するプログラミングを作れ。 # 例 0,1,1,2,3,5,8,13... # # 2)帰納を使い、インプットした数字nが偶数の場合は、 # 1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。 # ただし、nが奇数の場合は、-1と表示させる。 # # 3)帰納を使い、最大公約数を求めよ。 '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。ただし、nが偶数の場合は、-1と表示させる。'(_n) :- 'ただし、nが偶数の場合は、-1と表示させる。'(_n). '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。ただし、nが偶数の場合は、-1と表示させる。'(_n) :- 'インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(_n). 'ただし、nが偶数の場合は、-1と表示させる。'(_n) :- 偶数(_n). '-1と表示させる'. 'インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(_n) :- 奇数(_n), '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(1,_n,1). '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(_n,_n,_答え) :- 'その答えを表示する'(_答え),!. '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(N,_n,S1) :- 'インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行って計算して行く'(N,_n,S1). '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を計算して行く'(N,_n,S1) :- 'N_1に2を加えてN_2とした上で、N_2とM_1を掛けてM_2とする'(N_1,M_1,N_2,M_2), '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(N_2,_n,S2). 'N_1に2を加えてN_2とした上で、N_2とM_1を掛けてM_2とする'(N_1,M_1,N_2,M_2) :- N_2 is N_1 + 2, M_2 is M_1 * N_2. 偶数(_偶数) :- 0 is _偶数 mod 2. 奇数(_奇数) :- 1 is _奇数 mod 2. '-1と表示させる' :- writef('%w\n',[-1]). 'その答えを表示する'(_答え) :- writef('%w\n',[_答え]). % 以下のサイトは # 出典 :: 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). 入力される分数(_分子 / _分母) :- 行入力(_行), 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). 最小公倍数(_整数_1,_整数_2,_最小公倍数) :- 二つの整数の最小公倍数(_整数_1,_整数_2,_最小公倍数). 最小公倍数(_整数ならび,_最小公倍数) :- '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'(_整数ならび,_最小公倍数). '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'([_整数],_整数). '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'([_整数|R],_最小公倍数) :- '最小公倍数とは、0ではない複数の整数の公倍数のうち最小のものをさす'(R,_最小公倍数_1), 二つの整数の最小公倍数(_整数,_最小公倍数_1,_最小公倍数). 二つの整数の最小公倍数(A,B,X) :- 二つの整数の最大公約数(A,B,_最大公約数), X is A * B // _最大公約数. % 以下のサイトは # 出典: プログラミングのお題スレ Part4 #353 # # 素数pと素数qから(p-1)と(q-1)の最小公倍数を求める。 # 最大p*qまでの数で、n*最小公倍数+1の集合を求める。 # この集合の中から、eで割り切れる数を探す。 # 例:p=5,q=7:(5-1)と(7-1)つまり4と6の最小公倍数は12。 # 例:p*q=35なので12+1,24+1,36+1(>35)つまり13と25。 # 例:25/5=5=dとなる。eは割り切れる数があらかじめ入力される。 '素数pと素数qから(p-1)と(q-1)の最小公倍数を求める。 最大p*qまでの数で、n*最小公倍数+1の集合を求める。 この集合の中から、eで割り切れる数を探す。'(_p,_q,_e,X) :- _n is _p * _q, '素数pと素数qから(p-1)と(q-1)の最小公倍数を求める。'(_p,_q,_最小公倍数), '最大p*qまでの数で、n*最小公倍数+1の集合を求める。'(_n,_最小公倍数,_集合), 'この集合の中から、eで割り切れる数を探す。'(_集合,_e,X). '素数pと素数qから(p-1)と(q-1)の最小公倍数を求める。'(_p,_q,_最小公倍数) :- _p_1 is _p - 1, _q_1 is _q - 1, 最小公倍数(_p_1,_q_1,_最小公倍数). '最大p*qまでの数で、n*最小公倍数+1の集合を求める。'(_n,_最小公倍数,_集合) :- findall(_s,( between(1,_n,_), _s is _n * _最小公倍数 + 1), _集合). 'この集合の中から、eで割り切れる数を探す。'(_集合,_e,X) :- member(X,_集合), 0 is X mod _e. 最小公倍数(A,B,X) :- 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典: プログラミングのお題スレpart3 # お題:原点と格子点(a,b)を結ぶ線分上にある格子点をすべて求める。 # 例 # a=54, b=66 のとき # 0 0 # 9 11 # 18 22 # 27 33 # 36 44 # 45 55 # 54 66 '原点と格子点(a,b)を結ぶ線分上にある格子点をすべて求める。'(_a,_b,_格子点ならび) :- '原点から格子点へのX方向,Y方向の刻みを求める'(_a,_b,_X方向への刻み,_Y方向への刻み), '原点と格子点(a,b)を結ぶ線分上にある格子点をすべて求める。'(0,0,_a,_b,_X方向への刻み,_Y方向への刻み,_格子点ならび). '原点と格子点(a,b)を結ぶ線分上にある格子点をすべて求める。'(X,Y,X,Y,_,_,[(X,Y)]) :- !. '原点と格子点(a,b)を結ぶ線分上にある格子点をすべて求める。'(X_1,Y_1,_a,_b,_X方向への刻み,_Y方向への刻み,_格子点ならび) :- 刻みごとに格子点をすべて求める(X_1,Y_1,_a,_b,_X方向への刻み,_Y方向への刻み,_格子点ならび). 刻みごとに格子点をすべて求める(X_1,Y_1,_a,_b,_X方向への刻み,_Y方向への刻み,[(X_1,Y_1)|R]) :- X_2 is X_1 + _X方向への刻み, Y_2 is Y_1 + _Y方向への刻み, '原点と格子点(a,b)を結ぶ線分上にある格子点をすべて求める。'(X_2,Y_2,_a,_b,_X方向への刻み,_Y方向への刻み,R). '原点から格子点へのX方向,Y方向の刻みを求める'(_格子点のX座標,_格子点のY座標,_X方向への刻み,_Y方向への刻み) :- 格子点の絶対値の最大公約数(_格子点のX座標,_格子点のY座標,_格子点の_X_Y座標の絶対値の最大公約数), 'X方向とY方向の刻みを得る'(_格子点のX座標,_格子点のY座標,_格子点の_X_Y座標の絶対値の最大公約数,_X方向への刻み,_Y方向への刻み). 格子点の絶対値の最大公約数(_格子点のX座標,_格子点のY座標,_格子点の_X_Y座標の絶対値の最大公約数) :- 格子点の絶対値の(_格子点のX座標,_格子点のY座標,_格子点のX座標の絶対値,_格子点のY座標の絶対値), 最大公約数(_格子点のX座標の絶対値,_格子点のY座標の絶対値,_格子点の_X_Y座標の絶対値の最大公約数). 格子点の絶対値の(_格子点のX座標,_格子点のY座標,_格子点のX座標の絶対値,_格子点のY座標の絶対値) :- _格子点のX座標の絶対値 is abs(_格子点のX座標), _格子点のY座標の絶対値 is abs(_格子点のY座標). 'X方向とY方向の刻みを得る'(_格子点のX座標,_格子点のY座標,_格子点の_X_Y座標の絶対値の最大公約数,_X方向への刻み,_Y方向への刻み) :- _X方向への刻み is _格子点のX座標 // _格子点の_X_Y座標の絶対値の最大公約数, _Y方向への刻み is _格子点のY座標 // _格子点の_X_Y座標の絶対値の最大公約数. 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # お題:ふたつの自然数の公約数をすべて求める。 'ふたつの自然数の公約数をすべて求める。'(_ひとつめの自然数,_ふたつ目の自然数) :- 最大公約数をユークリッドの互除法で求める(_ひとつめの自然数,_ふたつ目の自然数,_最大公約数), forall((between(1,_最大公約数,_公約数),0 is _最大公約数 mod _公約数),writef('%t ',[_公約数])). 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X) . % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1361082416/887 # # [1] 授業単元:暇つぶし # [2] 問題文(含コード&リンク): # 2次元平面上における2線分の交点座標を求めよ # # 8つの整数 x1, y1, x2, y2, x3, y3, x4, y4 が与えられる # 線分ABを 点A(x1,y1) と 点B(x2,y2) とを繋ぐ線分とする # 線分CDを 点C(x3,y3) と 点D(x4,y4) とを繋ぐ線分とする # # 線分AB と 線分CD との交点座標を小数点表記で出力せよ(誤差は1e-20未満とする) # 交点が無い場合には「交点無し」と出力せよ # # 線分の端点での交差も認めることとし # 与えられる整数は -10000以上10000以下とする # # '2次元平面上における2線分の交点座標を求めよ 8つの整数 x1, y1, x2, y2, x3, y3, x4, y4 が与えられる 線分ABを 点A(x1,y1) と 点B(x2,y2) とを繋ぐ線分とする 線分CDを 点C(x3,y3) と 点D(x4,y4) とを繋ぐ線分とする 線分AB と 線分CD との交点座標を小数点表記で出力せよ(誤差は1e-20未満とする) 交点が無い場合には「交点無し」と出力せよ 線分の端点での交差も認めることとし 与えられる整数は -10000以上10000以下とする'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y) :- '2次元平面上における2線分の交点座標を求めよ'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y). '2次元平面上における2線分の交点座標を求めよ'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y) :- 'x1,y1,x2,y2を通る線分の方程式の係数'(_x1,_y1,_x2,_y2,A1,B1), 'x3,y3,x4,y4を通る線分の方程式の係数'(_x3,_y3,_x4,_y4,A2,B2), 二元一次連立方程式を解く(A1,B1,A2,B2,_x,_y), 'x,yは二つの線分上にある'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y). 'x1,y1,x2,y2を通る線分の方程式の係数'(_x1,_y1,_x2,_y2,A,B) :- 係数Aの算出(_x,_y1,_x2,_y2,_m_2,A), 係数Bの算出(_n_1,_y1,_m_2,B). 係数Aの算出(_x,_y1,_x2,_y2,_m_2,A) :- _m_1 is _y2 - _y1, _n_1 is _x2 - _x1, A_1 = (_m_1 / _n_1), _m_2 is _y1 * _x1 - _y2 * _x1, 約分(A_1,A). 係数Bの算出(_n_1,_y1,_m_2,B) :- _n_2 is _n_1 * _y1 + _m_2, B_1 = (_n_2 / _n_1), 約分(B_1,B). 'x3,y3,x4,y4を通る線分の方程式の係数'(_x3,_y3,_x4,_y4,A,B) :- 'x1,y1,x2,y2を通る線分の方程式の係数'(_x3,_y3,_x4,_y4,A,B). 二元一次連立方程式を解く(A1,B1,A2,B2,_x,_y) :- 既約ガウス行列に変形([[A1,-1,-B1],[A2,-1,-B2]],[[_,_,_x],[_,_,_y]]),!. 'x,yは二つの線分上にある'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y) :- 'x,yは直線上にある'(_x1,_y1,_x2,_y2,_x,_y), 'x,yは直線上にある'(_x3,_y3,_x4,_y4,_x,_y). 'x,yは直線上にある'(_x1,_y1,_x2,_y2,_x,_y) :- 'xは範囲にある'(_x1,_x2,_x), 'xは範囲にある'(_x3,_x4,_x), 'yは範囲にある'(_y1,_y2,_y), 'yは範囲にある'(_y3,_y4,_y),!. 'xは範囲にある'(_x1,_x2,_x) :- x2がx1と等しいか大きい場合(_x1,_x2,_x). 'xは範囲にある'(_x1,_x2,_x) :- x2がx1より小さい場合(_x1,_x2,_x). 'yは範囲にある'(_y1,_y2,_y) :- y2がy1と等しいか大きい場合(_y1,_y2,_y). 'yは範囲にある'(_y1,_y2,_y) :- y2がy1より小さい場合(_y1,_y2,_y). x2がx1と等しいか大きい場合(_x1,_x2,_x) :- _x1 =< _x2, _x >= _x2, _x =< _x1. x2がx1より小さい場合(_x1,_x2,_x) :- _x1 > _x2, _x >= _x1, _x =< _x2. y2がy1と等しいか大きい場合(_y1,_y2,_y) :- _y1 =< _y2, _y >= _y2, _y =< _y1. y2がy1より小さい場合(_y1,_y2,_y) :- _y1 > _y2, _y >= _y1, _y =< _y2. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1361082416/169 # # http://toro.2ch.net/test/read.cgi/tech/1357748713/775 # それで過去問さんにお願いがあるのですか、選りすぐった問題を一日一題のペースで載せていただけないでしょうか。 # # 1: http://toro.2ch.net/test/read.cgi/tech/1357748713/777 # 2: .http://toro.2ch.net/test/read.cgi/tech/1357748713/874 # 3.: ../test/read.cgi/tech/1361082416/59 # 4: .http://pc11.2ch.net/test/read.cgi/tech/1208268461/726 # [1] 授業単元:情報実験第一 # [2] 問題文:リストの全要素の最大公約数を求める述語 gcdlist を実装 # せよ。また、要素数が n であるリストに自然数 n 個を読み込み、関数 # gcdlist を用いてそれらの最大公約数を求めるプログラムを作成せよ。 # 'リストの全要素の最大公約数を求める述語 gcdlist を実装せよ。 また、要素数が n であるリストに自然数 n 個を読み込み、述語 gcdlist を用いて それらの最大公約数を求めるプログラムを作成せよ。'(_n,_最大公約数) :- '要素数が n であるリストに自然数 n 個を読み込み、gcdlist を用いて それらの最大公約数を求める'(_n,_最大公約数). gcdlist([N],N). gcdlist([N|R],_最大公約数) :- gcdlist(R,_最大公約数_2), 最大公約数をユークリッドの互除法で求める(N,_最大公約数_2,_最大公約数). 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). '要素数が n であるリストに自然数 n 個を読み込み、gcdlist を用いて それらの最大公約数を求める'(_n,_最大公約数) :- '要素数が n であるリストに自然数 n 個を読み込み'(_n,_リスト), gcdlist(_リスト,_最大公約数). '要素数が n であるリストに自然数 n 個を読み込み'(_n,_リスト) :- '要素数が n であるリスト'(_n,_リスト), findall(_自然数,( member(_,_リスト), 自然数を得る(自然数,_自然数)), _リスト). '要素数が n であるリスト'(_n,_リスト) :- length(_リスト,_n). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1357748713/48 # # [1] 授業単元:関数ポインタ # [2] 問題文(含コード&amp;リンク):http://codepad.org/O3eDo7F3 # # 以下のプログラムは2つの整数を入力させ,各種処理を選び, # 計算した結果をファイルへ出力するものであるが,作成途中である. # 下記に従い,プログラムを完成させよ. # ・各処理を行う場合は関数ポインタ引数とするをprocess()用いる. # ・加算:tasu(),除算(商):waru(),除算(剰余):amari(), #  最大公約数:yakusu(),最小公倍数:baisu()を用いる. # ・除算は商と剰余を求める. # ・最大公約数は2つの整数で共通の約数のうち最大のもの, #  最小公倍数は2つの整数で共通の倍数のうち最小のものである. # ・結果は「14 ÷ 5 = 2 余り 4」や「6 と 4 の最小公倍数は 12」のように #  計算式等も含めkekka.txtへ出力する. # # #include< stdio.h > # #include< stdlib.h > # # int process(ここを書く); # int tasu(ここを書く); # int waru(ここを書く); # int amari(ここを書く); # int yakusu(ここを書く); # int baisu(ここを書く); # # int main() # { # FILE *fp; //結果を出力するファイルのファイルポインタ # # int a, b; // 入力する2つ整数 # int op; // 選択された処理を示す変数 # int result1, result2; // 演算結果を格納する変数 # # fp = fopen("kekka.txt","w"); // ファイルを開く # if(fp == NULL) # { # printf("ファイルオープンエラー \n"); # exit(1); # } # # printf("1つめの整数を入力してください:"); # scanf("%d", &a); # printf("2つめの整数を入力してください:"); # scanf("%d", &b); # printf("1:加算,2:除算,3:最大公約数,4:最小公倍数\n"); # do { # printf("演算の番号を入力してください:"); # scanf("%d", &op); # } while(op<1 || op>4); # # ここを書く # # fclose(fp); // ファイルを閉じる # return 0; # } # # int process(ここを書く) # { # ここを書く # } # # int tasu(ここを書く) # { # ここを書く # } # # int waru(ここを書く) # { # ここを書く # } # # int amari(ここを書く) # { # ここを書く # } # # int yakusu(ここを書く) # { # ここを書く # } # # int baisu(ここを書く) # { # ここを書く # } '2つの整数を入力させ,各種処理を選び, 計算した結果をファイルへ出力するものである. 下記に従い,プログラムを完成させよ. ・各処理を行う場合は関数ポインタ引数とするをprocess()用いる ・加算:tasu(),除算(商):waru(),除算(剰余):amari()  最大公約数:yakusu(),最小公倍数:baisu()を用いる. ・除算は商と剰余を求める. ・最大公約数は2つの整数で共通の約数のうち最大のもの,  最小公倍数は2つの整数で共通の倍数のうち最小のものである. ・結果は「14 ÷ 5 = 2 余り 4」や「6 と 4 の最小公倍数は 12」のように  計算式等も含めkekka.txtへ出力する.' :- open('kekka.txt',write,Outstream), 二つの整数と演算番号を得る(_一つ目の整数,_二つ目の整数), 演算処理と結果を表示する(Outstream,_一つ目の整数,_二つ目の整数,_演算番号), \+(between(1,4,_演算番号)), close(Outstream). 二つの整数と演算番号を得る(_一つ目の整数,_二つ目の整数,_演算番号) :- 整数を得る('1つめの整数を入力してください',true,_一つ目の整数), 整数を得る('2つめの整数を入力してください',true,_二つ目の整数), 整数を得る('演算子番号を入力してください\n1:加算,2:除算,3:最大公約数,4:最小公倍数',between(1,4,_演算番号),_演算番号). 演算処理と結果を表示する(Outstream,_一つ目の整数,_二つ目の整数,_演算番号) :- 整数を得る('演算番号を入力してください\n1:加算,2:除算,3:最大公約数,4:最小公倍数',true,_演算番号), 演算処理(_演算番号,_一つ目の整数,_二つ目の整数,_結果文字列), writef(Outstream,'%t\n',[_結果文字列]). 演算処理と結果を表示する(Outstream,_一つ目の整数,_二つ目の整数,_演算番号) :- 演算処理と結果を表示する(Outstream,_一つ目の整数,_二つ目の整数,_演算番号). 演算処理(1,_一つ目の整数,_二つ目の整数,_結果文字列) :- _結果 is _一つ目の整数 + _二つ目の整数, swritef(_結果文字列,'%t + %t = %t',[_一つ目の整数,_二つ目の整数,_結果]). 演算処理(2,_一つ目の整数,_二つ目の整数,_結果文字列) :- _商 is _一つ目の整数 // _二つ目の整数, _剰余 is _一つ目の整数 mod _二つ目の整数, swritef(_結果文字列,'%t %% %t = %t 余り %t',[_一つ目の整数,_二つ目の整数,_商,_剰余]). 演算処理(最大公約数,_一つ目の整数,_二つ目の整数,_結果文字列) :- 最大公約数(_一つ目の整数,_二つ目の整数,_結果), swritef(_結果文字列,'%t と %t の最大公約数は %t,[_一つ目の整数,_二つ目の整数,_結果]). 演算処理(4,_一つ目の整数,_二つ目の整数,_結果文字列) :- 最小公倍数(_一つ目の整数,_二つ目の整数,_結果), swritef(_結果文字列,'%t と %t の最小公倍数は %t,[_一つ目の整数,_二つ目の整数,_結果]). 演算処理(N,_,_,'終了します') :- \+(between(1,4,N)). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 最小公倍数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,Y), X is M * N // Y. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1354070278/386 # # 二つの2×3型行列を # A=1.1 -2.2 0.9 #  -0.2  2.7 0.3 # # B= 1.8 0.5 1.3 # -0.4 0.6 -0.3 # と定義する。 # # これらの二つの行列の宣言、初期化し、C≡A+B C≡A-Bを算出して # 2×3型の表形式で出力するプログラムを作成せよ。ただし、行列CとDは固定長 # 配列とし、関数内の演算を行うこと # # 上記の問題と同じように行列A、Bを用いて、積C≡ABt を算出し、2×2型の表 # 形式で出力せよ。ただし、Bの転置行列、Btはプログラム中に直接記述するのでは # なく、Bより作成すること。また、Cはnew演算子によりメモリを確保し、関数内で # 演算を行うこと。 # # # だれかこのプログラムおしえてくださいm(_ _)m # # '行列A、Bを用いて、積C≡ABt を算出し、2×2型の表形式で出力せよ。ただし、Bの転置行列、Btはプログラム中に直接記述するのではなく、Bより作成すること。'(A,B,C) :- 転置(B,Bt), 行列の掛算_1(A,Bt,C), '2×2型の表形式で出力せよ'(C). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2) . 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 行列の掛算_1([],_,[]) :- !. 行列の掛算_1([A|R1],L,[S1|R3]) :- 行列の掛算_2(A,L,S1), 行列の掛算_1(R1,L,R3). 行列の掛算_2(_,[],[]) :- !. 行列の掛算_2(A,[B|R2],[C|R3]) :- 行列の掛算_3(A,B,C), 行列の掛算_2(A,R2,R3). 行列の掛算_3([],[],0) :- !. 行列の掛算_3([A|R1],[B|R2],S) :- 分数を含む掛算(A,B,S1), 行列の掛算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(0,_,0) :- !. 約分の二(0.0,_,0) :- !. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). '2×2型の表形式で出力せよ'(LL) :- 'M×Nの表形式で出力する'(2,2,LL). 'M×Nの表形式で出力する'(M,N,LL) :- 'N列カンマ区切り行表示形式'(N,_行表示形式), nth1(_nth1,LL,L), writef(_行表示形式,L), _nth1 = M. 'N列カンマ区切り行表示形式'(N,_行表示形式) :- findall('%t',between(1,N,_),PL), atomic_list_concat(PL,',',S1), atom_concat(S1,'\n',_行表示形式). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1354070278/386 # # 二つの2×3型行列を # A=1.1 -2.2 0.9 #  -0.2  2.7 0.3 # # B= 1.8 0.5 1.3 # -0.4 0.6 -0.3 # と定義する。 # # これらの二つの行列の宣言、初期化し、C≡A+B C≡A-Bを算出して # 2×3型の表形式で出力するプログラムを作成せよ。ただし、行列CとDは固定長 # 配列とし、関数内の演算を行うこと # # 上記の問題と同じように行列A、Bを用いて、積C≡ABt を算出し、2×2型の表 # 形式で出力せよ。ただし、Bの転置行列、Btはプログラム中に直接記述するのでは # なく、Bより作成すること。また、Cはnew演算子によりメモリを確保し、関数内で # 演算を行うこと。 # # # だれかこのプログラムおしえてくださいm(_ _)m # # '二つの2×3型行列を A=1.1 -2.2 0.9  -0.2  2.7 0.3 B= 1.8 0.5 1.3 -0.4 0.6 -0.3 と定義する。 これらの二つの行列の宣言、初期化し、C≡A+B C≡A-Bを算出して 2×3型の表形式で出力する' :- これらの二つの行列の宣言(A,B), 'C≡A+B C≡A-Bを算出して'(A,B,C), '2×3型の表形式で出力する'(C), '2×3型の表形式で出力する'(D). これらの二つの行列の宣言(A,B) :- A = [[1.1,-2.2,0.9],[-0.2,2.7,0.3]], B = [[1.8,0.5,1.3],[-0.4,0.6,-0.3]]. 'C≡A+B C≡A-Bを算出して'(A,B,C) :- 行列の和(A,B,C), 行列の差(A,B,D). 行列の和([],[],[]). 行列の和([L1|R1],[L2|R2],[L3|R3]) :- 行の和(L1,L2,L3), 行列の和(R1,R2,R3). 行の和([],[],[]). 行の和([A|R1],[B|R2],[C|R3]) :- 分数を含む加算(A,B,C), 行の和(R1,R2,R3). 行列の差([],[],[]). 行列の差([L1|R1],[L2|R2],[L3|R3]) :- 行の差(L1,L2,L3), 行列の差(R1,R2,R3). 行の差([],[],[]). 行の差([A|R1],[B|R2],[C|R3]) :- B_1 is B * (-1). 分数を含む加算(A,B_1,C), 行の差(R1,R2,R3). 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(0,_,0) :- !. 約分の二(0.0,_,0) :- !. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). '2×3型の表形式で出力する'(LL) :- 'M×Nの表形式で出力する'(2,3,LL). 'M×Nの表形式で出力する'(M,N,LL) :- 'N列カンマ区切り行表示形式'(N,_行表示形式), nth1(_nth1,LL,L), writef(_行表示形式,L), _nth1 = M. 'N列カンマ区切り行表示形式'(N,_行表示形式) :- findall('%t',between(1,N,_),PL), atomic_list_concat(PL,',',S1), atom_concat(S1,'\n',_行表示形式). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1349527750/562 # # 以下のような行列の積を求めるプログラムを作成して下さい # # 行列xを表示 # 1 2 # 3 4 # 5 6 # # 行列yを表示 # 1 2 4 # 3 6 9 # # 行列xとyの積を表示 # # # ^^^^^^^^^^^^^^^^^^^^^^^ # 行列xとyの積を表示の下には計算結果を表示するようなプログラムを教えて下さい # お願いします # 行列の積(L1,L2,X) :- 転置(L2,L4), 二つの行列の要素の全ての行と行の組合せに対して要素を乗算した上で合計した値による行列を作る(L1,L4,X). 二つの行列の要素の全ての行と行の組合せに対して要素を乗算した上で合計した値による行列を作る([],_,[]) :- !. 二つの行列の要素の全ての行と行の組合せに対して要素を乗算した上で合計した値による行列を作る([_行_1|R1],_行列_2,[_合計ならび|R3]) :- 二つのならびの要素を順に乗算した値の合計のならび(_行_1,_行列_2,_合計ならび), 二つの行列の要素の全ての行と行の組合せに対して要素を乗算した上で合計した値による行列を作る(R1,_行列_2,R3). 二つのならびの要素を順に乗算した値の合計のならび(_,[],[]) :- !. 二つのならびの要素を順に乗算した値の合計のならび(L1,[L2|R2],[_合計値|R3]) :- 二つのならびの要素を順に乗算した値の合計を取る(L1,L2,_合計値), 二つのならびの要素を順に乗算した値の合計のならび(L1,R2,R3). 二つのならびの要素を順に乗算した値の合計を取る([],[],0) :- !. 二つのならびの要素を順に乗算した値の合計を取る([A1 / A2|R1],[B1 / B2|R2],S) :- S01 is A1 * B1, S02 is A2 * B2, 約分(S01 / S02,S1), 二つのならびの要素を順に乗算した値の合計を取る(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 二つのならびの要素を順に乗算した値の合計を取る([A1 / A2|R1],[B|R2],S) :- S0 is A1 * B, 約分(S0 / A2,S1), 二つのならびの要素を順に乗算した値の合計を取る(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 二つのならびの要素を順に乗算した値の合計を取る([A|R1],[B1 / B2|R2],S) :- S0 is A * B1, 約分(S0 / B2,S1), 二つのならびの要素を順に乗算した値の合計を取る(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 二つのならびの要素を順に乗算した値の合計を取る([A|R1],[B|R2],S) :- S1 is A * B, 二つのならびの要素を順に乗算した値の合計を取る(R1,R2,S2), 分数を含む加算(S1,S2,S). 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1337692704/378 # # 課題:http://ime.nu/www.dotup.org/uploda/www.dotup.org3502064.jpg # ファイル名はKadai01.javaとする。 # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 GUI  】制限なし # 【 期限 】10月14(日曜日まで) # 【 Ver  】javac 1.7.0_07 # # 行列A,Bに対して,和A+B,積ABおよびBAを計算するプログラムを作成し実行しなさい.ただし # # A = # 1 2 3 # 4 5 6 # 7 8 9 # # B = # 1 1 0 # 2 0 1 # 0 2 3 # # とする. # '行列A,Bに対して,和A+B,積ABおよびBAを計算するプログラムを作成し実行しなさい'(_行列A,_行列B,_行列の和,_行列の積AB,_行列の積BA) :- '和A+B'(_行列A,_行列B,_行列の和), 積AB(_行列A,_行列B,_行列の積AB), 積BA(_行列A,_行列B,_行列の積BA). '和A+B'([],[],[]). '和A+B'([L1|R1],[L2|R2],[L3|R3]) :- 列ごとに加算(L1,L2,L3), '和A+B'(R1,R2,R3). 列ごとに加算([],[],[]). 列ごとに加算([A|R1],[B|R2],[C|R3]) :- 分数を含む加算(A,B,C), 列ごとに加算(R1,R2,R3). 積AB(_行列A,_行列B,_行列の積AB) :- 行列の積(_行列A,_行列B,_行列の積AB). 積BA(_行列A,_行列B,_行列の積BA) :- 行列の積(_行列B,_行列A,_行列の積BA). 行列の積(L1,L2,X) :- 転置(L2,L4), 行列の積_1(L1,L4,X). 行列の積_1([],_,[]) :- !. 行列の積_1([A|R1],L,[S1|R3]) :- 行列の積_2(A,L,S1), 行列の積_1(R1,L,R3). 行列の積_2(_,[],[]) :- !. 行列の積_2(A,[B|R2],[C|R3]) :- 行列の積_3(A,B,C), 行列の積_2(A,R2,R3). 行列の積_3([],[],0) :- !. 行列の積_3([A1 / A2|R1],[B1 / B2|R2],S) :- S01 is A1 * B1, S02 is A2 * B2, 約分(S01 / S02,S1), 行列の積_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列の積_3([A1 / A2|R1],[B|R2],S) :- S0 is A1 * B, 約分(S0 / A2,S1), 行列の積_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列の積_3([A|R1],[B1 / B2|R2],S) :- S0 is A * B1, 約分(S0 / B2,S1), 行列の積_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列の積_3([A|R1],[B|R2],S) :- S1 is A * B, 行列の積_3(R1,R2,S2), 分数を含む加算(S1,S2,S). 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4) . 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは 最大公約数をユークリッドの互除法で求める(M,N,N) :- 'MがNで割りきれたらNが最大公約数である'(M,N). 最大公約数をユークリッドの互除法で求める(M,N,X) :- 'MがNで割り切れず'(M,N), 'Modが余りなら'(M,N,Mod), '第一引数をN,第二引数をModに入れ替えて、最大公約数をユークリッドの互除法で求める'(N,Mod,X). 'MがNで割りきれたらNが最大公約数である'(M,N) :- 0 =:= M mod N. 'MがNで割り切れず'(M,N) :- 0 =\= M mod N. 'Modが余りなら'(M,N,Mod) :- Mod is M mod N. '第一引数をN,第二引数をModに入れ替えて、最大公約数をユークリッドの互除法で求める'(N,Mod,X) :- 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは ガウス法によるLU分解(_n,LL,LU,L,U) :- 解が生成される変数行列とその転置行列の生成(_n,LU,LU2), 転置(LL,LL2), ガウス法によるLU分解(LL,LL2,LU,LU2), 'LとUに分解'(LU,L,U),!. 解が生成される変数行列とその転置行列の生成(_n,LU,LU2) :- length(LU,_n), findall(L,( between(1,_n,_), length(L,_n)), LU), 転置(LU,LU2),!. ガウス法によるLU分解([],[],[],[]) :- !. ガウス法によるLU分解([[A|L1]|R1],[[A|L2]|R2],[[A|L3]|R3],[[A|L2]|R4]) :- '第一行は各列を隅要素(A)で割って置換する'(A,L1,L3), 第二行以下は次の対象矩形を生成する(L2,L3,R1,_次の対象矩形), '次の対象矩形の変数行列(第一行と第一列だけ段々に確定していく)'(R3,R4,R31,R41), 転置(_次の対象矩形,_転置された次の対象矩形), ガウス法によりLu分解(_次の対象矩形,_転置された次の対象矩形,R31,R41), '第一行は各列を隅要素(A)で割って置換する'(A,[],[]). '第一行は各列を隅要素(A)で割って置換する'(A,[A1|R1],[B1|R2]) :- 'A1をAで割る'(A,A1,B1), '第一行は各列を隅要素(A)で割って置換する'(A,R1,R2). 'A1をAで割る'(A,A1,B1) :- 行基本変形除算(A,1,A1,B1). 第二行以下は次の対象矩形を生成する([],_,[],[]) :- !. 第二行以下は次の対象矩形を生成する([A|R1],L2,[[_|L3]|R3],[L|R]) :- '各行の列を現在値(C)を基礎に第一列の値(A)と第一行の値(B)から書き換える'(A,L2,L3,L), 第二行以下は次の対象矩形を生成する(R1,L2,R3,R). '各行の列を現在値(C)を基礎に第一列の値(A)と第一行の値(B)から書き換える'(_,[],[],[]) :- !. '各行の列を現在値(C)を基礎に第一列の値(A)と第一行の値(B)から書き換える'(A,[B|R2],[C|R3],[D|R4]) :- 'D is C - A * B'(A,B,C,D), '各行の列を現在値(C)を基礎に第一列の値(A)と第一行の値(B)から書き換える'(A,R2,R3,R4). 'D is C - A * B'(A,B,C,D) :- 行基本変形乗算(A,B,V), 行基本変形減算(C,V,D),!. '次の対象矩形の変数行列(第一行と第一列だけ段々に確定していく)'([],[],[],[]). '次の対象矩形の変数行列(第一行と第一列だけ段々に確定していく)'([[_|L3]|R3],[[_|L4]|R4],[L3|R31],[L4|R41]) :- '次の対象矩形の変数行列(第一行と第一列だけ段々に確定していく)'(R3,R4,R31,R41). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 'LとUに分解'(LU,L,U) :- 'Lに分解'(LU,L), 'Uに分解'(LU,U). 'Lに分解'(LU,LL) :- findall(L2,( member(L1,LU), append(L0,R,L1), \+(L0 = []), '残り要素Rをすべて0に置き換える'(L0,R,L2)), LL). '残り要素Rをすべて0に置き換える'(L0,R,L2) :- length(R,Len), length(R1,Len), all(R1,0), append(L0,R1,L2),!. 'Uに分解'(LU,UU) :- findall(L2,( member(L,LU), append(L0,L1,L), 'L0の全要素を0に置き換える'(L0,L1,L2)), UU). 'L0の全要素を0に置き換える'(L,L0,[A|R1],L2) :- length(L0,Len), length(L0_2,Len), all(L0_2,0), 'L1を先頭要素で割る'(L1,L1_2), append(L0_2,L1_2,L2),!. 'L1を先頭要素で割る'([_先頭要素|R1],[1|R2]) :- findall(M,( member(A,R1), 分数を含む除算(A,_先頭要素,M)), R2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 行基本変形乗算(_乗数_1,_乗数_2,X) :- integer(_乗数_1), integer(_乗数_2), X is _乗数_1 * _乗数_2,!. 行基本変形乗算(_分子_1/_分母_1,_分子_2/_分母_2,X) :- _分子 is _分子_1 * _分子_2, _分母 is _分母_1 * _分母_2, 約分(_分子 / _分母,X),!. 行基本変形乗算(_分子/_分母,_乗数_2,X) :- A is _分子 * _乗数_2, 0 is A mod _分母, X is A // _分母,!. 行基本変形乗算(_乗数_1,_分子/_分母,X) :- atomic(_乗数_1), 行基本変形乗算(_分子/_分母,_乗数_1,X),!. 行基本変形乗算(_乗数_1,_乗数_2,X) :- X is _乗数_1 * _乗数_2,!. 行基本変形除算(A,_乗数,_除数,X) :- integer(A), integer(_乗数), integer(_除数), A2 is A * _乗数, 0 is A2 mod _除数, X is A * _乗数 // _除数,!. 行基本変形除算(A,_乗数,_除数,X) :- integer(A), integer(_乗数), integer(_除数), A2 is A * _乗数, \+(0 is A2 mod _除数), 約分(A2 / _除数,X),!. 行基本変形除算(A,_乗数,_除数,X) :- X is A * _乗数 / _除数. 行基本変形減算(A,B,C) :- atomic(A), atomic(B), C is A - B,!. 行基本変形減算(A1/A2,B1/B2,X) :- _分子 is A1 * B1, _分母 is A2 * B2, 約分(_分子 / _分母,X),!. 行基本変形減算(A1/A2,B1/B2,X) :- _分子 is A1 * B2 - B1 * A2, _分母 is A2 * B2, 約分(_分子 / _分母,X),!. 行基本変形減算(A1/A2,B,X) :- atomic(B), _分子 is A1 - A2 * B, _分母 is A2, 約分(_分子 / _分母,X),!. 行基本変形減算(B,A1/A2,X) :- 行基本変形減算(A1/A2,B,X),!. 行基本変形減算(A,B,X) :- X is A - B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/827 # # [1] 授業単元:C # [2] 問題文(含コード&リンク): # http://ime.nu/codepad.org/qQfTmJyV # リンク先のコードは分数を読み込み、その分数を約分した結果を表示するものの一部であり、 # このプログラムを完成させよ。ただし、分子と分母に0を入力すると終了する。 # # 実行例 # bunshi:36 # bunbo:48 # 3/4 # bunshi:-12 # bunbo:15 # -4/5 # bunshi:0 # bunbo:0 # # '分数を読み込み、その分数を約分した結果を表示する' :- '分数を読み込み、'(_分数), その分数を約分した結果を(_分数,_約分した結果), 表示する(_分数,_約分した結果). '分数を読み込み、'(_分数) :- 分子を読み込む(_分子), 分母を読み込む(_分母), _分数 = _分子 / _分母. 分子を読み込む(_分子) :- 整数を得る(分子,_分子). 分母はを読み込む(_分母) :- 整数を得る(分母,_分母). その分数を約分した結果を(_分子_1 / _分母_1,_分子 / _分母) :- 最大公約数(_分子_1,_分母_1,_最大公約数), _分子 is _分子_1 // _最大公約数, _分母 is _分母_1 // _最大公約数. 表示する(_分子_1/_分母_1,_分子/_分母) :- writef('入力した分数 %t/%t\n約分した分数 %t/%t\n',[_分子_1,_分母_1,_分子,_分母]). 整数を得る(_催促文,_整数) :- 催促文を表示して整数を得る(_催促文,_整数),!. 整数を得る(_催促文,_整数) :- 整数を得る(_催促文,_整数). 催促文を表示して整数を得る(_催促文,_整数) :- writef('%wを入力して下さい : ',[_催促文]), 整数を得る(_整数). 整数を得る(_整数) :- 行入力(_行), 整数検査(_行,_整数). 行入力(_行) :- read_line_to_codes(user_input,_codes), atom_codes(_行,_codes). 整数検査(_行,_整数) :- atom_number(_行,_整数), integer(_整数),!. 整数検査(_行,_) :- writef('入力された %w は整数ではありません。再入力をお願いします。\n',[_行]), fail. 最大公約数をユークリッドの互除法で求める(M,N,_最大公約数) :- ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(M,N,_最大公約数). ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,_最大公約数) :- _剰余 is _被除数 mod _除数, 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,_剰余,_最大公約数). 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,0,_最大公約数) :- 割り切れたらその時の除数が最大公約数だ(_除数,_最大公約数),!. 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,_剰余,_最大公約数) :- '割り切れなかったら除数を被除数、剰余を除数に置き換えて計算を続ける'(_被除数,_除数,_剰余,_最大公約数). 割り切れたらその時の除数が最大公約数だ(_除数,_最大公約数) :- _除数 = _最大公約数. '割り切れなかったら除数を被除数、剰余を除数に置き換えて計算を続ける'(_被除数,_除数,_剰余,_最大公約数) :- ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_除数,_剰余,_最大公約数). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/190 # # [1] プログラミング入門 # [2] # # 課題1 a[5] ={1, 3, 5, 2, -1} であるとき最も大きい値と小さい値を表示するプログラムを作成する。 # # 課題2 a[2][2] = {{1,2},{3,4}}, b[2][1]={{1},{3}} のとき行列aとbを掛け算した結果a*b を出力する。(難しいかな?) # # [環境] # [3.1] OS:windows # [3.2] コンパイラ名とバージョン:Microsoft Visual studio 2010 # [3.3] 言語:C++ # [4] 期限: 6月19日 21:00まで # '課題2 a[2][2] = {{1,2},{3,4}}, b[2][1]={{1},{3}} のとき行列aとbを掛け算した結果a*bを出力する' :- 行列の掛け算([[1,2],[3,4]],[[1],[3]],_行列aとbを掛け算した結果). 行列の掛け算(_a,_b,_行列aとbを掛け算した結果) :- 転置(_b,_転置したb), 行列の掛け算_1(_a,_転置したb,_行列aとbを掛け算した結果), '行列a*bを出力する'(_行列aとbを掛け算した結果). 行列の掛け算_1([],_,[]) :- !. 行列の掛け算_1([A|R1],L,[S1|R3]) :- 行列の掛け算_2(A,L,S1), 行列の掛け算_1(R1,L,R3) . 行列の掛け算_2(_,[],[]) :- !. 行列の掛け算_2(A,[B|R2],[C|R3]) :- 行列の掛け算_3(A,B,C), 行列の掛け算_2(A,R2,R3). 行列の掛け算_3([],[],0). 行列の掛け算_3([A|R1],[B|R2],S) :- S1 is A * B, 行列の掛け算_3(R1,R2,S2), 分数を含む加算(S1,S2,S) . 行列の掛け算_3([],[],0) :- !. 行列の掛け算_3([A1 / A2|R1],[B1 / B2|R2],S) :- S01 is A1 * B1, S02 is A2 * B2, 約分(S01 / S02,S1), 行列の掛け算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列の掛け算_3([A1 / A2|R1],[B|R2],S) :- S0 is A1 * B, 約分(S0 / A2,S1), 行列の掛け算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列の掛け算_3([A|R1],[B1 / B2|R2],S) :- S0 is A * B1, 約分(S0 / B2,S1), 行列の掛け算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列の掛け算_3([A|R1],[B|R2],S) :- S1 is A * B, 行列の掛け算_3(R1,R2,S2), 分数を含む加算(S1,S2,S) . 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B . 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). '行列a*bを出力する'(_行列aとbを掛け算した結果) :- write('['), append(_,[_行|R],_行列aとbを掛け算した結果), writef(' %t\n',[_行]), R = [_最終行], writef(' %t]\n',[_最終行]). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/138 # # [1] 授業単元:プログラミング # [2] 問題文:[1] 授業単元: # 出典:: http://ime.nu/www.fluid.cse.nagoya-u.ac.jp/~ishihara/c/Sec6kadai20.html # # # 2つの自然数aとbの最大公約数gcd(a, b)を求め、それを出力するプログラムを作成せよ。 # # なお、m = a % b としたとき、gcd(a, b) は m≠0 の場合 gcd(b, m) に等しく、 m=0 の場合 b に等しい。 # # 2つの自然数aとbを入力させ、a 人から b 人を選ぶ組み合わせ comb(a, b)を求め、それを出力するプログラムを作成せよ。 # # なお、comb(a, b) = comb( a-1, b) + comb( a-1, b-1) であり、 b==0 もしくは b==a のとき comb(a, b) = 1 である。 '2つの自然数aとbを入力させ、a 人から b 人を選ぶ組み合わせ comb(a, b) を求め、それを出力する' :- '2つの自然数aとbを入力させ'(_a,_b), comb(_a,_b,X), それを出力する'(_a,_b,X). '2つの自然数aとbを入力させ'(_a,_b) :- 整数を得る(自然数,_a > 0,_a), 整数を得る(自然数,_b > 0,_b). comb(_a,0,1). comb(_a,_a,1). comb(_a,_b,_x) :- _a_1 is _a - 1, _b_1 is _b - 1, comb(_a_1,_b,_x_1), comb(_a_1,_b_1,_x_2), _x is _x_1 + _x_2. それを出力する(_a,_b,X) :- writef('%t 人から %t 人を選ぶ組み合わせは %t 通りです。\n',[_a,_b,X]). % 整数を得る/2,整数を得る/3 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/138 # # [1] 授業単元:プログラミング # [2] 問題文:[1] 授業単元: # 出典:: http://ime.nu/www.fluid.cse.nagoya-u.ac.jp/~ishihara/c/Sec6kadai20.html # # # 2つの自然数aとbの最大公約数gcd(a, b)を求め、それを出力するプログラムを作成せよ。 # # なお、m = a % b としたとき、gcd(a, b) は m≠0 の場合 gcd(b, m) に等しく、 m=0 の場合 b に等しい。 # # 2つの自然数aとbを入力させ、a 人から b 人を選ぶ組み合わせ comb(a, b)を求め、それを出力するプログラムを作成せよ。 # # なお、comb(a, b) = comb( a-1, b) + comb( a-1, b-1) であり、 b==0 もしくは b==a のとき comb(a, b) = 1 である。 '2つの自然数aとbの最大公約数gcd(a, b)を求め、それを出力する。なお、m = a % b としたとき、gcd(a, b) は m≠0 の場合 gcd(b, m) に等しく、 m=0 の場合 b に等しい。'(_a,_b,_最大公約数) :- gcd(_a,_b,_最大公約数), それを出力する(_a,_b,_最大公約数). gcd(_a,_b,_b) :- 0 is _a mod _b. gcd(_a,_b,_最大公約数) :- _m is _a mod _b, gcd(_b,_m,_最大公約数). それを出力する(_a,_b,_最大公約数) :- writef('%t と %t の最大公約数は %t です。\n',[_a,_b,_最大公約数]). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/138 # # [1] 授業単元:プログラミング # [2] 問題文:[1] 授業単元: # 出典:: http://ime.nu/www.fluid.cse.nagoya-u.ac.jp/~ishihara/c/Sec6kadai20.html # # # 2つの自然数aとbの最大公約数gcd(a, b)を求め、それを出力するプログラムを作成せよ。 # # なお、m = a % b としたとき、gcd(a, b) は m≠0 の場合 gcd(b, m) に等しく、 m=0 の場合 b に等しい。 # # 2つの自然数aとbを入力させ、a 人から b 人を選ぶ組み合わせ comb(a, b)を求め、それを出力するプログラムを作成せよ。 # # なお、comb(a, b) = comb( a-1, b) + comb( a-1, b-1) であり、 b==0 もしくは b==a のとき comb(a, b) = 1 である。 '2つの自然数aとbの最大公約数gcd(a, b)を求め、それを出力する'(_a,_b,_最大公約数) :- ユークリッドの互除法で最大公約数を求める(_a,_b,_最大公約数). ユークリッドの互除法で最大公約数を求める(_a,_b,_b) :- 0 is _a mod _b. ユークリッドの互除法で最大公約数を求める(_a,_b,_最大公約数) :- _m is _a mod _b, ユークリッドの互除法で最大公約数を求める(_b,_m,_最大公約数). '2つの自然数aとbを入力させ、a 人から b 人を選ぶ組み合わせ comb(a, b) を求め、それを出力する' :- '2つの自然数aとbを入力させ'(_a,_b), 'a 人から b 人を選ぶ組み合わせ comb(a, b)を求め'(_a,_b,X), それを出力する'(_a,_b,X). '2つの自然数aとbを入力させ'(_a,_b) :- 整数を得る(自然数,_a), 整数を得る(自然数,_b), _a > 0, _b > 0. 'a 人から b 人を選ぶ組み合わせ'(_a,0,1). 'a 人から b 人を選ぶ組み合わせ'(_a,_a,1). 'a 人から b 人を選ぶ組み合わせ'(_a,_b,_x) :- _a_1 is _a - 1, _b_1 is _b - 1, 'a 人から b 人を選ぶ組み合わせ'(_a_1,_b,_x_1), 'a 人から b 人を選ぶ組み合わせ'(_a_1,_b_1,_x_2), _x is _x_1 + _x_2. それを出力する(_a,_b,X) :- writef('%t 人から %t 人を選ぶ組み合わせは %t 通りです。\n',[_a,_b,X]). % 以下のサイトは 分数の計算と表示 :- 分数を2項読み込む([一,分子,一,分母,二,分子,二,分母],[_分子_1,_分母_1,_分子_2,_分母_2]), _答え仮分数分子 is _分子_1 * _分母_2 + _分子_2 * _分母_1, _答え仮分数分母 is _分母_1 * _分母_2, 最大公約数(_答え仮分数分子,_答え仮分数分母,_最大公約数), _答え仮分数分子_2 is _答え仮分数分子 // _最大公約数, _答え仮分数分母_2 is _答え仮分数分母 // _最大公約数, 帯分数(_答え仮分数分子_2,_答え仮分数分母_2,_答え整数部分, _答え分子,_答え分母), 分数計算表示(_分子_1,_分子_2,_答え分子,_答え整数部分,_分母_1,_分母_2,_答え分母). 分数を2項読み込む([],[]). 分数を2項読み込む([A,B|R1],[C|R2]) :- writef('第%t項の%tを整数で入力してください : ',[A,B]), get_integer(C), 分数を2項読み込む(R1,R2). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, \+(_答えの分子=0), writef(' %2r %2r %2r \n',[_分子_1,_分子_2,_答え分子]), writef('---- + ---- =%2r---- \n',[_整数部分]), writef(' %2r %2r %2r \n',[_分母_1,_分母_2,_答え分母]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, 答えの分子=0, writef(' %2r %2r\n',[_分子_1,_分子_2]), writef('---- + ---- = %2r \n',[_整数部分]), writef(' %2r %2r\n',[_分母_1,_分母_2]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 = 0, writef(' %2r %2r %2r \n',[_分子_1,_分子_2,_答え分子]]), write('---- + ---- = ---- \n'), writef(' %2r %2r %2r \n',[_分母_1,_分母_2,_答え分子]]). 帯分数(_仮分数分子,_仮分数分母,_帯分数整数部分, _帯分数分子,_帯分数分母) :- _帯分数整数部分 is _仮分数分子 // _仮分数分母, _帯分数分子 is _仮分数分子 mod _仮分数分母. _帯分数分母 = _仮分数分母. % 行列の掛算の中での分数 行列の掛算(L1,L2,X) :- 転置(L2,L4), 行列の掛算_1(L1,L4,X). 行列の掛算_1([],_,[]) :-!. 行列の掛算_1([A|R1],L,[S1|R3]) :- 行列の掛算_2(A,L,S1), 行列の掛算_1(R1,L,R3). 行列の掛算_2(_,[],[]) :-!. 行列の掛算_2(A,[B|R2],[C|R3]) :- 行列の掛算_3(A,B,C), 行列の掛算_2(A,R2,R3). 行列の掛算_3([],[],0) :-!. 行列の掛算_3([A|R1],[B|R2],S) :- 分数を含む掛算(A,B,S1), 行列の掛算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 分数を含む掛算(A1 / A2,B1 / B2,C) :- S1 is A1 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む掛算(A1 / A2,B,C) :- S1 is A1 * B, 約分(S1 / A2,C),!. 分数を含む掛算(A,B1 / B2,C) :- S1 is B1 * A, 約分(S1 / B2,C),!. 分数を含む掛算(A,B,C) :- C is A * B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % get_numberのなかでの分数 get_number(_数値) :- get_line(Line), get_number_診断(Line,_数値),!. get_number(_数値) :- get_number(_数値). get_number_診断(Line,_数値,_) :- atom_to_term(Line,_数値,_), 数値か(_数値),!. get_number_診断(Line,_数値,_) :- writef('入力された %t からは数値が得られません。再入力をお願いします。\n',[Line]), fail. 数値か(_分子/_分母) :- integer(_分子), integer(_分母),!. 数値か(_数値) :- number(_数値). % '1/3 + 3/5 + 7/9 + 9/11 + 11/13+..........+95/97 + 97/99 を合計する' :- 分子ならび(_分子ならび), 分母ならび(_分母ならび), 分子(_分子ならび,_分母ならび,_分子), 分母(_分母ならび,_分母), _合計 is _分子 / _分母, writef('合計は %t です\n',[_合計]). 分子([N],_分母ならび,_分子) :- '重複のないならびからNを取り除く'(N,_分母ならび,L), 全てを掛ける([N|L],_分子),!. 分子([N|R1],_分母ならび,_分子) :- '重複のないならびからNを取り除く'(N,_分母ならび,L), 全てを掛ける(L,_分子_1), 分子式(R1,_分母ならび,_分子_2), _分子 is _分子_1 + _分子_2. 分子ならび(_分子ならび) :- findall(N,( for(1,N,97), 1 is N mod 2), _分子ならび). 分母([X],X) :- !. 分母([A|R],_分母) :- 分母(R,_分母_1) _分母 is A * _分母_1. 分母ならび(_分母ならび) :- findall(N,( for(3,N,99), 1 is N mod 2), _分母ならび). '重複のないならびからNを取り除く'(N,L,R) :- append(L0,[N|R1],L), append(L0,R1,R),!. % 分数の加算 分数の加算(_分子1/_分母1,_分子2/_分母2,_分子/_分母) :- A is _分母1 * _分母2, B is _分子1 * _分母2 + _分子2 * _分母1, 約分(B/A,_分子/_分母). 約分(B/A,_分子/_分母) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C. % 荷重移動平均 加重移動平均(_データならび,_サンプル数,_加重移動平均) :- reverse(_データならび,_反転したデータならび), length(L0,_サンプル数), append(L0,L1,_反転したデータならび), _分母 is _サンプル数 * (_サンプル数 + 1) / 2, 加重移動平均分子の計算(_サンプル数,L0,_分子), _加重移動平均 is _分子 / _分母,!. 加重移動平均分子の計算(_,[],0) :- !. 加重移動平均分子の計算(N,[A|R],S) :- N1 is N - 1, V is A * N, 加重移動平均分子の計算(N1,R,S1), S is S1 + V. % '2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求める'(_確率) :- '左からi番目のカードに書かれた数がi以上の度数'(1,2,0,0,_分子,_分母), \+(_分母 = 0), _確率 is _分子 / _分母,!. '左からi番目のカードに書かれた数がi以上の度数'(5,_カード,X,Y,X,Y) :- _カード > 6,!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード > 6, _i2 is _i + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i2,2,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分子2 is _分子1 + 1, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母2,_分子,_分母),!. '2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求める'(_確率) :- '左からi番目のカードに書かれた数がi以上の度数'(1,2,0,0,_分子,_分母), \+(_分母 = 0), _確率 is _分子 / _分母,!. '左からi番目のカードに書かれた数がi以上の度数'(5,_カード,X,Y,X,Y) :- _カード > 6,!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード > 6, _i2 is _i + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i2,2,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分子2 is _分子1 + 1, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母2,_分子,_分母),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1309076891/978 # # 【課題】http://www.dotup.org/uploda/www.dotup.org3052126.txt.html # 【形態】1. Javaアプリケーション(main()で開始) # 【GUI】4. 制限なし # 【期限】提出期限:6月4日 20時まで # 【Ver】java version "1.7.0_03" # 【 補足 】Java初心者なので教えていただけると幸いです。 # # # 最小公倍数と最大公約数 # # 2数MとNの最小公倍数と最大公約数を求める # # 整数を2 つM,N 入力して,その最小公倍数(LCM)と最大公約数(GCD) を求めて表示する # # for文で1つのソースコード # 「ユークリッドの互助法」でもう一つ作成する。 # # # 一応やってみましたが最小公倍数がうまく出力せずユークリッドを使用する方法はよくわかりませんでした。 # よろしくお願いします。 # ソース # import java.util.Scanner; # public class LCM_GCD { # # public static void main(String args[]) # { # # Scanner sc = new Scanner(System.in); # int i; # int j=0; # int m,n; # int a=0; # System.out.println("整数を2つ入力してください"); # m=sc.nextInt(); # n=sc.nextInt(); # # # for( i = 1; i <= n; i++) { # if(m*i % n == 0) { # a = i; # break; # } # } # # # # // for(i=1;i<=n;i++){ # //for(j=1;j<=m;j++){ # //if(m*i==n*j){ # //a=m*i; # //break; # //} # // } # //} # System.out.println("最小公倍数は"+a); # # # for(j=m;j>=1;j--){ # if(m%j==0&&n%j==0){ # break; # } # } # System.out.println("最大公約数は"+j); # # # # # } # # } 'ユークリッドの互除法により最大公約数を得る'(_m,_m,_m). 'ユークリッドの互除法により最大公約数を得る'(_m,_n,_最大公約数) :- _m > _n, _剰余 is _m mod _n, ユークリッドの互除法により最大公約数を得る(_m,_n,_剰余,_最大公約数). 'ユークリッドの互除法により最大公約数を得る'(_m,_n,_最大公約数) :- _m < _n, ユークリッドの互除法により最大公約数を得る(_n,_m,_最大公約数). ユークリッドの互除法により最大公約数を得る(_,_最大公約数,0,_最大公約数) :- !. ユークリッドの互除法により最大公約数を得る(_m,_n,_剰余,_最大公約数) :- 'ユークリッドの互除法により最大公約数を得る'(_n,_剰余,_最大公約数). 最小公倍数(_m,_n,_最小公倍数) :- Y is _m * _n, ユークリッドの互除法により最大公約数を得る(_m,_n,_最大公約数), _最小公倍数 is ( _m * _n ) // 最大公約数. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/654 # # [1] 授業単元: プログラミング # [2] 問題文(含コード&リンク): 問題文はリンク先にあります # http://ime.nu/codepad.org/3vEhNLeD # /* 問題文 # (1)行列の乗算を行う関数 # (2)行列の(i,j)要素に値をセットする関数 # (3)行列の(i,j)要素の値を得る関数 # (4)行列の第p行と第q行を入れ替える関数 を作りなさい。*/ 行列の乗算(L1,L2,X) :- 転置(L2,L4), 行列を転置された行列に掛け合わせる(L1,L4,X). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 行列を転置された行列に掛け合わせる([],_,[]) :- !. 行列を転置行された列に掛け合わせる([_行|R1],L,[S1|R3]) :- 行列の行を転置された行列に掛け合わせる(_行,L,S1), 行列を転置された行列に掛け合わせる(R1,L,R3). 行列を転置された行列に掛け合わせる(_,[],[]) :- !. 行列を転置された行列に掛け合わせる(A,[B|R2],[C|R3]) :- 行列要素の積(A,B,C), 行列を転置された行列に掛け合わせる(A,R2,R3). 行列要素の積([],[],0) :- !. 行列要素の積([A1 / A2|R1],[B1 / B2|R2],S) :- S01 is A1 * B1, S02 is A2 * B2, 約分(S01 / S02,S1), 行列要素の積(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列要素の積([A1 / A2|R1],[B|R2],S) :- S0 is A1 * B, 約分(S0 / A2,S1), 行列要素の積(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列要素の積([A|R1],[B1 / B2|R2],S) :- S0 is A * B1, 約分(S0 / B2,S1), 行列要素の積(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 行列要素の積([A|R1],[B|R2],S) :- S1 is A * B, 行列要素の積(R1,R2,S2), 分数を含む加算(S1,S2,S). 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. % 以下のサイトは # # 最大公約数をユークリッドの互除法で求める。 # 最大公約数をユークリッドの互除法で求める(M,N,_最大公約数) :- ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(M,N,_最大公約数). ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,_最大公約数) :- _剰余 is _被除数 mod _除数, 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,_剰余,_最大公約数). 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,0,_最大公約数) :- 割り切れたらその時の除数が最大公約数だ(_除数,_最大公約数),!. 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,_剰余,_最大公約数) :- '割り切れなかったら除数を被除数、剰余を除数に置き換えて計算を続ける'(_被除数,_除数,_剰余,_最大公約数). 割り切れたらその時の除数が最大公約数だ(_除数,_最大公約数) :- _除数 = _最大公約数. '割り切れなかったら除数を被除数、剰余を除数に置き換えて計算を続ける'(_被除数,_除数,_剰余,_最大公約数) :- ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_除数,_剰余,_最大公約数). % 以下のサイトは # # 最大公約数をユークリッドの互除法で求める。 # 最大公約数をユークリッドの互除法で求める(M,N,_最大公約数) :- 'MがNより小さい時はNとMを置換して実行する'(M,N,_最大公約数),!. 最大公約数をユークリッドの互除法で求める(M,N,_最大公約数) :- ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(M,N,_最大公約数). 'MがNより小さい時はNとMを置換して実行する'(M,N,_最大公約数) :- M < N, 最大公約数をユークリッドの互除法で求める(N,M,_最大公約数). ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_被除数,_除数,_最大公約数) :- _剰余 is _被除数 mod _除数, 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_除数,_剰余,_最大公約数). 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_除数,0,_最大公約数) :- 割り切れたらその時の除数が最大公約数だ(_除数,_最大公約数),!. 割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_除数,_剰余,_最大公約数) :- '割り切れなかったら除数を被除数、剰余を除数に置き換えて計算を続ける'(_除数,_剰余,_最大公約数). 割り切れたらその時の除数が最大公約数だ(_除数,_最大公約数) :- _除数 = _最大公約数. '割り切れなかったら除数を被除数、剰余を除数に置き換えて計算を続ける'(_除数,_剰余,_最大公約数) :- ユークリッドの互除法は割り切れるまで除数だった数を被除数に剰余だった数を除数として割ることを繰り返す(_除数,_剰余,_最大公約数). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1325685876/194 # # [1] 授業単元:C言語入門 # [2] 問題文: http://ime.nu/codepad.org/hsA7qgRQ # 課題3 # # キーボードからintの整数を入力する.入力された整数と,整数9699690との最大公約数を表示するプログラムを作成せよ.ただし整数9699690よりも大きい数が入力された場合はerrorと表示すること.マイナスの数を入力された場合は正の数として計算すること. # また,次の関数プロトタイプにしたがう自作の関数gcdを使うようにプログラムすること # # int gcd(int m, int x); //m>xとしてmとxの最大公約数を求めて返す関数 # このgcdを使うとmain関数は次のようにできる. # # int main(void) # { # int m,n,g; # m=9699690; # scanf("%d", &n); # g = gcd( m, n); # printf("%d\n",g); # } # 関数gcdの本体定義部分を自分で追加して全体としてプログラムを完成させること. # # 実行例 # 実行開始 # 60 ←キーボードから60と入力 # 30 ←9699690との最大公約数30を表示 # # ヒント # 最大公約数を求める有名なアルゴリズムとして,ユークリッドの互除法がある.二つの整数a,b(a>bとする)の最大公約数dを求める. # # ?Step 1. もしb=0であればd=|a|として終了 # ?Step 2. aをbで割った余りをrとする # ?Step 3. a=b, b=rとして、Step 1.へ # # # 'キーボードからintの整数を入力する.入力された整数と,整数9699690との最大公約数を表示する' :- 整数を入力する(_整数), 最大公約数をユークリッドの互除法で求める(9699690,_整数,_最大公約数), writef('最大公約数は %t です\n',[_最大公約数]). 整数を入力する(_整数) :- write('整数を入力して下さい : ), get_line(Line), 整数を入力する(Line,_整数),!. 整数を入力する(_整数) :- 整数を入力する(_整数). 整数を入力する(Line,_整数) :- atom_to_term(Line,_整数_1,_), integer(_整数), 整数入力検査(_整数_1,_整数),!. 整数を入力する(Line,_) :- writef('入力された %t からは適切な整数が得られません。再入力をお願いします\n',[Line]), fail. 整数入力検査(_整数_1,_整数) :- 9699690 > _整数_1, write('error\n'),!, fail. 整数入力検査(_整数_1,_整数) :- _整数_1 < 0, _整数 is abs(_整数_1),!. 整数入力検査(_整数,_整数) :- _整数 > 0,!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/477 # # [1] 授業単元:C言語 # [2] 問題文:3*3の逆行列Aをもとめよ # http://ime.nu/ideone.com/erZBk # '3*3の逆行列Aをもとめよ'(_a,_逆行列A) :- var(_a), '3行3列の行列aを入力'(_a), 正方行列の逆行列(_a,_逆行列A). '3*3の逆行列Aをもとめよ'(_a,_逆行列A) :- \+(var(_a)), 正方行列の逆行列(_a,_逆行列A). 正方行列の逆行列(_正方行列,_正方行列の逆行列) :- 余因子行列(_正方行列,_余因子行列), 転置(_余因子行列,_チルダ余因子行列), 行列式の値(_正方行列,_正方行列の行列式の値), チルダ余因子行列を正方行列の行列式の値で割る(_チルダ余因子行列,_正方行列の行列式の値,_正方行列の逆行列). チルダ余因子行列を正方行列の行列式の値で割る([],_,[]). チルダ余因子行列を正方行列の行列式の値で割る(_チルダ余因子行列,_正方行列の行列式の値,_正方行列の逆行列) :- _チルダ余因子行列 = [_行_1|R1], 行列要素の割り算(_行_1,_正方行列の行列式の値,_行_2), _正方行列の逆行列 = [_行_2|R2], チルダ余因子行列を正方行列の行列式の値で割る(R1,_正方行列の行列式の値,R2). 行列要素の割り算([],_,[]). 行列要素の割り算([_被除数|R1],_除数,[N2|R2]) :- 約分(_被除数/_除数,N2), 行列要素の割り算([N1|R1],D,[N2|R2]). 約分(B / A,V) :- \+(integer(B)), V is B / A,!. 約分(B / A,V) :- \+(integer(A)), V is B / A,!. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). '余因子行列で行列値|a|を求める'(_a,_行列式_aの値) :- 余因子行列(_n,_a,_余因子行列), _a = [_aの第一行|_], _余因子行列 = [_余因子行列の第一行|_], 二つのならびの積の和(_aの第一行,_余因子行列の第一行,_行列式_aの値). 余因子行列(_n,_正方行列,_余因子行列) :- length(_余因子行列,_n), findall(L,( nth1(_i,_余因子行列,L), 余因子行列の要素が余因子である(_n,_正方行列,_i,L)), _余因子行列). 余因子行列の要素が余因子である(_n,_正方行列,_i,L) :- length(L,_n), findall(_余因子,( nth1(_j,L,_余因子), 余因子(_n,_正方行列,_i,_j,_余因子)), L). 行列式の値(_正方行列,_i,_n,_行列式の値) :- findsum(W,( 'n次正方行列の要素を列・行取り出す'(_n,_正方行列,_i,_j,_正方行列の要素), 余因子(_n,_正方行列,_i,_j,_余因子), W is _正方行列の要素 * _余因子), _行列式の値). 余因子(_n,_正方行列,_i,_j,_余因子) :- 'n次正方行列から、第i行と第j列を取り除いた正方行列(n-1次正方行列の行列式に、(-1)のi+j乗をかけたものを、Aの(i,j)余因子といい、Cijで表します。'(_n,_正方行列,_i,_j,_余因子). 'n次正方行列から、第i行と第j列を取り除いた正方行列(n-1次正方行列の行列式に、(-1)のi+j乗をかけたものを、Aの(i,j)余因子といい、Cijで表します。'(_n,_正方行列,_i,_j,_余因子) :- '正方行列から第i行と第j列を取り除く'(_正方行列,_i,_j,_n_1次正方行列), 'i,jから乗数を得る'(_i,_j,_乗数), 二つの対角要素の積を得る(_n,_n_1次正方行列,_右下がり対角要素の積,_右上がり対角要素の積), _余因子 is _乗数 * (_右下がり対角要素の積-_右上がり対角要素の積). '正方行列から第i行と第j列を取り除く'(_正方行列,_i,_j,_n_1次正方行列) :- '第何行を取り除く'(_正方行列,_i,_第i行が取り除かれた行列), 転置(_第i行が取り除かれた行列,_転置された第i行が取り除かれた行列), '第何行を取り除く'(_転置された第i行が取り除かれた行列,_j,_転置された第i行第j列が取り除かれた行列), 転置(_転置された第i行第j列が取り除かれた行列,_n_1次正方行列). '第何行を取り除く'(_正方行列,_第何行,_第i行が取り除かれた行列) :- append(L0,[L|R],_正方行列), length([_|L0],_第何行), append(L0,R,_第i行が取り除かれた行列). 二つの対角要素の積を得る(_n,_正方行列,_右下がり対角要素の積,_右上がり対角要素の積) :- 二つの対角要素を得る(_n,_正方行列,_右下がり対角要素ならび,_右上がり対角要素ならび), 対角要素の掛算(_右下がり対角要素ならび,_右下がり対角要素の積), 対角要素の掛算(_右上がり対角要素ならび,_右上がり対角要素の積). 二つの対角要素を得る(_n,_正方行列,_右下がり対角要素ならび,_右上がり対角要素ならび) :- 右下がり対角要素ならび(_n,_正方行列,_右下がり対角要素ならび), 右上がり対角要素ならび(_n,_正方行列,_右上がり対角要素ならび). 右下がり対角要素ならび(_n,_正方行列,_右下がり対角要素ならび) :- findall(V,( nth1(_nth1,_正方行列,L), nth1(_nth1,L,V)), _右下がり対角要素ならび). 右上がり対角要素ならび(_n,_正方行列,_右上がり対角要素ならび) :- findall(V,( append(_,[L|R],_正方行列), length([_|R],_nth1), nth1(_nth1,L,V)), _右上がり対角要素ならび),!. 'i,jから乗数を得る'(_i,_j,(-1)) :- 1 is (_i + _j) mod 2,!. 'i,jから乗数を得る'(_i,_j,1) :- 0 is (_i + _j) mod 2,!. 対角要素の掛算([],1). 対角要素の掛算([A|R],X) :- 対角要素の掛算(R,Y), X is A * Y. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/344 # # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # # 3)帰納を使い、最大公約数を求めよ。 最大公約数(M,N,_最大公約数) :- 'MがNで割り切れたら'(M,N), 'Nが最大公約数だ'(N,_最大公約数),!. 最大公約数(M,N,_最大公約数) :- 'MがNで割り切れなかったら、MをNで割った余りを除数としNを被除数として更に最大公約数を求める'(M,N,_最大公約数). 'MがNで割り切れなかったら、MをNで割った余りを除数としNを被除数として更に最大公約数を求める'(M,N,_最大公約数) :- 'MがNで割り切れなかったら'(M,N,_MをNで割った余り), 最大公約数(N,_MをNで割った余り,_最大公約数). 'MがNで割り切れたら'(M,N) :- 0 is M mod N. 'MがNで割り切れなかったら'(M,N,_MをNで割った余り) :- _MをNで割った余り is M mod N, \+(_MをNで割った余り = 0). 'Nが最大公約数だ'(N,_最大公約数) :- N = _最大公約数. % % 何故、これで解けているのか。この点が匂ってこない。 % そういう意味で60点くらいの出来具合。 % % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/344 # # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # # 3)帰納を使い、最大公約数を求めよ。 最大公約数(M,N,_最大公約数) :- 'MがNで割り切れたら'(M,N), 'Nが最大公約数だ'(N,_最大公約数),!. 最大公約数(M,N,X) :- 'MをNで割った余りを除数としNを被除数として更に最大公約数を求める'(M,N,X). 'MをNで割った余りを除数としNを被除数として更に最大公約数を求める'(M,N,_最大公約数) :- _MをNで割った余り is M mod N, 最大公約数(N,_MをNで割った余り,_最大公約数). 'MがNで割り切れたら'(M,N) :- 0 is M mod N. 'Nが最大公約数だ'(N,_最大公約数) :- _最大公約数 = N. % % 何故、これで解けているのか。この点が匂ってこない。 % そういう意味で60点くらいの出来具合。 % % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/344 # # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # 1)帰納を使い、フィボナッチ数を表示するプログラミングを作れ。 # 例 0,1,1,2,3,5,8,13... # # 2)帰納を使い、インプットした数字nが偶数の場合は、 # 1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。 # ただし、nが奇数の場合は、-1と表示させる。 # # 3)帰納を使い、最大公約数を求めよ。 最大公約数(A,B,B) :- 'AがBで割り切れる'(A,B),!. 最大公約数(A,B,X) :- 'AをBで割った余りを除数としBを被除数とする'(A,B,X). 'AをBで割った余りを除数としBを被除数とする'(A,B,X) :- _余り is A mod B, 最大公約数(B,_余り,X). 'AがBで割り切れる'(A,B) :- 0 is A mod B. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/344 # # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # 1)帰納を使い、フィボナッチ数を表示するプログラミングを作れ。 # 例 0,1,1,2,3,5,8,13... # # 2)帰納を使い、インプットした数字nが偶数の場合は、 # 1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。 # ただし、nが奇数の場合は、-1と表示させる。 # # 3)帰納を使い、最大公約数を求めよ。 '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。ただし、nが偶数の場合は、-1と表示させる。'(_n,-1) :- 偶数(_n). '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。ただし、nが偶数の場合は、-1と表示させる。'(_n,_答え) :- 奇数(_n), '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを'(1,_n,1,_答え). '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(_n,_n,_答え,_答え) :- 表示する('%t\n',[_答え]),!. '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(N,_n,S1,_答え) :- 'N_1に2を加えてN_2とした上で、N_2とM_1を掛けてM_2とする'(N_1,M_1,N_2,M_2), '帰納を使い、インプットした数字nが奇数の場合は、1*3*5*7...n の計算式を行いその答えを表示する'(N_2,_n,S2,_答え). 'N_1に2を加えてN_2とした上で、N_2とM_1を掛けてM_2とする'(N_1,M_1,N_2,M_2) :- N_2 is N_1 + 2, M_2 is M_1 * N_2. 偶数(_偶数) :- 0 is _偶数 mod 2. 奇数(_奇数) :- 1 is _奇数 mod 2. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/344 # # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # 1)帰納を使い、フィボナッチ数を表示するプログラミングを作れ。 # 例 0,1,1,2,3,5,8,13... # # 2)帰納を使い、インプットした数字nが偶数の場合は、 # 1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。 # ただし、nが奇数の場合は、-1と表示させる。 # # 3)帰納を使い、最大公約数を求めよ。 '帰納を使い、フィボナッチ数を表示する'(X) :- '帰納を使い、フィボナッチ数を表示する'(1,X). writef('%t\n',[X]). '帰納を使い、フィボナッチ数を表示する'(N,X) :- '帰納を使い、フィボナッチ数を得る'(N,X). '帰納を使い、フィボナッチ数を表示する'(N,X) :- N_2 is N + 1, '帰納を使い、フィボナッチ数を表示する'(N_2,X). '帰納を使い、フィボナッチ数を表示する'(X) :- X_2 is X + 1, 帰納を使い、フィボナッチ数を得る(X_2). '帰納を使い、フィボナッチ数を得る'(0,0). '帰納を使い、フィボナッチ数を得る'(1,0). '帰納を使い、フィボナッチ数を得る'(2,1). '帰納を使い、フィボナッチ数を得る'(N,X) :- N > 2, N_1 is N - 1, N_2 is N - 2, '帰納を使い、フィボナッチ数を得る'(N_1,X_1), '帰納を使い、フィボナッチ数を得る'(N_2,X_2), X is X_1 + X_2,!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/344 # # [1] 授業単元: プログラミング基礎 # [2] 問題文(含コード&リンク): 3問 http://ime.nu/ideone.com/kXOZ8 # # 1)帰納を使い、フィボナッチ数を表示するプログラミングを作れ。 # 例 0,1,1,2,3,5,8,13... # # 2)帰納を使い、インプットした数字nが偶数の場合は、 # 1*3*5*7...n の計算式を行いその答えを表示するプログラミングを作れ。 # ただし、nが奇数の場合は、-1と表示させる。 # # 3)帰納を使い、最大公約数を求めよ。 帰納を使い、フィボナッチ数を表示するプログラミングを作れ(X) :- 帰納を使い、フィボナッチ数を表示するプログラミングを作れ(0,1,X). 帰納を使い、フィボナッチ数を表示するプログラミングを作れ(M,N,M). 帰納を使い、フィボナッチ数を表示するプログラミングを作れ(M,N,X) :- M2 is M + N, 帰納を使い、フィボナッチ数を表示するプログラミングを作れ(N,M2,X). % 以下のサイトは # # 行列の掛算 # 行列の掛算(L1,L2,X) :- 転置(L2,L4), 行列の掛算_1(L1,L4,X). 行列の掛算_1([],_,[]) :-!. 行列の掛算_1([A|R1],L,[S1|R3]) :- 行列の掛算_2(A,L,S1), 行列の掛算_1(R1,L,R3). 行列の掛算_2(_,[],[]) :-!. 行列の掛算_2(A,[B|R2],[C|R3]) :- 行列の掛算_3(A,B,C), 行列の掛算_2(A,R2,R3). 行列の掛算_3([],[],0) :-!. 行列の掛算_3([A|R1],[B|R2],S) :- 分数を含む掛算(A,B,S1), 行列の掛算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 分数を含む掛算(A1 / A2,B1 / B2,C) :- S1 is A1 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む掛算(A1 / A2,B,C) :- S1 is A1 * B, 約分(S1 / A2,C),!. 分数を含む掛算(A,B1 / B2,C) :- S1 is B1 * A, 約分(S1 / B2,C),!. 分数を含む掛算(A,B,C) :- C is A * B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは https://sites.google.com/site/prologsite/prolog-problems/2 # 2つの正の整数が互いに素であるかどうかを判断します。 # それらの最大公約数が1に等しい場合、2つの数字が互いに素である。 # '2つの正の整数が互いに素であるかどうかを判断します'(M,N) :- 'それらの最大公約数が1に等しい場合、2つの数字が互いに素である'(M,N). 'それらの最大公約数が1に等しい場合、2つの数字が互いに素である'(M,N) :- 最大公約数(M,N,1). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/340 # # 1C言語学習 # 2 2つの整数を入力して、その2つの最大公約数を求めよ # 3環境 は Linux gcc C言語です # 4期限は 明日までです # 5 配列には入っていません # ならったところまでの総合問題です # 初心者なので、簡略化しないで頂きたいです お願いします # # '2つの整数を入力して、その2つの最大公約数を求める' :- '2つの整数を入力して'(_整数_1,_整数_2), 'その2つの最大公約数を求める'(_整数_1,_整数_2,_最大公約数), 最大公約数を表示する(_整数_1,_整数_2,_最大公約数). '2つの整数を入力して'(_整数_1,_整数_2) :- 整数を入力して(_整数_1), 整数を入力して(_整数_2). 整数を入力して(_整数) :- write('整数を入力してください : '), get_line(Line), 整数入力診断(Line,_整数),!. 整数を入力して(_整数) :- 整数を入力して(_整数). 整数入力診断(Line,_整数) :- atom_to_term(Line,_整数,_), integer(_整数),!. 整数入力診断(Line,_整数) :- writef('入力された %t からは整数が得られません。再入力をお願いします。\n',[Line]), fail. 'その2つの最大公約数を求める'(_整数,_整数,_整数) :- !. 'その2つの最大公約数を求める'(_整数_1,_整数_2,_最大公約数) :- _整数_1 > _整数_2, 小さい整数を初期値として下降しながら2整数の公約数を捜す(_整数_2,_整数_1,_整数_2,_最大公約数),!. 'その2つの最大公約数を求める'(_整数_1,_整数_2,_最大公約数) :- _整数_1 < _整数_2, 小さい整数を初期値として下降しながら2整数の公約数を捜す(_整数_1,_整数_1,_整数_2,_最大公約数),!. 小さい整数を初期値として下降しながら2整数の公約数を捜す(_初期値,_整数_1,_整数_2,_最大公約数) :- for(_初期値,_最大公約数,1), 0 is _整数_1 mod _最大公約数, 0 is _整数_2 mod _最大公約数,!. 最大公約数を表示する(_整数_1,_整数_2,_最大公約数) :- writef('%t と %t の最大公約数は %t\n',[_整数_1,_整数_2,_最大公約数]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/340 # # 1C言語学習 # 2 2つの整数を入力して、その2つの最大公約数を求めよ # 3環境 は Linux gcc C言語です # 4期限は 明日までです # 5 配列には入っていません # ならったところまでの総合問題です # 初心者なので、簡略化しないで頂きたいです お願いします # # '2つの整数を入力して、その2つの最大公約数を求める' :- '2つの整数を入力して'(_整数_1,_整数_2), 'その2つの最大公約数を求める'(_整数_1,_整数_2,_最大公約数), 最大公約数を表示する(_整数_1,_整数_2,_最大公約数). '2つの整数を入力して'(_整数_1,_整数_2) :- 整数を入力して(_整数_1), 整数を入力して(_整数_2). 整数を入力して(_整数) :- write('整数を入力してください : '), get_line(Line), 整数入力診断(Line,_整数),!. 整数を入力して(_整数) :- 整数を入力して(_整数). 整数入力診断(Line,_整数) :- atom_to_term(Line,_整数,_), integer(_整数),!. 整数入力診断(Line,_整数) :- writef('入力された %t からは整数が得られません。再入力をお願いします。\n',[Line]), fail. 'その2つの最大公約数を求める'(_整数_1,_整数_2,_最大公約数) :- 最大公約数をユークリッドの互除法で求める(_整数_1,_整数_2,_最大公約数). 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 最大公約数を表示する(_整数_1,_整数_2,_最大公約数) :- writef('%t と %t の最大公約数は %t\n',[_整数_1,_整数_2,_最大公約数]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1308749241/797 # # (1)c言語(2)問題:最大公約数を求める関数を条件とベースに基づいて作成お願いします # 条件 # 1:関数gcdの呼ばれた回数を記録  2:呼ばれた回数と、その時の引数a,bの値を表示 # 実行結果:2つの整数を入力してください # 数値1:64 # 数値2:120 # 1回目の関数の呼び出し:a=64 ,b=120 # 2回目の関数の呼び出し:a=120 ,b=64 # 3回目の関数の呼び出し:a=64 ,b=56 # 4回目の関数の呼び出し:a=56 ,b=8 # 最大公約数は8です # ベース # #include <stdio.h>//ユークリッドのアルゴリズムで最大公約数gcdを求める # int gcd(int fa , int fb); //プロトタイプ宣言 # int main(){ # int a,b,g; # printf("2つの数値を入力してください。\n"); # printf("数値1:"); # scanf("%d",&a); # printf("数値2:"); # scanf("%d",&b); # g = gcd(a,b); # printf("最大公約数は%dです\n",g); # } # int gcd(int fa, int fb){ # int r,ret; # r = fa % fb ; # if(r > 0){ //不成立時が終了条件 # ret = gcd(fb,r); //再帰呼び出し # }else{ret = fb ; # }return ret; # } # # 実行結果:2つの整数を入力してください # 数値1:64 # 数値2:120 # 1回目の関数の呼び出し:a=64 ,b=120 # 2回目の関数の呼び出し:a=120 ,b=64 # 3回目の関数の呼び出し:a=64 ,b=56 # 4回目の関数の呼び出し:a=56 ,b=8 # 最大公約数は8です 最大公約数を求める :- '2つの整数を入力'(_整数1,_整数2), 最大公約数をユークリッドの互除法で求める(_a,_b,X), writef('最大公約数は%tです\n',[X]). '2つの整数を入力'(_整数1,_整数2) :- write('2つの整数をカンマ区切りで入力してください '), 数値1の入力(_整数1), 数値2の入力(_整数2). 数値1の入力(_整数1) :- get_line(Line), 整数入力診断(Line,_整数1),!. 数値1の入力(_整数1) :- 数値1の入力(_整数1). 数値2の入力(_整数2) :- get_line(Line), 整数入力診断(Line,_整数2),!. 数値2の入力(_整数2) :- 数値2の入力(_整数2). 整数入力診断(Line,_整数) :- atom_to_term(Line,_整数,_), integer(_整数),!. 整数入力診断(Line,_整数) :- writef('入力された%tからは整数が得られません。再入力をお願いします。\n',[Line]), fail. 最大公約数をユークリッドの互除法で求める(_a,_b,X) :- 最大公約数をユークリッドの互除法で求める(_a,_b,X,1,Count). 最大公約数をユークリッドの互除法で求める(_a,_b,_b,Count,Count) :- 0 is _a mod _b, writef(%t回目の呼び出し a=%t,b=%t\n,[Count,_a,_b]),!. 最大公約数をユークリッドの互除法で求める(_a,_b,X,Count1,Count) :- Mod is _a mod _b, writef(%t回目の呼び出し a=%t,b=%t\n,[Count1,_a,_b]), Count2 is Count + 1, 最大公約数をユークリッドの互除法で求める(_b,Mod,X,Count2,Count) . % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1307166756/386 # # [1] 授業単元:課題 # [2] 問題文: # 読み込んだ2つの正整数の最大公約数を出力するプログラムを作成せよ.ただし,以下の関数 gcd() を再帰を用いて定義し,使用すること. # 書式 # int gcd(int m, int n); # 返り値 # 正整数m, nの最大公約数 # 実行結果1 # 2正整数 > 8 12 # 4 # 実行結果2 # 2正整数 > 81 64 # 1 # 読み込んだ2つの正整数の最大公約数を出力する :- 読み込んだ2つの正整数(_1つ目の正整数,_2つ目の正整数), 最大公約数(_1つ目の正整数,_2つ目の正整数,_最大公約数), 出力する(_最大公約数). 読み込んだ2つの正整数(_1つ目の正整数,_2つ目の正整数) :- write('2つの正の整数を空白で区切り一行で入力してください : '), get_line(Line), 2つの正整数を読み込み診断(Line,_1つめの正整数,_2つ目の正整数),!. 読み込んだ2つの正整数(_1つ目の正整数,_2つ目の正整数) :- 読み込んだ2つの正整数(_1つ目の正整数,_2つ目の正整数). '2つの正整数を読み込み診断'(Line,_1つめの正整数,_2つ目の正整数) :- split(Line,[' '],[_1つ目の正整数,_2つ目の正整数]), integer(_1つ目の正整数), integer(_2つ目の正整数), _1つ目の正整数 > 0, _2つ目の正整数 > 0,!. '2つの正整数を読み込み診断'(Line,_,_) :- writef('入力された %t から2つの正整数を得ることができません。再入力をお願いします。\n',[Line]), fail. 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 出力する(_最大公約数) :- writef('%t\n',[_最大公約数]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1301553333/83 # # [1] 授業単元:整数演算 # [2] 問題文(含コード&リンク):1個以上32個以下の正整数の最大・最小・最小公倍数・最大公約数を求めよ # 1個以上32個以下の正整数の最大・最小・最小公倍数・最大公約数を求めよ(_N個,_整数ならび,_最大,_最小,_最小公倍数,_最大公約数) :- _N個 >= 1,_N個 =< 32, 'N個の正の整数を得る'(_N個,_整数ならび), _整数ならび = [_最初の整数|_残りならび], 最大値と最小値を同時に取得する(_残りならび,_最初の整数,_最初の整数,_最大値,_最小値), 最大公約数(_整数ならび,_最大公約数), 最小公倍数(_整数ならび,_最小公倍数). 'N個の正の整数を得る'(_N個,_整数ならび) :- length(L,_N個), _整数ならび = L, findall(_正の整数,( append(_,[_正の整数|R],L), length([_正の整数|R],_残り個数), 正の整数を得る(_残り個数,_正の整数)), L). 正の整数を得る(_残り個数,_正の整数) :- write_formatted('正の整数を入力してください(残り%t個) : ',[_残り個数]), get_line(Line), 正の整数診断(Line,_正の整数),!. 正の整数を得る(_残り個数,_正の整数) :- 正の整数を得る(_残り個数,_正の整数). 正の整数診断(Line,_正の整数) :- atom_to_term(Line,_正の整数,_), integer(_正の整数), _正の整数 > 0,!. 正の整数診断(Line,_正の整数) :- write_formatted('入力された %t から正の整数は得られません。再入力をお願いします。',[Line]), fail. 最大公約数([N1|R],_最大公約数) :- 最大公約数の三(R,N1,_最大公約数). 最大公約数の三([],_最大公約数,_最大公約数). 最大公約数の三([N|R],_最大公約数_1,_最大公約数) :- 最大公約数(N,_最大公約数_1,_最大公約数_2), 最大公約数の三(R,_最大公約数_2,_最大公約数). 最小公倍数([N1|R],_最小公倍数) :- 最小公倍数の三(R,N1,_最小公倍数). 最小公倍数の三([],_最小公倍数,_最小公倍数). 最小公倍数の三([N|R],_最小公倍数_1,_最小公倍数) :- 最小公倍数(N,_最小公倍数_1,_最小公倍数_2), 最小公倍数の三(R,_最小公倍数_2,_最小公倍数). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最大値と最小値を同時に取得する([],_最大値,_最小値,_最大値,_最小値) :- 最大値と最小値を同時に取得する([N|R],_最大値_1,_最小値_1,_最大値,_最小値) :- N > _最大値, 最大値と最小値を同時に取得する(R,N,_最小値_1,_最大値,_最小値),!. 最大値と最小値を同時に取得する([N|R],_最大値_1,_最小値_1,_最大値,_最小値) :- N < _最小値, 最大値と最小値を同時に取得する(R,_最大値_1,N,_最大値,_最小値),!. 最大値と最小値を同時に取得する([N|R],_最大値_1,_最小値_1,_最大値,_最小値) :- 最大値と最小値を同時に取得する(R,_最大値_1,_最小値_1,_最大値,_最小値),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1294061094/89 # # [1] 授業単元:Cプログラミング入門2 # [2] 問題文(含コード&リンク): # 複数の自然数に対する最小公倍数を求めるプログラムを作成せよ。 # 最小公倍数を求める関数を作成する必要あり # int型のオーバーフローは考慮しないで良い。 # 関数名はlcm # int lcm(int num0,int num1) # num1 num2は入力値 # lcmの戻り値は最小公倍数 # 入力に関して:キーボードから入力する整数の個数を入力し(最大10)改行する次に指定した数の整数を入力するように作る # 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最大公約数をユークリッドの互除法で求める(A,B,B) :- 0 is A mod B,!. 最大公約数をユークリッドの互除法で求める(A,B,C) :- Mod is A mod B, 最大公約数をユークリッドの互除法で求める(B,Mod,C). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1288531658/263 # # [1] 授業単元:プログラミング # [2] 問題文(含コード&リンク): # スタックを利用して、与えられたnに関するFarey数列の要素数を求めるプログラムを完成させよ。 # #include <stdio.h> # #include <stdlib.h> # #define MAX 100000 # main(){ # int count,n,top,x[MAX],y[MAX],w; # scanf("%d",&n); # x[0]=0; y[0]=1; # x[1]=1; y[1]=1; # count=2; # top=2; # while(top>1){ # # # # } # printf("%dに関するFarey数の個数:%d\n",n,count);} # 与えられたnに関するFarey数列の要素数を求める(_n,_要素数) :- findall(M,for(1,M,_n),L), count((組み合わせ(L,2,[A,B]), 最大公約数(A,B,1)),_1を除く要素数), _要素数 is 1 + _1を除く要素数. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1286978599/447 # # [1] 授業単元:C言語基礎実習 # [2] 問題文(含コード&リンク):w x y zを入力して # w/x+y/zを計算するプログラムを作成せよ。 # ただし例のように帯分数かつ、分母を約分して分数表示させること。 # 入力 # w = 5 # x = 3 # y = 2 # z = 4 # # 表示 #  5   2    1 # ---- + ---- = 2---- #  3   4    6 # # 計算した結果が整数になった場合は分数の部分は # 表示しないということでお願いします。 # 分数の計算と表示 :- 分数を2項読み込む([一,分子,一,分母,二,分子,二,分母],[_分子_1,_分母_1,_分子_2,_分母_2]), _答え仮分数分子 is _分子_1 * _分母_2 + _分子_2 * _分母_1, _答え仮分数分母 is _分母_1 * _分母_2, 最大公約数(_答え仮分数分子,_答え仮分数分母,_最大公約数), _答え仮分数分子_2 is _答え仮分数分子 // _最大公約数, _答え仮分数分母_2 is _答え仮分数分母 // _最大公約数, 帯分数(_答え仮分数分子_2,_答え仮分数分母_2,_答え整数部分, _答え分子,_答え分母), 分数計算表示(_分子_1,_分子_2,_答え分子,_答え整数部分,_分母_1,_分母_2,_答え分母). 分数を2項読み込む([],[]). 分数を2項読み込む([A,B|R1],[C|R2]) :- write_formatted('第%t項の%tを整数で入力してください : ',[A,B]), get_integer(C), 分数を2項読み込む(R1,R2). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, \+(_答えの分子=0), write(' %2d %2d %2d \n',[_分子_1,_分子_2,_答え分子]), write('---- + ---- =%2d---- \n',[_整数部分]), write(' %2d %2d %2d \n',[_分母_1,_分母_2,_答え分母]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, 答えの分子=0, write(' %2d %2d\n',[_分子_1,_分子_2]), write('---- + ---- = %2d \n',[_整数部分]), write(' %2d %2d\n',[_分母_1,_分母_2]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 = 0, write(' %2d %2d %2d \n',[_分子_1,_分子_2,_答え分子]]), write('---- + ---- = ---- \n'), write(' %2d %2d %2d \n',[_分母_1,_分母_2,_答え分子]]). 帯分数(_仮分数分子,_仮分数分母,_帯分数整数部分, _帯分数分子,_帯分数分母) :- _帯分数整数部分 is _仮分数分子 // _仮分数分母, _帯分数分子 is _仮分数分子 mod _仮分数分母. _帯分数分母 = _仮分数分母. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1263824755/420 # # [1] 授業単元:プログラミング実践 # [2] 問題文 # アフィン変換のプログラムを作成し、下の図の真ん中を座標の中心にして90°回転した結果を出力せよ。 # (図)affin.txt # 00000 # 00000 # 11111 # 00000 # 00000 # # アフィン変換により原点を中心に90度回転(X1,X2,Y1,Y2,_行列1,_アフィン変換された行列) :- length(_行列1,Len1), nth1(1,_行列1,_行), length(_行,Len2), findall([XX2,YY2,V],アフィン変換により原点を中心に90度回転(X1,X2,Y1,Y2,_行列1,XX2,YY2,V),L1), アフィン変換_2(1,Len1,1,Len2,L1,_アフィン変換された行列). アフィン変換により原点を中心に90度回転(X1,X2,Y1,Y2,_行列1,XX2,YY2,V) :- between(X1,X2,X), between(Y1,Y2,Y), 行列の掛算([[0,1,0],[-1,0,0]],[[X],[Y],[1]],[[X3],[Y3]]), XX is X + 3, YY is Y + 3, XX2 is X3 + 3, YY2 is Y3 + 3, nth1(YY,_行列1,_行1), nth1(XX,_行1,V). アフィン変換_2(M,Len1,_,_,_,[]) :- M > Len1,!. アフィン変換_2(M,Len1,N,Len2,L,[[]|R2]) :- N > Len2, M2 is M + 1, アフィン変換_2(M2,Len1,N,1,L,R2),!. アフィン変換_2(M,Len1,N,Len2,L,[[V|R1]|R2]) :- N =< Len2, member([M,N,V],L), N2 is N + 1, アフィン変換_2(M,Len1,N2,Len2,L,[R1|R2]),!. アフィン変換_2(M,Len1,N,Len2,L,[[0|R1]|R2]) :- N =< Len2, \+(member([M,N,V],L)), N2 is N + 1, アフィン変換_2(M,Len1,N2,Len2,L,[R1|R2]),!. 行列の掛算(L1,L2,X) :- 転置(L2,L4), 行列の掛算_1(L1,L4,X). 行列の掛算_1([],_,[]) :- !. 行列の掛算_1([A|R1],L,[S1|R3]) :- 行列の掛算_2(A,L,S1), 行列の掛算_1(R1,L,R3). 行列の掛算_2(_,[],[]) :- !. 行列の掛算_2(A,[B|R2],[C|R3]) :- 行列の掛算_3(A,B,C), 行列の掛算_2(A,R2,R3). 行列の掛算_3([],[],0) :- !. 行列の掛算_3([A|R1],[B|R2],S) :- 分数を含む掛算(A,B,S1), 行列の掛算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 分数を含む掛算(A1 / A2,B1 / B2,C) :- S1 is A1 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む掛算(A1 / A2,B,C) :- S1 is A1 * B, 約分(S1 / A2,C),!. 分数を含む掛算(A,B1 / B2,C) :- S1 is B1 * A, 約分(S1 / B2,C),!. 分数を含む掛算(A,B,C) :- C is A * B. 分数を含む加算(A,B,C) :- number(A), number(B), C is A + B,!. 分数を含む加算(A1 / B1,A2 / B2,C) :- A3 is A1 * B2 + A2 * B1, B3 is B1 * B2, 約分(A3 / B3,C),!. 分数を含む加算(A1 / B1,V,C) :- number(V), A2 is V * B1, C3 is A1 + A2, 約分(C3 / B1,C),!. 分数を含む加算(V,A2 / B2,C) :- number(V), A1 is V * B2, C3 is A1 + A2, 約分(C3 / B2,C),!. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子_1,_分母_1,_分子 / _分母) :- 分母が負数だったら分子分母ともに符号を反転する(_分子_1,_分母_1,_分子,_分母),!. 約分の二(_分子,_分母,_分子 / _分母). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4) . 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). ?- アフィン変換により原点を中心に90度回転(-2,2,-2,2,[[0,0,0,0,0],[0,0,0,0,0],[1,1,1,1,1],[0,0,0,0,0],[0,0,0,0,0]],L). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1274827528/599 # # 2つの自然数aとbの最大公約数gcd(a, b)を求め、それを出力するプログラムを作成せよ。 # なお、m = a % b としたとき、gcd(a, b) は m≠0 の場合 gcd(b, m) に等しく、 m=0 の場合 b に等しい。 # # # 2つの自然数aとbを入力させ、a 人から b 人を選ぶ組み合わせ comb(a, b)を求め、それを出力するプログラムを作成せよ。 # なお、comb(a, b) = comb( a-1, b) + comb( a-1, b-1) であり、 b==0 もしくは b==a のとき comb(a, b) = 1 である。 # # # 今週は2つありますが。。。よろしくお願いしますorz # # '2つの自然数aとbの最大公約数gcd(a, b)を求め、それを出力する' :- 催促付き整数入力('自然数aを入力してください : ',_a), 催促付き整数入力('自然数bを入力してください : ',_b), gcd(_a,_b,X), write_formatted('%tと%tの最大公約数は%tです\n',[_a,_b,X]). '2つの自然数aとbを入力させ、a 人から b 人を選ぶ組み合わせ comb(a, b)を求め、それを出力する' :- 催促付き整数入力('自然数aを入力してください : ',_a), 催促付き整数入力('自然数bを入力してください : ',_b), comb(_a,_b,X), write_formatted('%t人から%t人を選ぶ組み合わせは%t通りです\n',[_a,_b,X]). gcd(_a,_b,X) :- M is _a mod _b, \+(M = 0), gcd(_b,M,X),!. gcd(_a,_b,_b). comb(N,N,1) :- !. comb(_,0,1) :- !. comb(_a,_b,X) :- _a_1 is _a - 1, _b_1 is _b - 1, comb(_a_1,_b,Y), comb(_a_1,_b_1,Z), X is Y + Z. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1274827528/479 # # [1] 授業単元:プログラミング演習 # [2] 問題文(含コード&リンク):オイラーの定理の仮証明 # # 互いに素なnとaについてオイラーの定理が成り立つか確かめる。 # とりあえずnは1以上5以下の数とし、aは1以上n以下とする。 # http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10654.txt 互いに素なnとaについてオイラーの定理が成り立つか確かめる :- findall(_n,( for(1,_n,5), 互いに素なnとaについてオイラーの定理が成り立つか確かめる(_n)), L), length(L,5). 互いに素なnとaについてオイラーの定理が成り立つか確かめる(_n) :- findall(Mod,( 互いに素なnとa(_n,_a), オイラー関数(_n,Z), Mod is (_a ^ Z) mod _n), L), all(L,1),!. 互いに素なnとa(_n,_a) :- findall(M,for(1,M,_n-1),L), 組み合わせ(L,2,[_n,_a]), 最大公約数(_n,_a,1). オイラー関数(_n,Z) :- count((for(1,M,_n-1),\+(0 is _n mod M)),Z). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1274827528/424 # # 【質問テンプレ】 # [1] 授業単元:C言語課題 # [2] 問題文(含コード&リンク):2つの正の整数(aとb)の最大公約数をユークリッドの互除法を用いて表示するプログラムを作成せよ。ただし、0<b≦a≦32767とする。 #                ≪ユークリッドの互除法≫ #                ユークリッドの互除法による最大公約数(GREATEST COMMON DIVISOR:GCD)は、次のように求める。 #                2数(aとb)の中で大きい値をl、小さい値をmとする。 #                ■譴鬘蹐燃笋蝓△△泙蠅鬘鬚箸垢襦 #                       r=0ならば、mが最大公約数となる。 #                       r≠0(0<r<m)ならばl←m、m←r として再び△僚萢を行う。 # ユークリッドの互除法による最大公約数(N1,N2,X) :-     length(L1,N1),     length(L2,N2),     ユークリッドの互除法とならび演算による最大公約数(L1,L2,L),     length(L,X). ユークリッドの互除法とならび演算による最大公約数(L1,L2,L) :-     append(_,L2,L1),     ならび剰余算(L1,L2,R),     ユークリッドの互除法とならび演算による最大公約数(L1,L2,R,L),!.     ユークリッドの互除法とならび演算による最大公約数(L1,L2,L) :-     append(_,L1,L2),     ユークリッドの互除法とならび演算による最大公約数(L2,L1,L). ユークリッドの互除法とならび演算による最大公約数(_,L2,[],L2) :- !. ユークリッドの互除法とならび演算による最大公約数(L1,L2,R,L) :- ユークリッドの互除法とならび演算による最大公約数(L2,R,L). ならび割り算(L1,L2,Div,Mod) :- ならび割り算(L1,L2,[],Div,Mod). ならび割り算(L1,L2,Div,Div,L1) :- append([_|_],L1,L2),!. ならび割り算(L1,L2,L4,Div,Mod) :- append(L2,L3,L1), ならび割り算(L3,L2,[_|L4],Div,Mod). ならび剰余算(L1,L2,L1) :- append([_|_],L1,L2). ならび剰余算(L1,L2,L) :- append(L2,L3,L1),ならび剰余算(L3,L2,L). /* ならび割り算(L1,L2,X) :- ならび割り算(L1,L2,[],X). ならび割り算(L1,L2,L,L) :- append([_|_],L1,L2),!. ならび割り算(L1,L2,L4,L) :- append(L2,L3,L1),ならび割り算(L3,L2,[_|L4],L). */ % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1269438098/457 # # [2] 問題文(含コード&リンク): # ・ユークリッドの互除法の拡張アルゴリズム # 入力 f1,f2 (f1>f2>0でよい)に対して、 # s*f1+t*f2=gcd(f1,f2)となる、s,tを求めよ。 # ただし、s,tは整数、gcd(f1,f2)はf1とf2の最大公約数である。また 配列を使わずに再現すること。 # gcd_equal(_s * _f1 + _t * _f2 = _gcd) :- _f1 >= _f2, 最大公約数をユークリッドの互除法で求める(_f1,_f2,_gcd), U is (_f1-_f2)) // _gcd, gcd_equal(1,U,_s,_f1,_t,_f2,_gcd). gcd_equal(_s * _f1 + _t * _f2 = _gcd) :- _f2 > _f1, 最大公約数をユークリッドの互除法で求める(_f2,_f1,_gcd), U is (_f2-_f1) // _gcd, gcd_equal(1,U,_t,_f2,_s,_f1,_gcd). gcd_equal(N,0,_s,_f1,_t,_f1,_f1) :- gcd_equal(N,1, _s ,_f1,_t,_f1,_f1). gcd_equal(N,U,_s,_f1,_t,_f2,_gcd) :- U2 is U * N, 0 is (U2 * _f2 + _gcd) mod _f1, _t is U2 * (-1), _s is (U2 * _f2 + _gcd) // _f1. gcd_equal(N,U,_s,_f1,_t,_f2,_gcd) :- U2 is U * N, 0 is (U2 * _f2 - _gcd) mod _f1, _s is (U2 * _f2 - _gcd) // _f1 * (-1), _t is U2. gcd_equal(N,U,_s,_f1,_t,_f2,_gcd) :- U2 is U * N, 0 is (U2 * _f1 + _gcd) mod _f2, _s is U2 * (-1), _t is (U2 * _f1 + _gcd) // _f2. gcd_equal(N,U,_s,_f1,_t,_f2,_gcd) :- U2 is U * N, 0 is (U2 * _f1 - _gcd) mod _f2, _t is (U2 * _f1 - _gcd) // _f2 * (-1), _s is U2. gcd_equal(N,U,_s,_f1,_t,_f2,_gcd) :- N2 is N + 1, gcd_equal(N2,U,_s,_f1,_t,_f2,_gcd). 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1250204272/381 # # [1] 授業単元: 情報工学:数理I # [2] 問題文(含コード&リンク): ガウス行列を既約ガウス行列に変形する関数を定義せよ % *** user: '既約ガウス行列に変形' / 5 *** '既約ガウス行列に変形'(N,0,_,_行列,_行列) :- !. '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列1,_行列). '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), /* '行基本変形3の適用'(A,B,M,N,_行列1,_行列2), */ '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列2,_行列). % *** user: '既約ガウス行列に変形' / 3 *** '既約ガウス行列に変形'(1,_既約ガウス行列,_既約ガウス行列) :- !. '既約ガウス行列に変形'(N,_ガウス行列,_既約ガウス行列) :- list_nth(N,_ガウス行列,L0), '最初に現れる0ではない要素・位置'(1,L0,_列,Y), M is N - 1, list_nth(M,_ガウス行列,L), '既約ガウス行列に変形'(_列,M,Y,_ガウス行列,G1), N2 is N - 1, '既約ガウス行列に変形'(N2,G1,_既約ガウス行列),!. % *** user: '既約ガウス行列に変形' / 2 *** '既約ガウス行列に変形'(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), '既約ガウス行列に変形'(Len,_ガウス行列,G1), '既約ガウス行列に変形の二'(1,Len,G1,_既約ガウス行列). 既約ガウス行列に変形の二(N,Len,_既約ガウス行列,_既約ガウス行列) :- N > Len,!. 既約ガウス行列に変形の二(N,Len,G,_既約ガウス行列) :- list_nth(N,G,_行), list_nth(N,_行,A), 行基本変形(1 / A # N,G,G1), N2 is N + 1, 既約ガウス行列に変形の二(N2,Len,G1,_既約ガウス行列). % *** user: 行基本変形3の適用 / 7 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形3の適用 / 6 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: '行基本変形' / 5 *** '行基本変形'(*,_乗数,_行目,_行列,X) :- '行基本変形'(*,_乗数,1,_行目,_行列,X) . % *** user: '行基本変形' / 3 *** '行基本変形'(_行列式,_行列,X) :- atom(_行列式), \+(_行列式 = []), & '行列式変換' # [2|pro], '行列式述語変換'(_行列式,P), '行基本変形'(P,_行列,X),!. '行基本変形'([],_行列,[]) :-!. '行基本変形'([N|R1],_行列,[L|R2]) :- !, list_nth(N,_行列,L), '行基本変形'(R1,_行列,R2),!. '行基本変形'(# _行目1 # _行目2,_行列,X) :- list_nth(_行目1,_行列,_行1), list_nth(_行目2,_行列,_行2), 'ならびの位置指定置換'(_行目2,_行1,_行列,_行列1), 'ならびの位置指定置換'(_行目1,_行2,_行列1,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 >= 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 < 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 >= 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 < 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 + _乗数2 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行1) , U is A * _乗数1),_乗算された行1), findall(W,(member(B,_行2) , W is B * _乗数2),_乗算された行2), '型推論加算'([_乗算された行1,_乗算された行2],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 + _乗数 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数),_乗算された行), '型推論加算'([_乗算された行,_行1],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 - _乗数 # _行目2,_行列,X) :- !, _乗数2 is -1 * _乗数, '行基本変形'(# _行目1 + _乗数2 * _行目2,_行列,X),!. '行基本変形'(# _行目1 + _乗数 / _除数 * _行目2,_行列,X) :- integer(_除数), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 // _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 + _乗数 / _除数 # _行目2,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 / _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 - _乗数 / _除数 # _行目2,_行列,X) :- !, _除数2 is -1 * _除数, '行基本変形'(# _行目1 + _乗数 / _除数2 * _行目2,_行列,X),!. '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- integer(_除数), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 // _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 / _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. '行基本変形'(_乗数 # _行目,_行列,X) :- !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. % *** user: 行基本変形 / 5 *** 行基本変形(*,_乗数,_行目,_行列,X) :- 行基本変形(*,_乗数,1,_行目,_行列,X). % *** user: 行基本変形 / 6 *** 行基本変形(*,_乗数,_行目,_行目,[_行1|R1],[_行2|R1]) :- findall(X,(member(A,_行1) , X is A * _乗数),_行2) . 行基本変形(*,_乗数,M,_行目,[_行|R1],[_行|R2]) :- M2 is M + 1, 行基本変形(*,_乗数,M2,_行目,R1,R2). % *** user: 正方行列の行列式の値 / 2 *** 正方行列の行列式の値(_正方行列,_行列式の値) :- ガウス行列に変形(_正方行列,X,Y), '行列式|C|の値'(X,Z1), ならびの積(Y,Z2), _行列式の値 is Z1 // Z2. % *** user: ならびの積 / 2 *** ならびの積([A],A) :- !. ならびの積([A|R],X) :- ならびの積(R,Y), X is A * Y. % *** user: '行列式|C|の値' / 2 *** '行列式|C|の値'(_行列,_値) :- length(_行列,Len), findall(U,(for(1,N,Len) , list_nth(N,_行列,_行) , list_nth(N,_行,U)),L), ならびの積(L,_値). 要素がゼロ以外に出会うまで([A|R],[],[A|R]) :- \+((A = 0;A=0.0)),!. 要素がゼロ以外に出会うまで([0|R],[0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 要素がゼロ以外に出会うまで([0.0|R],[0.0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 最初に現れる0ではない要素・位置(Nth,[X|_],Nth,X) :- \+((X = 0;X=0.0)),!. 最初に現れる0ではない要素・位置(Mth,[0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . 最初に現れる0ではない要素・位置(Mth,[0.0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . % *** user: ならびの位置指定置換 / 4 *** ならびの位置指定置換(1,A,[_|R],[A|R]) :- !. ならびの位置指定置換(N,A,[B|R1],[B|R2]) :- N1 is N - 1, ならびの位置指定置換(N1,A,R1,R2) . 最小公倍数(N1 * A,B,C) :- integer(B), 最小公倍数(A,B,C), N1 is C // A,!. 最小公倍数(A,N2 * B,C) :- integer(A), 最小公倍数(A,B,C), N2 is C // B,!. 最小公倍数(N1 * A,N2 * B,C) :- 最小公倍数(A,B,C), N1 is C // A, N2 is C // B,!. 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最小公倍数([N1 * A|R],X) :- findall(U,member(_ * U,[N1 * A|R]),L1), 最小公倍数(L1,X), 最小公倍数_2([N1 * A|R],X),!. 最小公倍数([A,B],X) :- 最小公倍数(A,B,X),!. 最小公倍数([A|R],X) :- 最小公倍数(R,B), 最小公倍数(A,B,X),!. 最小公倍数_2([],_) :- !. 最小公倍数_2([N * A|R],Y) :- N is Y // A, 最小公倍数_2(R,Y),!. 最小公倍数_2([A|R],Y) :- integer(A), 最小公倍数_2(R,Y),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1245853701/162 # # [1] 授業単元:数値計算 # [2] 問題文(含コード&リンク):の連立1次方程式の解をガウスの消去法用いて解くプログラムを作成しなさい。 #    (この行列を使用してください # {{10,-9,0,0,0,0,0,0}, # {-9,17,-8,0,0,0,0,0}, # {0,-8,17,-9,0,0,0,0}, # {0,0-9,13,-4,0,0,0}, # {0,0,0,-4,12,-8,0,0}, # {0,0,0,0,-8,10,-2,0}, # {0,0,0,0,0,-2,2,7}} % 以下の定義では必ずしもこの問題に必要としない行列処理の述語定義も含んで % います。 問題の行列([[10,-9,0,0,0,0,0,0], [-9,17,-8,0,0,0,0,0], [0,-8,17,-9,0,0,0,0], [0,0-9,13,-4,0,0,0], [0,0,0,-4,12,-8,0,0], [0,0,0,0,-8,10,-2,0], [0,0,0,0,0,-2,2,7]]). t310(_解ならび) :- 問題の行列(_問題の行列), 既約ガウス行列に変形(_問題の行列,_既約ガウス行列), findall(X,(member(L,_既約ガウス行列),last(L,X)),_解ならび). ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R). ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R). ガウス行列(_行列) :- ガウス行列([],_行列). % *** user: 'ガウス行列に変形' / 7 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列,[]) :- M > Len,!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X,UL),!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X,UL),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[(-1)|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X,R),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N1|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 >= 0,!, '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N3|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 < 0,!, N3 is N1 * (-1), '行基本変形'(N3 # M + N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R),!. % *** user: 'ガウス行列に変形' / 6 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列) :- M > Len,!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X),!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X),!. % *** user: ガウス行列に変形 / 5 *** ガウス行列に変形(N,Len,X,X,[]) :- N >= Len,!. ガウス行列に変形(N,Len,_行列1,X,UL) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2,UL1), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X,UL2), append(UL1,UL2,UL). % *** user: ガウス行列に変形 / 4 *** ガウス行列に変形(N,Len,X,X) :- N >= Len,!. ガウス行列に変形(N,Len,_行列1,X) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X). % *** user: ガウス行列に変形 / 3 *** ガウス行列に変形(_行列,_ガウス行列,UL) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列,UL). % *** user: ガウス行列に変形 / 2 *** ガウス行列に変形(_行列,_ガウス行列) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列). 既約ガウス行列に変形(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), 既約ガウス行列に変形(Len,_ガウス行列,G1), 既約ガウス行列に変形の二(1,Len,G1,_既約ガウス行列). % *** user: '既約ガウス行列に変形' / 5 *** '既約ガウス行列に変形'(N,0,_,_行列,_行列) :- !. '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列1,_行列). '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), /* '行基本変形3の適用'(A,B,M,N,_行列1,_行列2), */ '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列2,_行列). % *** user: '既約ガウス行列に変形' / 3 *** '既約ガウス行列に変形'(1,_既約ガウス行列,_既約ガウス行列) :- !. '既約ガウス行列に変形'(N,_ガウス行列,_既約ガウス行列) :- list_nth(N,_ガウス行列,L0), '最初に現れる0ではない要素・位置'(1,L0,_列,Y), M is N - 1, list_nth(M,_ガウス行列,L), '既約ガウス行列に変形'(_列,M,N,Y,_ガウス行列,G1), N2 is N - 1, '既約ガウス行列に変形'(N2,G1,_既約ガウス行列),!. % *** user: '既約ガウス行列に変形' / 2 *** 既約ガウス行列に変形(_行列,_既約ガウス行列) :- \+(ガウス行列(_行列)), ガウス行列に変形(_行列,_ガウス行列), 既約ガウス行列に変形(_ガウス行列,_既約ガウス行列),!. 既約ガウス行列に変形(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), 既約ガウス行列に変形(Len,_ガウス行列,G1), 既約ガウス行列に変形の二(1,Len,G1,_既約ガウス行列). % *** user: '既約ガウス行列に変形の二' / 4 *** 既約ガウス行列に変形の二(N,Len,_既約ガウス行列,_既約ガウス行列) :- N > Len,!. 既約ガウス行列に変形の二(N,Len,G,_既約ガウス行列) :- list_nth(N,G,_行), list_nth(N,_行,A), 行基本変形(1 / A # N,G,G1), N2 is N + 1, 既約ガウス行列に変形の二(N2,Len,G1,_既約ガウス行列). % *** user: 行基本変形3の適用 / 7 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形3の適用 / 6 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形 / 3 *** 行基本変形(_行列式,_行列,X) :- atom(_行列式), \+(_行列式 = []), & 行列式変換#2.pro, 行列式述語変換(_行列式,P), 行基本変形(P,_行列,X),!. 行基本変形([],_行列,[]) :- !. 行基本変形([N|R1],_行列,[L|R2]) :- !, list_nth(N,_行列,L), 行基本変形(R1,_行列,R2),!. '行基本変形'(# _行目1 # _行目2,_行列,X) :- list_nth(_行目1,_行列,_行1), list_nth(_行目2,_行列,_行2), ならびの位置指定置換(_行目2,_行1,_行列,_行列1), ならびの位置指定置換(_行目1,_行2,_行列1,X),!. 行基本変形(_乗数1 # _行目1 + _乗数2 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行1) , U is A * _乗数1),_乗算された行1), findall(W,(member(B,_行2) , W is B * _乗数2),_乗算された行2), 型推論加算([_乗算された行1,_乗算された行2],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- !, _乗数3 is -1 * _乗数2, 行基本変形(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X),!. 行基本変形( # _行目1 + _乗数 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数),_乗算された行), 型推論加算([_乗算された行,_行1],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形( # _行目1 - _乗数 # _行目2,_行列,X) :- !, _乗数2 is -1 * _乗数, 行基本変形( # _行目1 + _乗数2 * _行目2,_行列,X),!. 行基本変形( # _行目1 + _乗数 / _除数 * _行目2,_行列,X) :- integer(_除数), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 // _除数),_除算された行), 型推論加算([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形( # _行目1 + _乗数 / _除数 # _行目2,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 / _除数),_除算された行), 型推論加算([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形( # _行目1 - _乗数 / _除数 # _行目2,_行列,X) :- !, _除数2 is -1 * _除数, 行基本変形( # _行目1 + _乗数 / _除数2 * _行目2,_行列,X),!. 行基本変形(_乗数 / _除数 # _行目,_行列,X) :- integer(_除数), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 // _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. 行基本変形(_乗数 / _除数 # _行目,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 / _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. 行基本変形(_乗数 # _行目,_行列,X) :- !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. % *** user: 行基本変形 / 5 *** 行基本変形(*,_乗数,_行目,_行列,X) :- 行基本変形(*,_乗数,1,_行目,_行列,X). % *** user: 行基本変形 / 6 *** 行基本変形(*,_乗数,_行目,_行目,[_行1|R1],[_行2|R1]) :- findall(X,(member(A,_行1) , X is A * _乗数),_行2) . 行基本変形(*,_乗数,M,_行目,[_行|R1],[_行|R2]) :- M2 is M + 1, 行基本変形(*,_乗数,M2,_行目,R1,R2). % *** user: 正方行列の行列式の値 / 2 *** 正方行列の行列式の値(_正方行列,_行列式の値) :- ガウス行列に変形(_正方行列,X,Y), '行列式|C|の値'(X,Z1), ならびの積(Y,Z2), _行列式の値 is Z1 // Z2. % *** user: ならびの積 / 2 *** ならびの積([A],A) :- !. ならびの積([A|R],X) :- ならびの積(R,Y), X is A * Y. % *** user: '行列式|C|の値' / 2 *** '行列式|C|の値'(_行列,_値) :- length(_行列,Len), findall(U,(for(1,N,Len) , list_nth(N,_行列,_行) , list_nth(N,_行,U)),L), ならびの積(L,_値). 要素がゼロ以外に出会うまで([A|R],[],[A|R]) :- \+((A = 0;A=0.0)),!. 要素がゼロ以外に出会うまで([0|R],[0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 要素がゼロ以外に出会うまで([0.0|R],[0.0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 最初に現れる0ではない要素・位置(Nth,[X|_],Nth,X) :- \+((X = 0;X=0.0)),!. 最初に現れる0ではない要素・位置(Mth,[0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X). 最初に現れる0ではない要素・位置(Mth,[0.0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X). % *** user: ならびの位置指定置換 / 4 *** ならびの位置指定置換(1,A,[_|R],[A|R]) :- !. ならびの位置指定置換(N,A,[B|R1],[B|R2]) :- N1 is N - 1, ならびの位置指定置換(N1,A,R1,R2) . 最小公倍数(N1 * A,B,C) :- integer(B), 最小公倍数(A,B,C), N1 is C // A,!. 最小公倍数(A,N2 * B,C) :- integer(A), 最小公倍数(A,B,C), N2 is C // B,!. 最小公倍数(N1 * A,N2 * B,C) :- 最小公倍数(A,B,C), N1 is C // A, N2 is C // B,!. 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最小公倍数([N1 * A|R],X) :- findall(U,member(_ * U,[N1 * A|R]),L1), 最小公倍数(L1,X), 最小公倍数_2([N1 * A|R],X),!. 最小公倍数([A,B],X) :- 最小公倍数(A,B,X),!. 最小公倍数([A|R],X) :- 最小公倍数(R,B), 最小公倍数(A,B,X),!. 最小公倍数_2([],_) :- !. 最小公倍数_2([N * A|R],Y) :- N is Y // A, 最小公倍数_2(R,Y),!. 最小公倍数_2([A|R],Y) :- integer(A), 最小公倍数_2(R,Y),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R). ガウス行列(_,[]) :- ! . ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R) . ガウス行列(_行列) :- ガウス行列([],_行列) . % *** user: 'ガウス行列に変形' / 7 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列,[]) :- M > Len, ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X,UL), ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X,UL), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[(-1)|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X,R), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N1|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 >= 0,!, '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N3|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 < 0,!, N3 is N1 * (-1), '行基本変形'(N3 # M + N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R), ! . % *** user: 'ガウス行列に変形' / 6 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列) :- M > Len, ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X), ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X), ! . % *** user: ガウス行列に変形 / 5 *** ガウス行列に変形(N,Len,X,X,[]) :- N >= Len, !. ガウス行列に変形(N,Len,_行列1,X,UL) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2,UL1), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X,UL2), append(UL1,UL2,UL). % *** user: ガウス行列に変形 / 4 *** ガウス行列に変形(N,Len,X,X) :- N >= Len, !. ガウス行列に変形(N,Len,_行列1,X) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X). % *** user: ガウス行列に変形 / 3 *** ガウス行列に変形(_行列,_ガウス行列,UL) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列,UL). % *** user: ガウス行列に変形 / 2 *** ガウス行列に変形(_行列,_ガウス行列) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列). % *** user: '既約ガウス行列に変形' / 5 *** '既約ガウス行列に変形'(N,0,_,_行列,_行列) :- ! . '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列1,_行列) . '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), /* '行基本変形3の適用'(A,B,M,N,_行列1,_行列2), */ '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列2,_行列) . % *** user: '既約ガウス行列に変形' / 2 *** '既約ガウス行列に変形'(_行列,_既約ガウス行列) :- \+('ガウス行列'(_行列)), 'ガウス行列に変形'(_行列,_ガウス行列), '既約ガウス行列に変形'(_ガウス行列,_既約ガウス行列), ! . '既約ガウス行列に変形'(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), '既約ガウス行列に変形'(Len,_ガウス行列,G1), '既約ガウス行列に変形の二'(1,Len,G1,_既約ガウス行列) . % *** user: 行基本変形3の適用 / 7 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形3の適用 / 6 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: '行基本変形' / 5 *** '行基本変形'(*,_乗数,_行目,_行列,X) :- '行基本変形'(*,_乗数,1,_行目,_行列,X) . % *** user: '行基本変形' / 5 *** '行基本変形'(*,_乗数,_行目,_行列,X) :- '行基本変形'(*,_乗数,1,_行目,_行列,X) . % *** user: '行基本変形' / 3 *** '行基本変形'(_行列式,_行列,X) :- atom(_行列式), \+(_行列式 = []), & '行列式変換' # [2|pro], '行列式述語変換'(_行列式,P), '行基本変形'(P,_行列,X), ! . '行基本変形'([],_行列,[]) :- ! . '行基本変形'([N|R1],_行列,[L|R2]) :- !, list_nth(N,_行列,L), '行基本変形'(R1,_行列,R2), ! . '行基本変形'(# _行目1 # _行目2,_行列,X) :- list_nth(_行目1,_行列,_行1), list_nth(_行目2,_行列,_行2), 'ならびの位置指定置換'(_行目2,_行1,_行列,_行列1), 'ならびの位置指定置換'(_行目1,_行2,_行列1,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 >= 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 < 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 >= 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 < 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 + _乗数2 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行1) , U is A * _乗数1),_乗算された行1), findall(W,(member(B,_行2) , W is B * _乗数2),_乗算された行2), '型推論加算'([_乗算された行1,_乗算された行2],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 + _乗数 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数),_乗算された行), '型推論加算'([_乗算された行,_行1],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 - _乗数 # _行目2,_行列,X) :- !, _乗数2 is -1 * _乗数, '行基本変形'(# _行目1 + _乗数2 * _行目2,_行列,X), ! . '行基本変形'(# _行目1 + _乗数 / _除数 * _行目2,_行列,X) :- integer(_除数), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 // _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 + _乗数 / _除数 # _行目2,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 / _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 - _乗数 / _除数 # _行目2,_行列,X) :- !, _除数2 is -1 * _除数, '行基本変形'(# _行目1 + _乗数 / _除数2 * _行目2,_行列,X), ! . '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- integer(_除数), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 // _除数),_行2), replace_nth(1,_行目,_行2,_行列,X), ! . '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 / _除数),_行2), replace_nth(1,_行目,_行2,_行列,X), ! . '行基本変形'(_乗数 # _行目,_行列,X) :- !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数),_行2), replace_nth(1,_行目,_行2,_行列,X), ! . % *** user: 行基本変形 / 5 *** 行基本変形(*,_乗数,_行目,_行列,X) :- 行基本変形(*,_乗数,1,_行目,_行列,X) . % *** user: 行基本変形 / 6 *** 行基本変形(*,_乗数,_行目,_行目,[_行1|R1],[_行2|R1]) :- findall(X,(member(A,_行1) , X is A * _乗数),_行2) . 行基本変形(*,_乗数,M,_行目,[_行|R1],[_行|R2]) :- M2 is M + 1, 行基本変形(*,_乗数,M2,_行目,R1,R2) . 要素がゼロ以外に出会うまで([A|R],[],[A|R]) :- \+((A = 0; A = 0.0)),!. 要素がゼロ以外に出会うまで([0|R],[0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 要素がゼロ以外に出会うまで([0.0|R],[0.0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 最初に現れる0ではない要素・位置(Nth,[X|_],Nth,X) :- \+((X = 0;X = 0.0)),!. 最初に現れる0ではない要素・位置(Mth,[0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . 最初に現れる0ではない要素・位置(Mth,[0.0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . 最小公倍数(N1 * A,B,C) :- integer(B), 最小公倍数(A,B,C), N1 is C // A,!. 最小公倍数(A,N2 * B,C) :- integer(A), 最小公倍数(A,B,C), N2 is C // B,!. 最小公倍数(N1 * A,N2 * B,C) :- 最小公倍数(A,B,C), N1 is C // A, N2 is C // B,!. 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最小公倍数([N1 * A|R],X) :- findall(U,member(_ * U,[N1 * A|R]),L1), 最小公倍数(L1,X), 最小公倍数_2([N1 * A|R],X),!. 最小公倍数([A,B],X) :- 最小公倍数(A,B,X),!. 最小公倍数([A|R],X) :- 最小公倍数(R,B), 最小公倍数(A,B,X),!. 最小公倍数_2([],_) :- !. 最小公倍数_2([N * A|R],Y) :- N is Y // A, 最小公倍数_2(R,Y),!. 最小公倍数_2([A|R],Y) :- integer(A), 最小公倍数_2(R,Y),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # # 出典::プログラミングのための線形代数 p179 サンプルコード # # LU分解(コレスキー分解) # 'LU分解'(LL1,LL2) :- '行数・列数のうち小さい方の回数制御ならび'(LL1,_回数制御ならび), 'LU分解'(_回数制御ならび,LL1,LL2). '行数・列数のうち小さい方の回数制御ならび'(LL1,_回数制御ならび) :- 行数(LL1,_行数), 列数(LL1,_列数), min_list([_行数,_列数],Len), length(_回数制御ならび,Len). 行数(LL1,_行数) :- length(LL1,_行数). 列数([L|_],_列数) :- length(L,_列数). 'LU分解'([],LL,LL). 'LU分解'([_|Ln],_主小行列_1,[_lL|_LU_3]) :- '_lLと_uLと_主小行列に分割し主小行列部分を計算する'(_主小行列_1,_lL,_uL,_主小行列_2), 'LU分解'(Ln,_主小行列_2,_LU_2), '_uLを主小行列に貼り付ける'(_uL,_LU_2,_LU_3). '_lLと_uLと_主小行列に分割し主小行列部分を計算する'([_lL|R1],_lL,_uL,_主小行列) :- _lL = [_l|L], '_uLと_主小行列を切り出す'(_l,R1,_uL,R2), '主小行列部分を計算する'(R2,_lL,_uL,_主小行列). '_uLと_主小行列を切り出す'(_,[],[],[]). '_uLと_主小行列を切り出す'(_l,[[_u_1|L]|R2],[_u_2|R3],[L|R4]) :- 分数を含む除算(_u_1,_l,_u_2), '_uLと_主小行列を切り出す'(_l,R2,R3,R4). 主小行列部分を計算する([],[],[],[]). 主小行列部分を計算する([L1|R1],_lL,[_u|_uL],[L3|R4]) :- 主小行列部分の一行を計算する(L1,_lL,_u,L3), 主小行列部分を計算する(R1,_lL,_uL,R4). 主小行列部分の一行を計算する([],[],_,[]) :- !. 主小行列部分の一行を計算する([_d_1|R1],[_l|R3],_u,[_d_2|R4]) :- '_d_2 is _d_1 - _u * _l'(_u,_l,_d_1,_d_2), 主小行列部分の一行を計算する(R1,R3,_u,R4). '_d_2 is _d_1 - _u * _l'(_u,_l,_d_1,_d_2) :- 分数を含む掛算(_u,_l,Y), 分数を含む減算(_d_1,Y,_d_2). '_uLを主小行列に貼り付ける'([],[],[]). '_uLを主小行列に貼り付ける'([_u|_uL],[L1|_LU_2],[[_u|L1]|_LU_3]) :- '_uLを主小行列に貼り付ける'(_uL,_LU_2,_LU_3). 分数を含む掛算(A1 rdiv A2,B1 rdiv B2,C) :- S1 is A1 * B1, S2 is A2 * B2, 約分(S1 rdiv S2,C),!. 分数を含む掛算(A1 rdiv A2,B,C) :- S1 is A1 * B, 約分(S1 rdiv A2,C),!. 分数を含む掛算(A,B1 rdiv B2,C) :- S1 is B1 * A, 約分(S1 rdiv B2,C),!. 分数を含む掛算(A,B,C) :- C is A * B. 分数を含む除算(A,B,C) :- number(A), number(B), 約分(A rdiv B,C),!. 分数を含む除算(A1 rdiv B1,A2 rdiv B2,C) :- 分数を含む乗算(A1 rdiv B1,B2 rdiv A2,C),!. 分数を含む除算(V,A2 rdiv B2,C) :- number(V), 分数を含む乗算(V,B2 rdiv A2,C),!. 分数を含む除算(A1 rdiv B1,V,C) :- number(V), B2 is V * B1, 約分(A1 rdiv B2,C),!. 分数を含む加算(A,B,C) :- number(A), number(B), C is A + B,!. 分数を含む加算(A1 rdiv B1,A2 rdiv B2,C) :- A3 is A1 * B2 + A2 * B1, B3 is B1 * B2, 約分(A3 rdiv B3,C),!. 分数を含む加算(A1 rdiv B1,V,C) :- number(V), A2 is V * B1, C3 is A1 + A2, 約分(C3 rdiv B1,C),!. 分数を含む加算(V,A2 rdiv B2,C) :- number(V), A1 is V * B2, C3 is A1 + A2, 約分(C3 rdiv B2,C),!. 分数を含む減算(A,B,C) :- number(A), number(B), C is A - B,!. 分数を含む減算(A1 rdiv B1,A2 rdiv B2,C) :- A3 is A1 * B2 - A2 * B1, B3 is B1 * B2, 約分(A3 rdiv B3,C),!. 分数を含む減算(A1 rdiv B1,V,C) :- number(V), A2 is V * B1, C3 is A1 - A2, 約分(C3 rdiv B1,C),!. 分数を含む減算(V,A2 rdiv B2,C) :- number(V), A1 is V * B2, C3 is A1 - A2, 約分(C3 rdiv B2,C),!. 約分(B rdiv A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子_1,_分母_1,_分子 rdiv _分母) :- 分母が負数だったら分子分母ともに符号を反転する(_分子_1,_分母_1,_分子,_分母),!. 約分の二(_分子,_分母,_分子 rdiv _分母). 分母が負数だったら分子分母ともに符号を反転する(_分子_1,_分母_1,_分子,_分母) :- _分母_1 < 0, _分子 is _分子_1 * -1, _分母 is _分母_1 * -1. 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X) . % 以下のサイトは ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R). ガウス行列(_,[]) :- ! . ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R) . ガウス行列(_行列) :- ガウス行列([],_行列) . % *** user: 'ガウス行列に変形' / 7 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列,[]) :- M > Len, ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X,UL), ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X,UL), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[(-1)|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X,R), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N1|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 >= 0,!, '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N3|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 < 0,!, N3 is N1 * (-1), '行基本変形'(N3 # M + N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R), ! . % *** user: 'ガウス行列に変形' / 6 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列) :- M > Len, ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X), ! . 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X), ! . 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X), ! . % *** user: ガウス行列に変形 / 5 *** ガウス行列に変形(N,Len,X,X,[]) :- N >= Len, !. ガウス行列に変形(N,Len,_行列1,X,UL) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2,UL1), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X,UL2), append(UL1,UL2,UL). % *** user: ガウス行列に変形 / 4 *** ガウス行列に変形(N,Len,X,X) :- N >= Len, !. ガウス行列に変形(N,Len,_行列1,X) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X). % *** user: ガウス行列に変形 / 3 *** ガウス行列に変形(_行列,_ガウス行列,UL) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列,UL). % *** user: ガウス行列に変形 / 2 *** ガウス行列に変形(_行列,_ガウス行列) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列). % *** user: '既約ガウス行列に変形' / 5 *** '既約ガウス行列に変形'(N,0,_,_行列,_行列) :- ! . '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列1,_行列) . '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), /* '行基本変形3の適用'(A,B,M,N,_行列1,_行列2), */ '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列2,_行列) . % *** user: '既約ガウス行列に変形' / 2 *** '既約ガウス行列に変形'(_行列,_既約ガウス行列) :- \+('ガウス行列'(_行列)), 'ガウス行列に変形'(_行列,_ガウス行列), '既約ガウス行列に変形'(_ガウス行列,_既約ガウス行列), ! . '既約ガウス行列に変形'(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), '既約ガウス行列に変形'(Len,_ガウス行列,G1), '既約ガウス行列に変形の二'(1,Len,G1,_既約ガウス行列) . % *** user: 行基本変形3の適用 / 7 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形3の適用 / 6 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: '行基本変形' / 5 *** '行基本変形'(*,_乗数,_行目,_行列,X) :- '行基本変形'(*,_乗数,1,_行目,_行列,X) . % *** user: '行基本変形' / 5 *** '行基本変形'(*,_乗数,_行目,_行列,X) :- '行基本変形'(*,_乗数,1,_行目,_行列,X) . % *** user: '行基本変形' / 3 *** '行基本変形'(_行列式,_行列,X) :- atom(_行列式), \+(_行列式 = []), & '行列式変換' # [2|pro], '行列式述語変換'(_行列式,P), '行基本変形'(P,_行列,X), ! . '行基本変形'([],_行列,[]) :- ! . '行基本変形'([N|R1],_行列,[L|R2]) :- !, list_nth(N,_行列,L), '行基本変形'(R1,_行列,R2), ! . '行基本変形'(# _行目1 # _行目2,_行列,X) :- list_nth(_行目1,_行列,_行1), list_nth(_行目2,_行列,_行2), 'ならびの位置指定置換'(_行目2,_行1,_行列,_行列1), 'ならびの位置指定置換'(_行目1,_行2,_行列1,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 >= 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 < 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 >= 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 < 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X), ! . '行基本変形'(_乗数1 # _行目1 + _乗数2 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行1) , U is A * _乗数1),_乗算された行1), findall(W,(member(B,_行2) , W is B * _乗数2),_乗算された行2), '型推論加算'([_乗算された行1,_乗算された行2],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 + _乗数 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数),_乗算された行), '型推論加算'([_乗算された行,_行1],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 - _乗数 # _行目2,_行列,X) :- !, _乗数2 is -1 * _乗数, '行基本変形'(# _行目1 + _乗数2 * _行目2,_行列,X), ! . '行基本変形'(# _行目1 + _乗数 / _除数 * _行目2,_行列,X) :- integer(_除数), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 // _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 + _乗数 / _除数 # _行目2,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 / _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X), ! . '行基本変形'(# _行目1 - _乗数 / _除数 # _行目2,_行列,X) :- !, _除数2 is -1 * _除数, '行基本変形'(# _行目1 + _乗数 / _除数2 * _行目2,_行列,X), ! . '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- integer(_除数), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 // _除数),_行2), replace_nth(1,_行目,_行2,_行列,X), ! . '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 / _除数),_行2), replace_nth(1,_行目,_行2,_行列,X), ! . '行基本変形'(_乗数 # _行目,_行列,X) :- !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数),_行2), replace_nth(1,_行目,_行2,_行列,X), ! . % *** user: 行基本変形 / 5 *** 行基本変形(*,_乗数,_行目,_行列,X) :- 行基本変形(*,_乗数,1,_行目,_行列,X) . % *** user: 行基本変形 / 6 *** 行基本変形(*,_乗数,_行目,_行目,[_行1|R1],[_行2|R1]) :- findall(X,(member(A,_行1) , X is A * _乗数),_行2) . 行基本変形(*,_乗数,M,_行目,[_行|R1],[_行|R2]) :- M2 is M + 1, 行基本変形(*,_乗数,M2,_行目,R1,R2) . 要素がゼロ以外に出会うまで([A|R],[],[A|R]) :- \+((A = 0; A = 0.0)),!. 要素がゼロ以外に出会うまで([0|R],[0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 要素がゼロ以外に出会うまで([0.0|R],[0.0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 最初に現れる0ではない要素・位置(Nth,[X|_],Nth,X) :- \+((X = 0;X = 0.0)),!. 最初に現れる0ではない要素・位置(Mth,[0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . 最初に現れる0ではない要素・位置(Mth,[0.0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . 最小公倍数(N1 * A,B,C) :- integer(B), 最小公倍数(A,B,C), N1 is C // A,!. 最小公倍数(A,N2 * B,C) :- integer(A), 最小公倍数(A,B,C), N2 is C // B,!. 最小公倍数(N1 * A,N2 * B,C) :- 最小公倍数(A,B,C), N1 is C // A, N2 is C // B,!. 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最小公倍数([N1 * A|R],X) :- findall(U,member(_ * U,[N1 * A|R]),L1), 最小公倍数(L1,X), 最小公倍数_2([N1 * A|R],X),!. 最小公倍数([A,B],X) :- 最小公倍数(A,B,X),!. 最小公倍数([A|R],X) :- 最小公倍数(R,B), 最小公倍数(A,B,X),!. 最小公倍数_2([],_) :- !. 最小公倍数_2([N * A|R],Y) :- N is Y // A, 最小公倍数_2(R,Y),!. 最小公倍数_2([A|R],Y) :- integer(A), 最小公倍数_2(R,Y),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1250204272/381 # # [1] 授業単元: 情報工学:数理I # [2] 問題文(含コード&リンク): ガウス行列を既約ガウス行列に変形する関数を定義せよ % *** user: '既約ガウス行列に変形' / 5 *** '既約ガウス行列に変形'(N,0,_,_行列,_行列) :- !. '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列1,_行列). '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), /* '行基本変形3の適用'(A,B,M,N,_行列1,_行列2), */ '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列2,_行列). % *** user: '既約ガウス行列に変形' / 3 *** '既約ガウス行列に変形'(1,_既約ガウス行列,_既約ガウス行列) :- !. '既約ガウス行列に変形'(N,_ガウス行列,_既約ガウス行列) :- list_nth(N,_ガウス行列,L0), '最初に現れる0ではない要素・位置'(1,L0,_列,Y), M is N - 1, list_nth(M,_ガウス行列,L), '既約ガウス行列に変形'(_列,M,Y,_ガウス行列,G1), N2 is N - 1, '既約ガウス行列に変形'(N2,G1,_既約ガウス行列),!. % *** user: '既約ガウス行列に変形' / 2 *** '既約ガウス行列に変形'(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), '既約ガウス行列に変形'(Len,_ガウス行列,G1), '既約ガウス行列に変形の二'(1,Len,G1,_既約ガウス行列). 既約ガウス行列に変形の二(N,Len,_既約ガウス行列,_既約ガウス行列) :- N > Len,!. 既約ガウス行列に変形の二(N,Len,G,_既約ガウス行列) :- list_nth(N,G,_行), list_nth(N,_行,A), 行基本変形(1 / A # N,G,G1), N2 is N + 1, 既約ガウス行列に変形の二(N2,Len,G1,_既約ガウス行列). % *** user: 行基本変形3の適用 / 7 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形3の適用 / 6 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: '行基本変形' / 5 *** '行基本変形'(*,_乗数,_行目,_行列,X) :- '行基本変形'(*,_乗数,1,_行目,_行列,X) . % *** user: '行基本変形' / 3 *** '行基本変形'(_行列式,_行列,X) :- atom(_行列式), \+(_行列式 = []), & '行列式変換' # [2|pro], '行列式述語変換'(_行列式,P), '行基本変形'(P,_行列,X),!. '行基本変形'([],_行列,[]) :-!. '行基本変形'([N|R1],_行列,[L|R2]) :- !, list_nth(N,_行列,L), '行基本変形'(R1,_行列,R2),!. '行基本変形'(# _行目1 # _行目2,_行列,X) :- list_nth(_行目1,_行列,_行1), list_nth(_行目2,_行列,_行2), 'ならびの位置指定置換'(_行目2,_行1,_行列,_行列1), 'ならびの位置指定置換'(_行目1,_行2,_行列1,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 >= 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 >= 0, _乗数1 < 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 >= 0, _乗数3 is _乗数1 * (-1), !, '行基本変形'(_乗数3 # _行目1 + _乗数2 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- _乗数2 < 0, _乗数1 < 0, !, _乗数3 is -1 * _乗数2, '行基本変形'(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X),!. '行基本変形'(_乗数1 # _行目1 + _乗数2 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行1) , U is A * _乗数1),_乗算された行1), findall(W,(member(B,_行2) , W is B * _乗数2),_乗算された行2), '型推論加算'([_乗算された行1,_乗算された行2],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 + _乗数 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数),_乗算された行), '型推論加算'([_乗算された行,_行1],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 - _乗数 # _行目2,_行列,X) :- !, _乗数2 is -1 * _乗数, '行基本変形'(# _行目1 + _乗数2 * _行目2,_行列,X),!. '行基本変形'(# _行目1 + _乗数 / _除数 * _行目2,_行列,X) :- integer(_除数), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 // _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 + _乗数 / _除数 # _行目2,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 / _除数),_除算された行), '型推論加算'([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. '行基本変形'(# _行目1 - _乗数 / _除数 # _行目2,_行列,X) :- !, _除数2 is -1 * _除数, '行基本変形'(# _行目1 + _乗数 / _除数2 * _行目2,_行列,X),!. '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- integer(_除数), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 // _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. '行基本変形'(_乗数 / _除数 # _行目,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 / _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. '行基本変形'(_乗数 # _行目,_行列,X) :- !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. % *** user: 行基本変形 / 5 *** 行基本変形(*,_乗数,_行目,_行列,X) :- 行基本変形(*,_乗数,1,_行目,_行列,X). % *** user: 行基本変形 / 6 *** 行基本変形(*,_乗数,_行目,_行目,[_行1|R1],[_行2|R1]) :- findall(X,(member(A,_行1) , X is A * _乗数),_行2) . 行基本変形(*,_乗数,M,_行目,[_行|R1],[_行|R2]) :- M2 is M + 1, 行基本変形(*,_乗数,M2,_行目,R1,R2). % *** user: 正方行列の行列式の値 / 2 *** 正方行列の行列式の値(_正方行列,_行列式の値) :- ガウス行列に変形(_正方行列,X,Y), '行列式|C|の値'(X,Z1), ならびの積(Y,Z2), _行列式の値 is Z1 // Z2. % *** user: ならびの積 / 2 *** ならびの積([A],A) :- !. ならびの積([A|R],X) :- ならびの積(R,Y), X is A * Y. % *** user: '行列式|C|の値' / 2 *** '行列式|C|の値'(_行列,_値) :- length(_行列,Len), findall(U,(for(1,N,Len) , list_nth(N,_行列,_行) , list_nth(N,_行,U)),L), ならびの積(L,_値). 要素がゼロ以外に出会うまで([A|R],[],[A|R]) :- \+((A = 0;A=0.0)),!. 要素がゼロ以外に出会うまで([0|R],[0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 要素がゼロ以外に出会うまで([0.0|R],[0.0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 最初に現れる0ではない要素・位置(Nth,[X|_],Nth,X) :- \+((X = 0;X=0.0)),!. 最初に現れる0ではない要素・位置(Mth,[0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . 最初に現れる0ではない要素・位置(Mth,[0.0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X) . % *** user: ならびの位置指定置換 / 4 *** ならびの位置指定置換(1,A,[_|R],[A|R]) :- !. ならびの位置指定置換(N,A,[B|R1],[B|R2]) :- N1 is N - 1, ならびの位置指定置換(N1,A,R1,R2) . 最小公倍数(N1 * A,B,C) :- integer(B), 最小公倍数(A,B,C), N1 is C // A,!. 最小公倍数(A,N2 * B,C) :- integer(A), 最小公倍数(A,B,C), N2 is C // B,!. 最小公倍数(N1 * A,N2 * B,C) :- 最小公倍数(A,B,C), N1 is C // A, N2 is C // B,!. 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最小公倍数([N1 * A|R],X) :- findall(U,member(_ * U,[N1 * A|R]),L1), 最小公倍数(L1,X), 最小公倍数_2([N1 * A|R],X),!. 最小公倍数([A,B],X) :- 最小公倍数(A,B,X),!. 最小公倍数([A|R],X) :- 最小公倍数(R,B), 最小公倍数(A,B,X),!. 最小公倍数_2([],_) :- !. 最小公倍数_2([N * A|R],Y) :- N is Y // A, 最小公倍数_2(R,Y),!. 最小公倍数_2([A|R],Y) :- integer(A), 最小公倍数_2(R,Y),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/743 # # [1] 授業単元:プログラミング基礎 # [2] 問題文(含コード&リンク): # 2つの整数をキーボードから入力し、それらの最大公約数を表示する # プログラムを作成せよ。 # 最大公約数と、2つの数字を割り切る最大の整数のことである。 # 例えば12と18の最大公約数は6,24と48の最大公約数は24である。 t598 :- write('2数の最大公約数を求めます。カンマ区切りで二つの整数を入力してください : '), get_Line(Line), split(Line,[','],[N1,N2]), appendを使って最大公約数を求める(N1,N2,X), write_formatted('%tと%tの最大公約数は%tです\n',[N1,N2,X]). appendを使って最大公約数を求める(N1,N2,X) :- length(L1,N1), length(L2,N2), appendを使って最大公約数を求める(L1,L2,[_],[_],LX), length(LX,X). appendを使って最大公約数を求める(L1,L2,L,X,X) :- not((append(L,_,L1),append(L,_,L2))),!. appendを使って最大公約数を求める(L1,L2,L,_,X) :- 割り切れる(L1,L), 割り切れる(L2,L), appendを使って最大公約数を求める(L1,L2,[_|L],L,X). appendを使って最大公約数を求める(L1,L2,L,Y,X) :- appendを使って最大公約数を求める(L1,L2,[_|L],Y,X). 割り切れる([],_) :- !. 割り切れる(L,DL) :- append(DL,L3,L), 割り切れる(L3,DL). % 以下のサイトは 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1245853701/423 # # [1] 授業単元: 情報処理 # [2] 問題文(含コード&リンク): # #  2つの正整数 m とn とを引数として受け取り、m と n の最大公約数を戻 # り値として返す関数gcd()を作成する。この関数を用いることにより、キー # ボードから入力した3つの正整数 a, b, c の最大公約数を求めるプログラム # を書け。 # # 注意: 最大公約数を計算するには次のような「ユークリッドの互除法」を # 用いるとよい。 # # 「ユークリッドの互除法」 #  2つの正の整数 m、n(m>n)の最大公約数を求めるには、m を n で割っ # て余り r1 を求め、次に n を r1 で割って余り r2 を求め、・・・、この # ように大きい方を小さい方で割って余りを求め、最後に割り切れたときの除 # 数が求める最大公約数である。 # # 例)440/380=1余り60  # 380/60=6余り20 # 60/20=3 余りなし #  したがって、440と380の最大公約数は20  最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1245853701/162 # # [1] 授業単元:数値計算 # [2] 問題文(含コード&リンク):の連立1次方程式の解をガウスの消去法用いて解くプログラムを作成しなさい。 #    (この行列を使用してください # {{10,-9,0,0,0,0,0,0}, # {-9,17,-8,0,0,0,0,0}, # {0,-8,17,-9,0,0,0,0}, # {0,0-9,13,-4,0,0,0}, # {0,0,0,-4,12,-8,0,0}, # {0,0,0,0,-8,10,-2,0}, # {0,0,0,0,0,-2,2,7}} % 以下の定義では必ずしもこの問題に必要としない行列処理の述語定義も含んで % います。 問題の行列([[10,-9,0,0,0,0,0,0], [-9,17,-8,0,0,0,0,0], [0,-8,17,-9,0,0,0,0], [0,0-9,13,-4,0,0,0], [0,0,0,-4,12,-8,0,0], [0,0,0,0,-8,10,-2,0], [0,0,0,0,0,-2,2,7]]). t310(_解ならび) :- 問題の行列(_問題の行列), 既約ガウス行列に変形(_問題の行列,_既約ガウス行列), findall(X,(member(L,_既約ガウス行列),last(L,X)),_解ならび). ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R). ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- append(L,_,_行), 要素がゼロ以外に出会うまで(_行,P1,_), ガウス行列([0|P1],R). ガウス行列(_行列) :- ガウス行列([],_行列). % *** user: 'ガウス行列に変形' / 7 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列,[]) :- M > Len,!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X,UL),!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X,UL) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X,UL),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[(-1)|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X,R),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N1|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 >= 0,!, '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X,[N3|R]) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), N1 < 0,!, N3 is N1 * (-1), '行基本変形'(N3 # M + N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X,R),!. % *** user: 'ガウス行列に変形' / 6 *** 'ガウス行列に変形'(N,M,Len,_,_行列,_行列) :- M > Len,!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), '行の置換'(N,M,_行列1,_行列2), M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,B,_行列2,X),!. 'ガウス行列に変形'(N,M,Len,0,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), B = 0, M2 is N + 1, 'ガウス行列に変形'(N,M2,Len,0,_行列1,X),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列1,X),!. 'ガウス行列に変形'(N,M,Len,A,_行列1,X) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M + 1, 'ガウス行列に変形'(N,M2,Len,A,_行列2,X),!. % *** user: ガウス行列に変形 / 5 *** ガウス行列に変形(N,Len,X,X,[]) :- N >= Len,!. ガウス行列に変形(N,Len,_行列1,X,UL) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2,UL1), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X,UL2), append(UL1,UL2,UL). % *** user: ガウス行列に変形 / 4 *** ガウス行列に変形(N,Len,X,X) :- N >= Len,!. ガウス行列に変形(N,Len,_行列1,X) :- list_nth(N,_行列1,_行), list_nth(N,_行,A), M is N + 1, ガウス行列に変形(N,M,Len,A,_行列1,_行列2), N2 is N + 1, ガウス行列に変形(N2,Len,_行列2,X). % *** user: ガウス行列に変形 / 3 *** ガウス行列に変形(_行列,_ガウス行列,UL) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列,UL). % *** user: ガウス行列に変形 / 2 *** ガウス行列に変形(_行列,_ガウス行列) :- length(_行列,Len), ガウス行列に変形(1,Len,_行列,_ガウス行列). 既約ガウス行列に変形(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), 既約ガウス行列に変形(Len,_ガウス行列,G1), 既約ガウス行列に変形の二(1,Len,G1,_既約ガウス行列). % *** user: '既約ガウス行列に変形' / 5 *** '既約ガウス行列に変形'(N,0,_,_行列,_行列) :- !. '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,0), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列1,_行列). '既約ガウス行列に変形'(N,M,A,_行列1,_行列) :- list_nth(M,_行列1,_行1), list_nth(N,_行1,B), \+(B = 0), /* '行基本変形3の適用'(A,B,M,N,_行列1,_行列2), */ '最小公倍数'(N2 * A,N1 * B,_), '行基本変形'(N1 # M - N2 # N,_行列1,_行列2), M2 is M - 1, '既約ガウス行列に変形'(N,M2,A,_行列2,_行列). % *** user: '既約ガウス行列に変形' / 3 *** '既約ガウス行列に変形'(1,_既約ガウス行列,_既約ガウス行列) :- !. '既約ガウス行列に変形'(N,_ガウス行列,_既約ガウス行列) :- list_nth(N,_ガウス行列,L0), '最初に現れる0ではない要素・位置'(1,L0,_列,Y), M is N - 1, list_nth(M,_ガウス行列,L), '既約ガウス行列に変形'(_列,M,N,Y,_ガウス行列,G1), N2 is N - 1, '既約ガウス行列に変形'(N2,G1,_既約ガウス行列),!. % *** user: '既約ガウス行列に変形' / 2 *** 既約ガウス行列に変形(_行列,_既約ガウス行列) :- \+(ガウス行列(_行列)), ガウス行列に変形(_行列,_ガウス行列), 既約ガウス行列に変形(_ガウス行列,_既約ガウス行列),!. 既約ガウス行列に変形(_ガウス行列,_既約ガウス行列) :- length(_ガウス行列,Len), 既約ガウス行列に変形(Len,_ガウス行列,G1), 既約ガウス行列に変形の二(1,Len,G1,_既約ガウス行列). % *** user: '既約ガウス行列に変形の二' / 4 *** 既約ガウス行列に変形の二(N,Len,_既約ガウス行列,_既約ガウス行列) :- N > Len,!. 既約ガウス行列に変形の二(N,Len,G,_既約ガウス行列) :- list_nth(N,G,_行), list_nth(N,_行,A), 行基本変形(1 / A # N,G,G1), N2 is N + 1, 既約ガウス行列に変形の二(N2,Len,G1,_既約ガウス行列). % *** user: 行基本変形3の適用 / 7 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2,N2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形3の適用 / 6 *** 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B >= 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M-N1#N,_行列1,_行列2),!. 行基本変形3の適用(A,B,M,N,_行列1,_行列2) :- B < 0, A2 is abs(A), B2 is abs(B), 最小公倍数(N1 * A2,N2 * B2,_), 行基本変形(N2#M+N1#N,_行列1,_行列2),!. % *** user: 行基本変形 / 3 *** 行基本変形(_行列式,_行列,X) :- atom(_行列式), \+(_行列式 = []), & 行列式変換#2.pro, 行列式述語変換(_行列式,P), 行基本変形(P,_行列,X),!. 行基本変形([],_行列,[]) :- !. 行基本変形([N|R1],_行列,[L|R2]) :- !, list_nth(N,_行列,L), 行基本変形(R1,_行列,R2),!. '行基本変形'(# _行目1 # _行目2,_行列,X) :- list_nth(_行目1,_行列,_行1), list_nth(_行目2,_行列,_行2), ならびの位置指定置換(_行目2,_行1,_行列,_行列1), ならびの位置指定置換(_行目1,_行2,_行列1,X),!. 行基本変形(_乗数1 # _行目1 + _乗数2 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行1) , U is A * _乗数1),_乗算された行1), findall(W,(member(B,_行2) , W is B * _乗数2),_乗算された行2), 型推論加算([_乗算された行1,_乗算された行2],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形(_乗数1 # _行目1 - _乗数2 # _行目2,_行列,X) :- !, _乗数3 is -1 * _乗数2, 行基本変形(_乗数1 # _行目1 + _乗数3 # _行目2,_行列,X),!. 行基本変形( # _行目1 + _乗数 # _行目2,_行列,X) :- !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数),_乗算された行), 型推論加算([_乗算された行,_行1],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形( # _行目1 - _乗数 # _行目2,_行列,X) :- !, _乗数2 is -1 * _乗数, 行基本変形( # _行目1 + _乗数2 * _行目2,_行列,X),!. 行基本変形( # _行目1 + _乗数 / _除数 * _行目2,_行列,X) :- integer(_除数), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 // _除数),_除算された行), 型推論加算([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形( # _行目1 + _乗数 / _除数 # _行目2,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目2,_行列,_行2), list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行2) , U is A * _乗数 / _除数),_除算された行), 型推論加算([_行1,_除算された行],_加算された行), replace_nth(1,_行目1,_加算された行,_行列,X),!. 行基本変形( # _行目1 - _乗数 / _除数 # _行目2,_行列,X) :- !, _除数2 is -1 * _除数, 行基本変形( # _行目1 + _乗数 / _除数2 * _行目2,_行列,X),!. 行基本変形(_乗数 / _除数 # _行目,_行列,X) :- integer(_除数), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 // _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. 行基本変形(_乗数 / _除数 # _行目,_行列,X) :- \+(integer(_除数)), !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数 / _除数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. 行基本変形(_乗数 # _行目,_行列,X) :- !, list_nth(_行目,_行列,_行1), findall(X,(member(A,_行1) , X is A * _乗数),_行2), replace_nth(1,_行目,_行2,_行列,X),!. % *** user: 行基本変形 / 5 *** 行基本変形(*,_乗数,_行目,_行列,X) :- 行基本変形(*,_乗数,1,_行目,_行列,X). % *** user: 行基本変形 / 6 *** 行基本変形(*,_乗数,_行目,_行目,[_行1|R1],[_行2|R1]) :- findall(X,(member(A,_行1) , X is A * _乗数),_行2) . 行基本変形(*,_乗数,M,_行目,[_行|R1],[_行|R2]) :- M2 is M + 1, 行基本変形(*,_乗数,M2,_行目,R1,R2). % *** user: 正方行列の行列式の値 / 2 *** 正方行列の行列式の値(_正方行列,_行列式の値) :- ガウス行列に変形(_正方行列,X,Y), '行列式|C|の値'(X,Z1), ならびの積(Y,Z2), _行列式の値 is Z1 // Z2. % *** user: ならびの積 / 2 *** ならびの積([A],A) :- !. ならびの積([A|R],X) :- ならびの積(R,Y), X is A * Y. % *** user: '行列式|C|の値' / 2 *** '行列式|C|の値'(_行列,_値) :- length(_行列,Len), findall(U,(for(1,N,Len) , list_nth(N,_行列,_行) , list_nth(N,_行,U)),L), ならびの積(L,_値). 要素がゼロ以外に出会うまで([A|R],[],[A|R]) :- \+((A = 0;A=0.0)),!. 要素がゼロ以外に出会うまで([0|R],[0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 要素がゼロ以外に出会うまで([0.0|R],[0.0|R1],R2) :- 要素がゼロ以外に出会うまで(R,R1,R2). 最初に現れる0ではない要素・位置(Nth,[X|_],Nth,X) :- \+((X = 0;X=0.0)),!. 最初に現れる0ではない要素・位置(Mth,[0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X). 最初に現れる0ではない要素・位置(Mth,[0.0|R],Nth,X) :- Mth_2 is Mth + 1, 最初に現れる0ではない要素・位置(Mth_2,R,Nth,X). % *** user: ならびの位置指定置換 / 4 *** ならびの位置指定置換(1,A,[_|R],[A|R]) :- !. ならびの位置指定置換(N,A,[B|R1],[B|R2]) :- N1 is N - 1, ならびの位置指定置換(N1,A,R1,R2) . 最小公倍数(N1 * A,B,C) :- integer(B), 最小公倍数(A,B,C), N1 is C // A,!. 最小公倍数(A,N2 * B,C) :- integer(A), 最小公倍数(A,B,C), N2 is C // B,!. 最小公倍数(N1 * A,N2 * B,C) :- 最小公倍数(A,B,C), N1 is C // A, N2 is C // B,!. 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最小公倍数([N1 * A|R],X) :- findall(U,member(_ * U,[N1 * A|R]),L1), 最小公倍数(L1,X), 最小公倍数_2([N1 * A|R],X),!. 最小公倍数([A,B],X) :- 最小公倍数(A,B,X),!. 最小公倍数([A|R],X) :- 最小公倍数(R,B), 最小公倍数(A,B,X),!. 最小公倍数_2([],_) :- !. 最小公倍数_2([N * A|R],Y) :- N is Y // A, 最小公倍数_2(R,Y),!. 最小公倍数_2([A|R],Y) :- integer(A), 最小公倍数_2(R,Y),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). % 以下のサイトは # 出典 :: C/C++の宿題片付けます 127代目 # [1] 授業単元: c言語演習 # [2] 問題文(含コード&リンク): http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9478.txt gcd(M,N,N) :- 0 is M mod N,!. gcd(M,N,X) :- Mod is M mod N, gcd(N,Mod,X). gcd(M,N,O,X) :- gcd(M,N,Y), gcd(Y,O,X). % 以下のサイトは 相加平均(L,_相加平均) :- 算術平均(L,_相加平均). 算術平均([],N,S,M) :- M is S / N,!. 算術平均([A|R],N,S,M) :- S1 is S + A,算術平均(R,N,S1,M) . 算術平均(L,M) :- length(L,N),算術平均(L,N,0.0,M). 標準偏差([],N,M,S,V) :- V is sqrt(S / (N - 1)),!. 標準偏差([A|R],N,M,S,V) :- S1 is (A - M) ^ 2,S2 is S + S1,標準偏差(R,N,M,S2,V). 標準偏差(L,V) :- length(L,N),算術平均(L,M),標準偏差(L,N,M,0.0,V) . 平均偏差(L,_平均偏差) :- 算術平均(L,Avg), length(L,N), 平均偏差(L,Avg,0.0,Amd), _平均偏差 is Amd / N. 平均偏差([],_,X,X). 平均偏差([A|R1],Avg,Y,X) :- Y2 is Y + abs(A-Avg), 平均偏差(R1,Avg,Y2,X). 尖度(_標本,_尖度) :- length(_標本,_標本数), 算術平均(_標本,_算術平均), 分散(_標本,_分散), findsum(U,(member(A,_標本),U is (A-_算術平均) ^ 4),X1), _尖度 is X1 / ((sqrt(_分散) ^ 4) * _標本数). 尖度([],N,M,S1,S2,V) :- V is S2 / (M * S2 ^ 2). 尖度([A|R],N,M,S1,S2,V) :- S3 is (A - M) ^ 2, S4 is (A - M) ^ 4, S5 is S1 + S3, S6 is S2 + S4, 尖度(R,N,M,S5,S6,V). 分散(L,V) :- length(L,N), 算術平均(L,M), 分散(L,N,M,0.0e+00,V). 分散([],N,M,S,V) :- V is S / N,!. 分散([A|R],N,M,S,V) :- S1 is (A - M) ^ 2, S2 is S + S1, 分散(R,N,M,S2,V). 相乗平均(L,_相乗平均) :- 幾何平均(L,_相乗平均). 幾何平均([],N,S,M) :- M is exp(S / N),!. 幾何平均([A|R],N,S,M) :- S0 is ln(A), S1 is S + S0, 幾何平均(R,N,S1,M). 幾何平均(_標本ならび,_幾何平均) :- length(_標本ならび,_標本数), 幾何平均(_標本ならび,_標本数,0,_幾何平均). 加重平均(_標本ならび,_加重平均) :- findsum(_重み,member([_重み,_],_標本ならび),S), findsum(M,(member([A,B],_標本ならび),M is A * B),S2), _加重平均 is S2 / S,!. 偏差値(_母集合,_偏差値ならび) :- 加算(_母集合,_算術合計), length(_母集合,_ならびの長さ), _算術平均 is _算術合計 / _ならびの長さ, 標準偏差(_母集合,_標準偏差), findall(_偏差値,( member(_値,_母集合) , 偏差値(_値,_算術平均,_標準偏差,_偏差値)), _偏差値ならび). 偏差値(_標本値,_算術平均,_標準偏差,_偏差値) :- _偏差値 is 10 * (_標本値 - _算術平均) / _標準偏差 + 50. 中央値(_標本ならび,_中央値) :- medium(_標本ならび,_中央値). medium(L,_中央値) :- quicksort(L,L2), length(L2,Len), Len2 is Len // 2, medium(L2,Len2,_中央値). medium(L,Len,_中央値) :- append(L1,[_中央値|L2],L), length(L1,Len), length(L2,Len),!. medium(L,Len,_中央値) :- Len2 is Len - 1, append(L1,[_中央値1,_中央値2|L2],L), length(L1,Len2), length(L2,Len2), _中央値 is (_中央値1 + _中央値2) / 2. 最小公倍数(N1 * A,B,C) :- integer(B), 最小公倍数(A,B,C), N1 is C // A,!. 最小公倍数(A,N2 * B,C) :- integer(A), 最小公倍数(A,B,C), N2 is C // B,!. 最小公倍数(N1 * A,N2 * B,C) :- 最小公倍数(A,B,C), N1 is C // A, N2 is C // B,!. 最小公倍数(A,B,X) :- integer(A), integer(B), 最大公約数をユークリッドの互除法で求める(A,B,C), X is A * B // C. 最小公倍数([N1 * A|R],X) :- findall(U,member(_ * U,[N1 * A|R]),L1), 最小公倍数(L1,X), 最小公倍数_2([N1 * A|R],X),!. 最小公倍数([A,B],X) :- 最小公倍数(A,B,X),!. 最小公倍数([A|R],X) :- 最小公倍数(R,B), 最小公倍数(A,B,X),!. 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X).