このディレクトリの索引

% 以下のサイトは # 出典 :: C/C++の宿題片付けます 157代目 #602 # [1] 授業単元:配列 # [2] 問題文(含コード&リンク): 文字列を入力し、その文字列に含まれる英字、数字、その他の文字の数を出力せよ。 # '文字列を入力し、その文字列に含まれる英字、数字、その他の文字の数を出力せよ。' :- '文字列を入力し、'(_文字列), 'その文字列に含まれる英字、数字、その他の文字の数を出力せよ。'(_文字列). '文字列を入力し、'(_文字列) :- read_line_to_codes(user_input,Codes), atom_chars(_文字列,Codes). 'その文字列に含まれる英字、数字、その他の文字の数を出力せよ。'(_文字列) :- 'その文字列に含まれる英字、数字、その他の文字の数を'(_文字列,_英字の数,_数字の数,_その他の文字の数), 出力せよ(_英字の数,_数字の数,_その他の文字の数). 'その文字列に含まれる英字、数字、その他の文字の数を'(_文字列,_英字の数,_数字の数,_その他の文字の数) :- 文字ごとの種別判定行列を作る(_文字列,_文字ごとの種別判定行列), 列を合計したならび(_文字ごとの種別判定行列,[_英字の数,_数字の数,_その他の文字の数]). 文字ごとの種別判定行列を作る(_文字列,_文字ごとの種別判定行列) :- findall([A,B,C],( sub_atom(_文字列,_,1,_,_文字), 文字種判定(_文字,A,B,C)),_文字ごとの種別判定行列). 列を合計したならび(_行列,[_英字の数,_数字の数,_その他の文字の数]) :- 転置(_行列,_転置された行列), 転置された行の合計をならびに取る(_転置された行列,[_英字の数,_数字の数,_その他の文字の数]). 転置された行の合計をならびに取る(_転置された行列,_行の合計ならび) :- findall(S,( member(L,_転置された行列), sum_list(L,S)),_行の合計ならび). 出力せよ(_英字の数,_数字の数,_その他の文字の数) :- writef('英字の数は %w,数字の数は %w,その他の文字の数は %w\n',[_英字の数,_数字の数,_その他の文字の数]). 文字種判定(_文字,1,0,0) :- 英字(_文字),!. 文字種判定(_文字,0,1,0) :- 数字(_文字),!. 文字種判定(_文字,0,0,1). 英字(A) :- A @>='A',A @=< 'Z'; A @>='a',A @=< 'z'. 数字(A) :- A @>= '0', A @=< '9'. 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは 成績(尾崎,前期,国語,30). 成績(尾崎,前期,社会,40). 成績(山崎,前期,国語,20). 成績(山崎,前期,社会,50). 成績(尾崎,後期,国語,50). 成績(山崎,後期,国語,40). 集約合計を得る(_目標,_集約対象項,_集約鍵ならび,_集約値) :- 鍵となる値ならび(_集約鍵ならび,_目標,_鍵となる値ならび), 集約する鍵値毎に合計を得る(_目標,_集約対象項,_鍵となる値ならび,_集約鍵ならび,_集約値). 集約する鍵値毎に合計を得る(_目標,_集約対象項,_鍵となる値ならび,_集約鍵ならび,_集約値) :- member(_集約鍵ならび,_鍵となる値ならび), 対象項の合計をとる(_集約対象項,_目標,_集約値). 対象項の合計をとる(_対象項,_目標,_合計) :- findall(_対象項,_目標,L), 合計をとる(L,_合計). 鍵となる値ならび(_集約鍵ならび,_目標,_鍵となる値ならび) :- term_variables(_目標,_全ての変数ならび), setof(_集約鍵ならび,_全ての変数ならび ^ _目標,_鍵となる値ならび). % 実行例 合計をとる(L,_合計) :- 'Lが数値ならび場合、sum_listで合計を得る'(L,_合計). 合計をとる(L,_合計ならび) :- 'Lの要素がならびの場合、ならび要素ごとの合計ならびを得る'(L,_合計ならび). 'Lが数値ならび場合、sum_listで合計を得る'([],0). 'Lが数値ならび場合、sum_listで合計を得る'([A|R],_合計) :- number(A), sum_list([A|R],_合計). 'Lの要素がならびの場合、ならび要素ごとの合計ならびを得る'(L,_合計ならび) :- 'Lの要素がならびの場合'(L), ならび要素ごとの合計ならびを得る(L,_合計ならび). 'Lの要素がならびの場合'(L) :- L = [L1|R], is_list(L1). ならび要素ごとの合計ならびを得る(LL,_合計ならび) :- 転置(LL,LL2), '転置されたLL2の各要素をsum_listしたならびを得る'(LL2,_合計ならび). '転置されたLL2の各要素をsum_listしたならびを得る'(LL2,_合計ならび) :- findall(_合計,( member(L,LL2), sum_list(L,_合計)),_合計ならび). 転置([],[],[]):- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]):- 転置(R2,R3,R4). 転置([[]|_],[]):- !. 転置(L,[L1|R2]):- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは 縦書文書を横書文書に変形する(_縦書文書,_横書文書) :- 縦書文書を横書行ならびに変形する(_縦書文書,_横書き行ならび), atomic_list_concat(_横書行ならび,'\n',_縦書文書). 縦書文書を横書行ならびに変形する(_縦書文書,_横書き行ならび) :- 改行を区切りに行ならびに変形する(_縦書文書,_縦書行ならび), 縦書行ならびを横書行ならびに変形する(_縦書行ならび,_横書き行ならび). 縦書行ならびを横書行ならびに変形する(_縦書行ならび,_横書き行ならび) :- 縦書行ならびを反転した行文字ならびに変換(_縦書行ならび,_反転した行文字ならび), 転置(_反転した行文字ならび,_転置した行文字ならび), 転置した行文字ならびを横書き行ならびに変換(_転置した行文字ならび,_横書き行ならび). 縦書行ならびを反転した行文字ならびに変換(_縦書行ならび,_反転した行文字ならび) :- findall(_反転した文字ならび,( member(_行文字列,_縦書行ならび), 文字列を反転した文字ならびに変換(_行文字列,_反転した文字ならび)),_反転した行文字ならび). 文字列を反転した文字ならびに変換(_文字列,_反転した文字ならび) :- 文字列を反転した文字ならびに変換(_文字列,[],_反転した文字ならび). 文字列を反転した文字ならびに変換('',_反転した文字ならび,_反転した文字ならび) :- !. 文字列を反転した文字ならびに変換(_文字列,L1,_反転した文字ならび) :- 先頭文字と残り文字列(_文字列,_先頭文字,_残り文字列), 文字列を反転した文字ならびに変換(_残り文字列,[_先頭文字|L1],_反転した文字ならび). 先頭文字と残り文字列(_文字列,_先頭文字,_残り文字列) :- sub_atom(_文字列,0,1,_末尾からの変位,_先頭文字), sub_atom(_文字列,_,_末尾からの変位,0,_残り文字列). 改行を区切りに行ならびに変形する(_縦書文書,[_前文字列|R]) :- 改行を区切りに(_縦書文書,_前文字列,_後文字列), 改行を区切りに行ならびに変形する(_後文字列,R). 改行を区切りに行ならびに変形する(_文字列,R) :- 改行が存在しない場合停止する(_文字列,R). 改行が存在しない場合停止する('',[]) :- !. 改行が存在しない場合停止する(_文書,[_文書]). 改行を区切りに(_縦書文書,_前文字列,_後文字列) :- sub_atom(_縦書文書,_先頭からの変位,1,_末尾からの変位,'\n'), sub_atom(_縦書文書,0,_先頭からの変位,_,_前文字列), sub_atom(_縦書文書,_,_末尾からの変位,0,_後文字列),!. 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置した行文字ならびを横書き行ならびに変換(_転置した行文字ならび,_横書き行ならび) :- findall(_行文字列,( 空白行を取り除きながら行文字ならびを行文字列に変換する(_転置した行文字ならび,_行文字列)),_横書き行ならび). 空白行を取り除きながら行文字ならびを行文字列に変換する(_転置した行文字ならび,_行文字列) :- member(_行文字ならび,_転置した行文字ならび), 空白行ではない(_行文字ならび), atom_chars(_行文字列,_行文字ならび). 空白行ではない(_行文字ならび) :- \+(空白行(_行文字ならび)). 空白行(_行文字ならび) :- forall(member(_文字,_行文字ならび),_文字 = ' '). % 以下のサイトは # # 横書文書を縦書文書に変形する # # 事例として、あぜといへかの万葉仮名表記部分の生成 # 横書文書を縦書文書に変形する(_横書文書,_縦書文書) :- 横書文書を縦書文書に変形する(_横書文書,0,_縦書文書). 横書文書を縦書文書に変形する(_横書文書,_列間隔文字数,_縦書文書) :- 改行を区切りに行ならびに変形する(_横書文書,_行ならび), 行ならびを縦書文書に変形する(_行ならび,_列間隔文字数,_縦書文書). 行ならびを縦書文書に変形する(_行ならび,_列間隔文字数,_縦書文書) :- 最大文字列長を調べその長さに揃えて文書を矩形にする(_行ならび,_矩形ならび), 行ならびを転置する(_矩形ならび,_転置した矩形ならび), 矩形ならびの各要素行の内容を反転して縦書文書にする(_転置した矩形ならび,_列間隔文字数,_縦書文書). 矩形ならびの各要素行の内容を反転して縦書文書にする(_転置した矩形ならび,_列間隔文字数,_縦書文書) :- 矩形ならびの各要素行の内容を反転する(_転置した矩形ならび,_要素が反転した転置した矩形ならび), 縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書). 改行を区切りに行ならびに変形する(_横書文書,[_前文字列|R]) :- 改行を区切りに(_横書文書,_前文字列,_後文字列), 改行を区切りに行ならびに変形する(_後文字列,R). 改行を区切りに行ならびに変形する(_文字列,R) :- 改行が存在しない場合停止する(_文字列,R). 改行が存在しない場合停止する('',[]) :- !. 改行が存在しない場合停止する(_文書,[_文書]). 改行を区切りに(_横書文書,_前文字列,_後文字列) :- sub_atom(_横書文書,S,1,R,'\n'), sub_atom(_横書文書,0,S,_,_前文字列), sub_atom(_横書文書,_,R,0,_後文字列),!. 最大文字列長を調べその長さに揃えて文書を矩形にする(_行ならび,_矩形ならび) :- 最大文字列長を調べ(_行ならび,_最大文字列長), その長さに揃えて文書を矩形にする(_行ならび,_最大文字列長,_矩形ならび). 最大文字列長を調べ(_行ならび,_最大文字列長) :- findmax(_文字数,( member(_行,_行ならび), atom_length(_行,_文字数)),_最大文字列長). その長さに揃えて文書を矩形にする(_行ならび,_最大文字列長,_矩形ならび) :- findall(_空白を付加した文字列,( member(_行,_行ならび), 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_空白を付加した文字列)),_矩形ならび). 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_空白を付加した文字列) :- atom_length(_行,_文字列長), 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_文字列長,_空白を付加した文字列). 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_文字列長,_空白を付加した文字列) :- 達しない文字数の空白(_最大文字列長,_文字列長,_空白文字列), atom_concat(_行,_空白文字列,_空白を付加した文字列). 達しない文字数の空白(_最大文字列長,_文字列長,_空白文字列) :- _nth1 is _最大文字列長 - _文字列長, findall(' ',( between(1,_nth1,_)),_空白文字ならび), 文字ならびを文字列に変換する(_空白文字列,_空白文字ならび). 行ならびを転置する(_矩形ならび,_転置された矩形ならび) :- 矩形文字ならびに変換する(_矩形ならび,_矩形文字ならび), 転置(_矩形文字ならび,_転置された矩形文字ならび), 転置された矩形文字ならびを行ならびに変換(_転置された矩形文字ならび,_転置された矩形ならび). 矩形文字ならびに変換する(_矩形ならび,_矩形文字ならび) :- findall(_文字ならび,( member(_行,_矩形ならび), 文字列を文字ならびに変換する(_行,_文字ならび)),_矩形文字ならび). 転置された矩形文字ならびを行ならびに変換(_転置された矩形文字ならび,_転置された矩形ならび) :- findall(_文字列,( member(_文字ならび,_転置された矩形文字ならび), 文字ならびを文字列に変換する(_文字列,_文字ならび)),_転置された矩形ならび). 転置した矩形ならびの各行文字列を反転する(_転置した矩形ならび,_反転した行文字列) :- member(_行文字列,_転置した矩形ならび), 文字列の反転(_行文字列,_反転した行文字列). 矩形ならびの各要素行の内容を反転する(_転置した矩形ならび,_要素が反転した転置した矩形ならび) :- findall(_反転した行文字列,( member(_行文字列,_転置した矩形ならび), 文字列の反転(_行文字列,_反転した行文字列)),_要素が反転した転置した矩形ならび). 縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書) :- 列間隔文字を挟んで縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書). 列間隔文字を挟んで縦書文書に変形する(_矩形ならび,_列間隔文字数,_縦書文書) :- 列間隔文字を挟んで(_矩形ならび,_列間隔文字数,_矩形ならび_1), 縦書文書に変形する(_矩形ならび_1,_縦書文書). 列間隔文字を挟んで(_矩形ならび_1,_列間隔文字数,_矩形ならび_2) :- 列間隔文字(_列間隔文字数,_列間隔文字), findall(_行,( 行文字の間に列間隔文字を挿入する(_矩形ならび_1,_列間隔文字,_行)),_矩形ならび_2). 列間隔文字(_列間隔文字数,_列間隔文字) :- findall(' ',( between(1,_列間隔文字数,_)),_列間隔文字ならび), atomic_list_concat(_列間隔文字ならび,_列間隔文字). 行文字の間に列間隔文字を挿入する(_矩形ならび_1,_列間隔文字,_行) :- member(_行_1,_矩形ならび_1), 文字列を文字ならびに変換する(_行_1,_文字ならび), atomic_list_concat(_文字ならび,_列間隔文字,_行). 縦書文書に変形する(_矩形ならび_1,_縦書文書) :- atomic_list_concat(_矩形ならび_1,'\n',_縦書文書). 文字列の反転(_文字列,_反転した文字列) :- 文字列を文字ならびに変換する(_文字列,_文字ならび), 文字ならびを反転する(_文字ならび,_反転した文字ならび), 文字ならびを文字列に変換する(_反転した文字列,_反転した文字ならび). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 文字列を文字ならびに変換する(_文字列,_文字ならび) :- atom_chars(_文字列,_文字ならび). 文字ならびを反転する(_文字ならび,_反転した文字ならび) :- reverse(_文字ならび,_反転した文字ならび). 文字ならびを文字列に変換する(_反転した文字列,_反転した文字ならび) :- atom_chars(_反転した文字列,_反転した文字ならび). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). findmax(A,P,_最大値) :- findall(A,P,L), max_list(L,_最大値). % 以下のサイトは # # 横書文書を縦書文書に変形する # # 事例として、あぜといへかの万葉仮名表記部分の生成 # :- op(700,xfx,は). 横書文書を縦書文書に変形する(_横書文書,_縦書文書) :- 横書文書を縦書文書に変形する(_横書文書,0,_縦書文書). 横書文書を縦書文書に変形する(_横書文書,_列間隔文字数,_縦書文書) :- 改行を区切りに行ならびに変形する(_横書文書,_行ならび), 行ならびを縦書文書に変形する(_行ならび,_列間隔文字数,_縦書文書). 行ならびを縦書文書に変形する(_行ならび,_列間隔文字数,_縦書文書) :- 最大文字列長を調べその長さに揃えて文書を矩形にする(_行ならび,_矩形ならび), 行ならびを転置する(_矩形ならび,_転置した矩形ならび), 矩形ならびの各要素行の内容を反転して縦書文書にする(_転置した矩形ならび,_列間隔文字数,_縦書文書). 矩形ならびの各要素行の内容を反転して縦書文書にする(_転置した矩形ならび,_列間隔文字数,_縦書文書) :- 矩形ならびの各要素行の内容を反転する(_転置した矩形ならび,_要素が反転した転置した矩形ならび), 縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書). 改行を区切りに行ならびに変形する(_横書文書,[_前文字列|R]) :- 改行を区切りに(_横書文書,_前文字列,_後文字列), 改行を区切りに行ならびに変形する(_後文字列,R). 改行を区切りに行ならびに変形する(_文字列,R) :- 改行が存在しない場合停止する(_文字列,R). 改行が存在しない場合停止する('',[]) :- !. 改行が存在しない場合停止する(_文書,[_文書]). 改行を区切りに(_横書文書,_前文字列,_後文字列) :- 副文字列(_横書文書,_先頭からの変位,1,_末尾からの変位,'\n'), 副文字列(_横書文書,0,_先頭からの変位,_,_前文字列), 副文字列(_横書文書,_,_末尾からの変位,0,_後文字列),!. 最大文字列長を調べその長さに揃えて文書を矩形にする(_行ならび,_矩形ならび) :- 最大文字列長を調べ(_行ならび,_最大文字列長), その長さに揃えて文書を矩形にする(_行ならび,_最大文字列長,_矩形ならび). 最大文字列長を調べ(_行ならび,_最大文字列長) :- 解の最大値(_文字数,( 行ならびから行を取り出す(_行,_行ならび), 文字列長(_行,_文字数)),_最大文字列長). その長さに揃えて文書を矩形にする(_行ならび,_最大文字列長,_矩形ならび) :- 解を集める(_空白を付加した文字列,( 行ならびから行を取り出す(_行,_行ならび), 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_空白を付加した文字列)),_矩形ならび). 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_空白を付加した文字列) :- 文字列長(_行,_文字列長), 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_文字列長,_空白を付加した文字列). 最大文字列長に達しない部分は空白を付加する(_行,_最大文字列長,_文字列長,_空白を付加した文字列) :- 達しない文字数の空白(_最大文字列長,_文字列長,_空白文字列), 二つの文字列を結合する(_行,_空白文字列,_空白を付加した文字列). 達しない文字数の空白(_最大文字列長,_文字列長,_空白文字列) :- _最大文字列長と文字列長の差 は _最大文字列長 - _文字列長, 解を集める(' ',( 整数を順に生成する(1,_最大文字列長と文字列長の差,_)),_空白文字ならび), 文字ならびを文字列に変換する(_空白文字列,_空白文字ならび). 行ならびを転置する(_矩形ならび,_転置された矩形ならび) :- 矩形文字ならびに変換する(_矩形ならび,_矩形文字ならび), 転置(_矩形文字ならび,_転置された矩形文字ならび), 転置された矩形文字ならびを行ならびに変換(_転置された矩形文字ならび,_転置された矩形ならび). 矩形文字ならびに変換する(_矩形ならび,_矩形文字ならび) :- 解を集める(_文字ならび,( 矩形ならびから行を取り出す(_行,_矩形ならび), 文字列を文字ならびに変換する(_行,_文字ならび)),_矩形文字ならび). 転置された矩形文字ならびを行ならびに変換(_転置された矩形文字ならび,_転置された矩形ならび) :- 解を集める(_文字列,( 矩形文字ならびから文字ならびを取り出す(_文字ならび,_転置された矩形文字ならび), 文字ならびを文字列に変換する(_文字列,_文字ならび)),_転置された矩形ならび). 転置した矩形ならびの各行文字列を反転する(_転置した矩形ならび,_反転した行文字列) :- 要素の取り出し(_行文字列,_転置した矩形ならび), 文字列の反転(_行文字列,_反転した行文字列). 矩形ならびの各要素行の内容を反転する(_転置した矩形ならび,_要素が反転した転置した矩形ならび) :- 解を集める(_反転した行文字列,( 矩形ならびから行を取り出す(_行文字列,_転置した矩形ならび), 文字列の反転(_行文字列,_反転した行文字列)),_要素が反転した転置した矩形ならび). 縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書) :- 列間隔文字を挟んで縦書文書に変形する(_要素が反転した転置した矩形ならび,_列間隔文字数,_縦書文書). 列間隔文字を挟んで縦書文書に変形する(_矩形ならび,_列間隔文字数,_縦書文書) :- 列間隔文字を挟んで(_矩形ならび,_列間隔文字数,_矩形ならび_1), 縦書文書に変形する(_矩形ならび_1,_縦書文書). 列間隔文字を挟んで(_矩形ならび_1,_列間隔文字数,_矩形ならび_2) :- 列間隔文字(_列間隔文字数,_列間隔文字), 解を集める(_行,( 行文字の間に列間隔文字を挿入する(_矩形ならび_1,_列間隔文字,_行)),_矩形ならび_2). 列間隔文字(_列間隔文字数,_列間隔文字) :- 解を集める(' ',( 整数を順に生成する(1,_列間隔文字数,_)),_列間隔文字ならび), 文字列を結合する(_列間隔文字ならび,_列間隔文字). 行文字の間に列間隔文字を挿入する(_矩形ならび_1,_列間隔文字,_行) :- 矩形ならびから行を取り出す(_行_1,_矩形ならび_1), 文字列を文字ならびに変換する(_行_1,_文字ならび), 文字列を結合する(_文字ならび,_列間隔文字,_行). 縦書文書に変形する(_矩形ならび_1,_縦書文書) :- 文字列を結合する(_矩形ならび_1,'\n',_縦書文書). 文字列の反転(_文字列,_反転した文字列) :- 文字列を文字ならびに変換する(_文字列,_文字ならび), 文字ならびを反転する(_文字ならび,_反転した文字ならび), 文字ならびを文字列に変換する(_反転した文字列,_反転した文字ならび). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 副文字列(_文字列,_開始位置,_長さ,_残り文字数,_副文字列) :- sub_atom(_文字列,_開始位置,_長さ,_残り文字数,_副文字列). 矩形ならびから行を取り出す(_行,_矩形ならび) :- member(_行,_矩形ならび). 矩形文字ならびから文字ならびを取り出す(_文字ならび,_転置された矩形文字ならび) :- member(_文字ならび,_転置された矩形文字ならび). 行ならびから行を取り出す(_行,_行ならび) :- member(_行,_行ならび). 二つの文字列を結合する(_文字列_1,_文字列_2,_結合した文字列) :- atom_concat(_文字列_1,_文字列_2,_結合した文字列). 文字列を結合する(_文字列ならび,_挿入文字,_結合した文字列) :- atomic_list_concat(_文字列ならび,_挿入文字,_結合した文字列). 文字列を結合する(_文字列ならび,_結合した文字列) :- atomic_list_concat(_文字列ならび,_結合した文字列). 文字列を文字ならびに変換する(_文字列,_文字ならび) :- atom_chars(_文字列,_文字ならび). 文字ならびを反転する(_文字ならび,_反転した文字ならび) :- reverse(_文字ならび,_反転した文字ならび). 文字ならびを文字列に変換する(_反転した文字列,_反転した文字ならび) :- atom_chars(_反転した文字列,_反転した文字ならび). 文字列長(_文字列,_文字列長) :- atom_length(_文字列,_文字列長). 整数を順に生成する(1,_列間隔文字数,_) :- between(1,_列間隔文字数,_). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 解を集める(_候補項,_目標,_解ならび) :- findall(_候補項,_目標,_解ならび). 解の最大値(_候補項,_目標,_解の最大値) :- findall(_候補項,_目標,_解ならび), 最大値(_解ならび,_解の最大値). 最大値(_ならび,_最大値) :- select(_最大値,_ならび,_残りならび), forall(member(_値,_残りならび),_最大値 @>= _値). 解の最小値(_候補項,_目標,_解の最小値) :- findall(_候補項,_目標,_解ならび), 最小値(_解ならび,_解の最小値). 最小値(_ならび,_最小値) :- select(_最小値,_ならび,_残りならび), forall(member(_値,_残りならび),_最小値 @=< _値). _値 は _式 :- _値 is _式. % 以下のサイトは % [1] 授業単元:C言語演習課題 % http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9422.txt % 問題 % 年と月を「YYYY/MM」と入力し、入力された月のカレンダーを表示しなさい。 % % 1752年10月以前、及び10000年1月以降はエラーを返す。 % % 出力形式は以下のとおり % ・1行目は該当月の1日が月曜日でなければ、前月の最終月曜日から表示。 % ・該当月の最終日が日曜日でなければ、翌月の第1日曜日まで表示。 % ・6行目の表示が必要ない場合は表示しない。 % % うるう年判定は以下のとおり % ・年が4で割り切れる年はうるう年。 % ・年が100で割り切れる年はうるう年でない。 % ・年が400で割り切れる年はうるう年である。 % % [出力例] % 年月日を入力:2009/07 % % 月 火 水 木 金 土 日 % 29 30 01 02 03 04 05 % 06 07 08 09 10 11 12 % 13 14 15 16 17 18 19 % 20 21 22 23 24 25 26 % 27 28 29 30 31 01 02 課題のカレンダー(_年/_月) :- not((_年/_月 >= 1752/10,_年/_月 =< 10000/1)), write('エラー: 入力された年月は範囲を逸脱しています\n'),!. 課題のカレンダー(_年/_月) :- _年/_月 @=< 2009/6,!, 曜日検索(_日付,_曜日,2009/6/13,土曜), _日付=_年/_月/1, 課題のカレンダー表示(_日付,_曜日). 課題のカレンダー(_年/_月) :- _年/_月 @>= 2009/6,!, 曜日検索(2009/6/13,土曜,_日付,_曜日), _日付=_年/_月/1, 課題のカレンダー表示(_日付,_曜日). 課題のカレンダー表示(_年/_月/_日,月曜) :- 日付候補を得る(_年/_月/_日,_年/_月/_日,月曜,_日付整数ならび), 課題のカレンダー見出し表示, 課題のカレンダー週表示(_日付整数ならび). 課題のカレンダー表示(_年/_月/_日,_曜日) :- not(_曜日=月曜), 前週の月曜日(_年/_月/_日,_曜日,_前週の月曜日), 日付候補を得る(_年/_月/_日,_前週の月曜日,月曜,_日付整数ならび), 課題のカレンダー見出し表示, 課題のカレンダー週表示(_日付整数ならび). 前週の月曜日(_年/_月/_日,_曜日,_前週の月曜日) :- 曜日検索(_前週の月曜日,_前週の曜日,_年/_月/_日,_曜日), _前週の曜日 = 月曜,!. 日付候補を得る(_年/_月/_日,_起点日付,_曜日,_日付整数ならび) :- findall(_日付,( 曜日(_起点日付,_曜日,_日付2,_),(_日付2=_年2/_月2/7,_年2/_月2 @> _年/_月,!,fail;true)),_日付整数ならび). 課題のカレンダー週表示(_日付整数ならび) :- n個組(7,_日付整数ならび,_7個組), 月曜から日曜までヘッドゼロサプライで表示(_7個組). 月曜から日曜までヘッドゼロサプライで表示([_年/_月/_日]) :- ヘッドゼロサプライ(2,_日,_日付文字列), write_formatted('%t\n',[_日文字列]),!. 月曜から日曜までヘッドゼロサプライで表示([_年/_月/_日|R]) :- ヘッドゼロサプライ(2,_日,_日付文字列), write_formatted('%t ',[_日付文字列]), 月曜から日曜までヘッドゼロサプライで表示(R). 課題のカレンダー見出し表示 :- write_formatted('月 火 水 木 金 土 日\n'). 曜日検索(_日付,_曜日,_今日,_今日の曜日) :- var(_日付), var(_曜日), 前日・今日(_日付,_曜日,_今日,_今日の曜日). 曜日検索(_日付,_曜日,_今日,_今日の曜日) :- var(_日付), var(_曜日), 前日・今日(_前日,_前日の曜日,_今日,_今日の曜日), 曜日検索(_日付,_曜日,_前日,_前日の曜日). 曜日検索(_今日,_今日の曜日,_日付,_曜日) :- var(_日付), var(_曜日), 前日・今日(_今日,_今日の曜日,_日付,_曜日). 曜日検索(_今日,_今日の曜日,_日付,_曜日) :- var(_日付), var(_曜日), 前日・今日(_今日,_今日の曜日,_翌日,_翌日の曜日), 曜日検索(_翌日,_翌日の曜日,_日付,_曜日). '曜日'(_日付,_曜日,_日付,_曜日) :- ! . '曜日'(_日付1,_曜日1,_日付2,_曜日2) :- _日付1 @> _日付2, '前日・今日'(_日付3,_曜日3,_日付1,_曜日1), '曜日'(_日付3,_曜日3,_日付2,_曜日2) . '曜日'(_日付1,_曜日1,_日付2,_曜日2) :- _日付1 @< _日付2, '前日・今日'(_日付1,_曜日1,_日付3,_曜日3), '曜日'(_日付3,_曜日3,_日付2,_曜日2) . 前日・今日(_前日の年/12/31,_前日の曜日,_年/1/1,_曜日) :- 一つ違い(_前日の年,_年), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/2/29,_前日の曜日,_年/3/1,_曜日) :- うるう年(_年), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/2/28,_前日の曜日,_年/3/1,_曜日) :- not(うるう年(_年)), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/_前月/30,_前日の曜日,_年/_月/1,_曜日) :- 一つ違い(_前月,_月), member(_前月,[4,6,9,11]), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/_前月/31,_前日の曜日,_年/_月/1,_曜日) :- 一つ違い(_前月,_月), member(_前月,[1,3,5,7,8,10,12]), 曜日連鎖(_前日の曜日,_曜日),!. 前日・今日(_年/_月/_前日,_前日の曜日,_年/_月/_日,_曜日) :- 一つ違い(_前日,_日), 曜日連鎖(_前日の曜日,_曜日),!. 一つ違い(M,N) :- integer(M),!, N is M + 1. 一つ違い(M,N) :- integer(N),!, M is N - 1. うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100,!,fail. うるう年(_年) :- 0 is _年 mod 4,!. うるう年(_年) :- not(0 is _年 mod 4),fail. 曜日連鎖(月曜,火曜). 曜日連鎖(火曜,水曜). 曜日連鎖(水曜,木曜). 曜日連鎖(木曜,金曜). 曜日連鎖(金曜,土曜). 曜日連鎖(土曜,日曜). 曜日連鎖(日曜,月曜). n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. ヘッドゼロサプライ(N桁,_整数,_ヘッドゼロ整数文字列) :- number_chars(_整数,_数字ならび), ヘッドゼロサプライ_1(N桁,_数字ならび,_ヘッドゼロ整数文字ならび), concat_atom(_ヘッドゼロ整数文字ならび,_ヘッドゼロ整数文字列),!. ヘッドゼロサプライ_1(N桁,L,L) :- length(L,N桁),!. ヘッドゼロサプライ_1(N桁,L,['0'|R]) :- M桁 is N桁 - 1, ヘッドゼロサプライ_1(M桁,L,R). # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1200175247/550 # # [1] 授業単元: Ruby演習 [2] 問題文、http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9426.txt # Rubyの問題がわかりません 助けてください # # (1)曜日を表す英語と日本語との対応を表すハッシュwdayを定義しなさい # # p wday["sunday"] #=> "日曜日" # p wday["monday"] #=> "月曜日" # p wday["saturday"] #=> "土曜日" # # (2)ハッシュのメソッドを使って(1)のハッシュwdayのペアの数を数えなさい # # (3)eachメソッドと(1)のハッシュwdayを使って以下の文字列を出力させてくださ い。 # 「sunday」は日曜日のことです。 # 「monday」は月曜日のことです。 # # (4)ハッシュには配列の%wのようなものがありません。そこで、空白とタブと改行(正 規表現で定義するなら「/\uff3cs+/」)で区切られた文字列をハッシュに変換するメソ ッドstr2hashを定義してください。 # # p str2hash("bule 青 white 白\uff3cnred赤"); # #=> {"bule"=>"青", "white"=>"白", "red"=>"赤"} :- op(450,xfx,(=>)). % (1) wday({ "sunday" => "日曜日","monday" => "月曜日","saturday" #=> "土曜日"}). % (2) hash_count(Hashname,Count) :- functor(P,Hashname,1), call(P), arg(1,P,H), count(H,Count). count(','(A,B),Count) :- count(B,Count2), Count is Count2 + 1. count(A,1). % (3) ?- each(wday.A=>B),write_formatted('「%t」は%tのことです。\n',[A,B]),fail;true. each(Hashname.Key=>Value) :- functor(P,Hashname,1), arg(1,P,V), each(V,Key=>Value). each(','(Key=>Value,B),Key=>Value). each(','(_,B),Key=>Value) :- each(B,Key=>Value). each(Key=>Value,Key=>Value). % (4) str2hash(Atom,Hash) :- split(Atom,[' ','\t','\n'],L), findall(U,n個組(2,L,U),L2), hashを成長させる(L2,Hash). hashを成長させる([A,B],{ A=>B }) :- !. hashを成長させる([[A,B]|R], { (A=>B,R2) }) :- hashを成長させる(R,{ R2 }). n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/103 # # 【質問テンプレ】 # [1] 授業単元: C言語演習 # [2] 問題文(含コード&リンク): http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9753.txt # 2.入力された年月の1日が何曜日かを調べる。 #   曜日のチェックはZellerの公式を使用する。Zellerの公式は、 #    #   曜日を表す値=(y + [ y / 4 ] - [ y / 100 ] + [ y / 400 ] + [ (( 13 * m ) + 8 ) / 5 ] + d ) % 7 # #           ※ 上記の公式中の y は年、 m は月、 d は日を表し、 #             []はその数を越えない最大の整数を表す。(例: [13.6]は13になる) # #   で、曜日を表す値は次のようになっている。 # #     日曜日 = 0, 月曜日 = 1, 火曜日 = 2, 水曜日 = 3, # # 木曜日 = 4, 金曜日 = 5, 土曜日 = 6, # #   ※但し、1月と2月は前年の13月14月として計算するものとする。 % (1) 年月の入力 年月入力処理(_年,_月) :- 年入力処理(_年), 月入力処理(_月). % (2) 曜日計算 :- op(450,xfx,が),op(500,xfx,であり),op(600,xfx,ならば),op(450,xfx,は). 'Zellerの公式'(年 が Y であり 月 が M であり 日 が D ならば 曜日を表す値 は (Y + Y // 4 - Y // 100 + Y // 400 + ((( 13 * M ) + 8 ) // 5 ) + D ) mod 7). 曜日計算処理(_年,_月,_日,_曜日) :- 'Zellerの公式を用いて曜日を得る'(_年,_月,_日,_曜日). 'Zellerの公式を用いて曜日を得る'(_年,_月,_日,_曜日) :- 'Zellerの公式を用いて曜日を表す値を得る'(_年,_月,_日,_曜日を表す値), 曜日を表す値(_曜日を表す値,_曜日). 'Zellerの公式を用いて曜日を表す値を得る'(_年,1,_日,_曜日を表す値) :- _前年 is _年 - 1, 'Zellerの公式を用いて曜日を表す値を得る'(_前年,13,_日,_曜日を表す値),!. 'Zellerの公式を用いて曜日を表す値を得る'(_年,2,_日,_曜日を表す値) :- _前年 is _年 - 1, 'Zellerの公式を用いて曜日を表す値を得る'(_前年,14,_日,_曜日を表す値),!. 'Zellerの公式を用いて曜日を表す値を得る'(_年,_月,_日,_曜日を表す値) :- _年=Y,_月=M,_日=D, 'Zellerの公式'(年 が Y であり 月 が M であり 日 が D ならば 曜日を表す値 は _Zellerの公式), _曜日を表す値 is _Zellerの公式,!. 曜日を表す値(0,日曜). 曜日を表す値(1,月曜). 曜日を表す値(2,火曜). 曜日を表す値(3,水曜). 曜日を表す値(4,木曜). 曜日を表す値(5,金曜). 曜日を表す値(6,土曜). % (3) カレンダー表示 カレンダー表示 :- 年月入力処理(_年,_月), 'Zellerの公式を用いて曜日を表す値を得る'(_年,_月,1,_曜日を表す整数値), カレンダー表示データ編集(_年,_月,_曜日を表す整数値,_カレンダー表示文字列ならび), 要素に空白を挿入して全行表示(_カレンダー表示文字列ならび). カレンダー表示データ編集(_年,_月,_各月1日の曜日を表す整数値,_カレンダー表示文字列ならび) :- 年月文字列編集処理(_年,_月,_年月文字列), 月日数(_年,_月,_月日数), findall(S,for(1,N,_月日数),ヘッドゼロサプレス(2,N,S)),_表示日ならび), Length is _月日数 + _各月1日の曜日を表す整数値, M is (7 - (Length mod 7)), '7個組ならび'(Length,M,_表示日ならび,_7個組ならび), 見出しならび(_年月文字列,_見出しならび), append(_見出しならび,_7個組ならび,_カレンダー表示文字列ならび). 見出しならび(_年月文字列,[[_年月文字列],[日,月,火,水,木,金,土]]). '7個組ならび'(Length,0,_表示日ならび,_7個組ならび) :- length(L0,Length), すべての要素が(L0,' '), append(L0,_表示日ならび,L), '7個組'(L,_7個組ならび),!. '7個組ならび'(Length,M,_表示日ならび,_7個組ならび) :- not(M=0), length(L0,Length), すべての要素が(L0,' '), length(L2,M), すべての要素が(L2,' '), append(L0,_表示日ならび,L2,L), '7個組'(L,_7個組ならび),!. うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100,!,fail. うるう年(_年) :- 0 is _年 mod 4,!. うるう年(_年) :- not(0 is _年 mod 4),fail. 月日数(_年,2,29) :- うるう年(_年),!. 月日数(_年,2,28) :- not(うるう年(_年)),!. 月日数(_,_月,30) :- member(_月,[4,6,9,11]). 月日数(_,_月,31) :- member(_月,[1,3,5,7,8,10,12]). % (4) 基礎述語の定義 年入力処理(_年) :- write('表示したいカレンダーは西暦何年 ? '), get_line(_行), 年入力処理の二(_行,_年), 年入力検査(_年),!. 年入力処理(_年) :- 年入力処理(_年). 年入力処理の二(_行,_年) :- atom_to_term(_行,_年), integer(_年),!. 年入力処理の二(_行,_年) :- write_formatted('この入力[ %t ]は整数ではありません\n',[_行]), fail. 年入力検査(_年) :- _年 >= 1583, _年 =< 3999,!. 年入力検査(_年) :- write_formatted('この年を表す整数%tは不正です\n',[_年]), fail. 月入力処理(_月) :- write('月は ? '), get_line(_行), 月入力処理の二(_行,_月), 月入力検査(_月),!. 月入力処理(_月) :- 月入力処理(_月). 月入力処理の二(_行,_月) :- atom_to_term(_行,_月,_), integer(_月),!. 月入力処理の二(_行,_月) :- write_formatted('この入力[ %t ]は整数ではありません\n',[_行]), fail. 月入力検査(_月) :- _月 >= 1, _月 =< 12,!. 月入力検査(_月) :- write_formatted('この月を表す整数%tは不正です\n',[_月]), fail. 日付文字列編集処理(_年,_月,_日,_日付文字列) :- ヘッドゼロサプライ(2,_年,_年文字列), ヘッドゼロサプライ(2,_月,_月文字列), ヘッドゼロサプライ(2,_日,_日文字列), concat_atom([_年文字列,_月文字列,_日文字列],_日付文字列). 年月文字列編集処理(_年,_月,_年月文字列) :- ヘッドゼロサプライ(2,_年,_年文字列), ヘッドゼロサプライ(2,_月,_月文字列), concat_atom([_年文字列,_月文字列],_年月文字列). ヘッドゼロサプライ(N桁,_整数,_ヘッドゼロ整数文字列) :- number_chars(_整数,_数字ならび), ヘッドゼロサプライ_1(N桁,_数字ならび,_ヘッドゼロ整数文字ならび), concat_atom(_ヘッドゼロ整数文字ならび,_ヘッドゼロ整数文字列),!. ヘッドゼロサプライ_1(N桁,L,L) :- length(L,N桁),!. ヘッドゼロサプライ_1(N桁,L,['0'|R]) :- M桁 is N桁 - 1, ヘッドゼロサプライ_1(M桁,L,R). ヘッドゼロサプレス(N桁,_整数,_ヘッド空白整数文字列) :- number_chars(_整数,_数字ならび), ヘッドゼロサプレス_1(N桁,_数字ならび,_ヘッド空白整数文字ならび), concat_atom(_ヘッド空白整数文字ならび,_ヘッド空白整数文字列),!. ヘッドゼロサプレス_1(N桁,L,L) :- length(L,N桁),!. ヘッドゼロサプレス_1(N桁,L,[' '|R]) :- M桁 is N桁 - 1, ヘッドゼロサプレス_1(M桁,L,R). 要素に空白を挿入して全行表示([]) :- !. 要素に空白を挿入して全行表示([L|R]) :- concat_atom(L,' ',_表示行), write_formatted('%t\n',[_表示行]), 要素に空白を挿入して全行表示(R). すべての要素が([],_). すべての要素が([V|R],V) :- すべての要素が(R,V). '7個組'([],[]) :- !. '7個組'([A,B,C,D,E,F,G|R1]),[[A,B,C,D,E,F,G]|R2]) :- '7個組'(R1,R2). n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. not(P) :- \+(P). append([],L1,L2,L) :- append(L1,L2,L) . append([A|R1],L1,L2,[A|R]) :- append(R1,L1,L2,R) . concat_atom([],'') :- !. concat_atom([A],A) :- !. concat_atom([A|R],S) :- concat_atom(R,S1), atom_concat(A,S1,S). concat_atom([],_,'') :- !. concat_atom([A],_,A) :- !. concat_atom([A|R],_区切り文字列,S) :- concat_atom(R,_区切り文字列,S1), atom_concat(A,_区切り文字列,S2), atom_concat(S2,S1,S). # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/157 # # [1] 授業単元: C++ # [2] 問題文(含コード&リンク): # http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9762.txt # # 正数による正方行列のうち、全ての行、列、斜め列の合計が同じであり、 # かつ2回以上使用される数字が存在しないものを魔方陣という。 # 下図に示すa,bに数値を設定したときに、1〜9の整数によって構成される魔方陣を # 出力するプログラムを作成せよ。 # 但し、魔方陣が作成不可能な(a,b)の組み合わせが設定された場合は、「Impossible」 # と出力するとする。 # # la_lb_l__l # l__l__l__l # l__l__l__l # 魔方陣(N枡,A,B,_行列) :- 魔方陣のための行列の生成(N枡,_行列), _行列 = [[A,B|_],_,_], 行の合計が全て一致する(_行列,S), 列の合計が全て一致する(_行列,S), 正方行列の斜め要素の合計が一致する(_行列,S). 魔方陣のための行列の生成(N枡,_行列) :- N2 is N枡 ^ 2, findall(M,for(1,M,N2),NL),!, 順列(NL,N2,_順列数字ならび), findall(_N個組,n個組(N枡,_順列数字ならび,_N個組),_行列). 行の合計が全て一致する([],S) :- !. 行の合計が全て一致する([_行|R],S) :- 魔方陣の加算(_行,0,S), 行の合計が全て一致する(R,S). 列の合計が全て一致する(_行列,S) :- 行列の転置(_行列,_転置行列), 列の合計が全て一致する(_転置行列,S),!. 正方行列の斜め要素の合計が一致する(_正方行列,S) :- length(_行列,Len), 左上から右下方向の合計(1,Len,_正方行列,0,S), 右上から左下方向の合計(1,Len,_正方行列,0,S),!. 左上から右下方向の合計(M,N,_,S,S) :- M > N,!. 左上から右下方向の合計(M,N,_行列,S1,S) :- list_nth(M,_行列,_行), list_nth(M,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 左上から右下方向の合計(M2,N,_行列,S2,S),!. 右上から左下方向の合計(M,N,_,S,S) :- M > N,!. 右上から左下方向の合計(M,N,_行列,S1,S) :- M1 is N - M + 1, list_nth(M1,_行列,_行), list_nth(M1,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 右上から左下方向の合計(M2,N,_行列,S2,S),!. n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. 魔方陣の加算([],X,X) :- !. 魔方陣の加算([A|R],Y,X) :- Z is A + Y, 魔方陣の加算(R,Z,X). # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/566 # # [1] 授業単元:プログラミング # [2] 問題文(含コード&リンク): # 番号と点数を配列に初期化して、それらを # 5段階にランク付けをして、受験番号・ランクを表示するプログラムを作成。 # ランク付けをする部分を関数Rankとして、番号と評価を表示する部分を関数Outputとすること。 # なお、ランクの評価は0〜19点をE、20〜39点をD、40〜59点をC、 # 60〜79点をB、80〜100点をAとする。 # ただし、受験者の数は、50人以下とする。 # 番号と点数は、以下の配列を使用すること。 # 番号 int no[NUMBER]={1,2,3,4,5,6,7,8,9,10}; # 点数 int tensu[NUMBER]={45,21,60,81,70,99,0,10,20,100}; # '問題文の5段階にランク付け'('ランクの評価は0〜19点をE、20〜39点をD、40〜59点をC、 60〜79点をB、80〜100点をAとする。 '). 番号の定義文('番号 int no[NUMBER]={1,2,3,4,5,6,7,8,9,10};'). 点数の定義文('点数 int tensu[NUMBER]={45,21,60,81,70,99,0,10,20,100};'). 'ランクならびの生成'(_ランクならび) :- '問題文の5段階にランク付け'(_ランク定義文), ランクの定義文解析(_ランク定義文,_ランクならび). 番号ならびの生成(_番号ならび) :- 番号の定義文(_番号の定義文), 番号の定義文解析(_番号の定義文,_番号ならび). 点数ならびの生成(_点数ならび) :- 点数の定義文(_点数の定義文), 点数の定義文解析(_点数の定義文,_点数ならび). '5段階にランク付けをして、受験番号・ランクを表示する' :- ランクならびの生成(_ランクならび), 番号ならびの生成(_番号ならび), 点数ならびの生成(_点数ならび), '5段階にランク付けをして、受験番号・ランクを表示する'(_番号ならび,_点数ならび,_ランクならび). '5段階にランク付けをして、受験番号・ランクを表示する'([],[],_). '5段階にランク付けをして、受験番号・ランクを表示する'([_番号|R1],[_点数|R2],_ランクならび) :- append(_,[[_点数下限,_点数上限,_ランク]|_],_ランクならび), _点数 >= _点数下限, _点数 =< _点数上限, writef('受験番号:%t ランク:%t\n',[_番号,_ランク]), '5段階にランク付けをして、受験番号・ランクを表示する'(R1,R2,_ランクならび). ランクの定義文解析(_ランク定義文,_ランクならび) :- 全角数字を半角数字に変換(_ランク定義文,_半角数字変換されたランク定義文), split(_半角数字変換されたランク定義文,[' ','。','、','〜','点を','とする'],L), n個組(3,L,_ランクならび). 全角数字を半角数字に変換(_ランク定義文,_半角数字変換されたランク定義文) :- atom_chars(_ランク定義文,Chars), findall(_文字_1, append(_,[_文字|_],Chars), 全角数字ならば半角数字に変換(_文字,_文字_1)), Chars2), atom_chars(_半角数字変換されたランク定義文,Chars2). 全角数字ならば半角数字に変換([_全角数字|R1],[_半角数字|R2]) :- 全角数字半角数字変換(_全角数字,_半角数字), 全角数字ならば半角数字に変換(R1,R2). 全角数字ならば半角数字に変換([_文字|R1],[_文字|R2]) :- \+(全角数字半角数字変換(_文字,_)), 全角数字ならば半角数字に変換(R1,R2). 全角数字半角数字変換(0,0). 全角数字半角数字変換(1,1). 全角数字半角数字変換(2,2). 全角数字半角数字変換(3,3). 全角数字半角数字変換(4,4). 全角数字半角数字変換(5,5). 全角数字半角数字変換(6,6). 全角数字半角数字変換(7,7). 全角数字半角数字変換(8,8). 全角数字半角数字変換(9,9). 番号の定義文解析(_番号の定義文,_番号ならび) :- split(_番号の定義文,['=',',',';'],[_|_番号ならび]). 点数の定義文解析(_点数の定義文,_点数ならび) :- split(_点数の定義文,['=',',',';'],[_|_点数ならび]). % 以下のサイトは # 出典: プログラミングのお題スレ Part5 #252 # お題: # 整数n(0<=n<1000000)をソロバンのAAに変換するプログラムを書け # # n=9563なら # ######## # #oo|||o# # #||ooo|# # ######## # #||o|oo# # #oooo|o# # #oooooo# # #ooooo|# # #oo|ooo# # ######## # # 等幅フォントじゃないとちゃんと見れないけどごめんね '整数n(0<=n<1000000)をソロバンのAAに変換するプログラムを書け'(_n) :- '整数n(0<=n<1000000)をソロバンの'(_n,[],LL), 'AAに変換する'(LL). '整数n(0<=n<1000000)をソロバンの'(0,LL,LL) :- !. '整数n(0<=n<1000000)をソロバンの'(_n,LL1,LL) :- 一桁を天下に二分する(_n,[_1,_2,_3],[_4,_5,_6,_7,_8]), _n_2 is _n // 10, '整数n(0<=n<1000000)をソロバンの'(_n_2,[[_1,_2,_3,_4,_5,_6,_7,_8]|LL1],LL). 一桁を天下に二分する(_n,_天,_下) :- _n_1 is _n mod 10, _n_1_1 is _n_1 // 5, _n_1_2 is _n_1 mod 5, 天(_n_1_1,_天), 下(_n_1_2,_下). 天(0,['O','|']). 天(1,['|','O']). 下(0,['|','O','O','O','O']). 下(1,['O','|','O','O','O']). 下(2,['O','O','|','O','O']). 下(3,['O','O','O','|','O']). 下(4,['O','O','O','O','|']). 'AAに変換する'(LL) :- 梁(LL,_梁), 転置(LL,LL2), 枠の中に描く(_梁,LL2). 枠の中に描く(_梁,LL) :- writef('#%t#\n',[_梁]), forall(上から下まで枠と珠ならびを描く(_梁,LL,_表示行),writef('%t',[_表示行])), writef('#%t#\n',[_梁]). 上から下までの枠と珠ならびを描く(_梁,LL,_表示行) :- nth1(_nth1,LL,_横方向珠ならび), atomic_list_concat(_横方向珠ならび,_横方向珠文字列), 上から下までの枠と珠ならびを描く(_nth1,_梁,_横方向珠文字列,_表示行). 上から下までの枠と珠ならびを描く(4,_梁,_横方向珠文字列,_表示行) :- swritef(_表示行,'%t\n#%t#\n',[_梁,_横方向珠文字列]). 上から下までの枠と珠ならびを描く(_nth1,_梁,_横方向珠文字列,_表示行) :- \+(_nth1=4), swritef(_表示行,'#%t#\n',[_横方向珠文字列]). 梁(LL,_梁) :- length(LL,_幅), lenth(L,_幅), all(L,'#'), atom_chars(_梁,L). % 以下のサイトは # 出題場所 :: http://peace.2ch.net/test/read.cgi/tech/1402622093/549 # お題:数独の答を表す文字列が与えられたとき、'1'が各列の何行目にあるかを # いちばん左の列から順に調べて表示する。 # 入力 # 145327698 # 839654127 # 672918543 # 496185372 # 218473956 # 753296481 # 367542819 # 984761235 # 521839764 # # 出力 # 159438276 # # '数独の答を表す文字列が与えられたとき、1が各列の何行目にあるかをいちばん左の列から順に調べて表示する。'(_数独文字列,_列目,_行目) :- 数独文字列を数独に変換(_数独文字列,_数独), 転置(_数独,_転置された数独), forall('1が各列の何行目にあるかをいちばん左の列から順に調べて'(_転置された数独,_行目),write(_行目)). 数独文字列を数独に変換(_数独文字列,_数独) :- split(_数独文字列,['\n'],_数独文字列行ならび), findall(_数独行,( findall(_数,( sub_atom(_数独文字列,_,1,_,_文字), 数値に変換(_文字,_数)), _数独行)), _数独). '1が各列の何行目にあるかをいちばん左の列から順に調べて'(_転置された数独,_行目) :- nth1(_列目,_転置された数独,_列), nth1(_行目,_列,'1'). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは 魔方陣(_魔方陣) :- 魔方陣の構成要素を得る(_魔方陣,Ln1,Ln2,_数ならび), 魔方陣を構成してみる(Ln1,Ln2,_数ならび,_行_列_合計,_魔方陣), 魔方陣列検査(_魔方陣,_行_列_合計). 魔方陣の構成要素を得る(_魔方陣,Ln1,Ln2,_数ならび) :- length(_魔方陣,_n), length(Ln1,_n), length(Ln2,_n), _n掛けるn is _n * _n, findall(M,between(1,_n掛けるn,M),_数ならび). 魔方陣を構成してみる([],Ln2,_,_行の合計,[]). 魔方陣を構成してみる([_|Ln1],Ln2,_数ならび_1,_行の合計,[L|R]) :- 魔方陣の一行を得る(Ln2,_数ならび_1,L,_数ならび_2), sum_list(L,_行の合計), 魔方陣を構成してみる(Ln1,Ln2,_数ならび_2,_行の合計,R). 魔方陣の一行を得る([],_残り数ならび,[],_残り数ならび). 魔方陣の一行を得る([_|Ln],_数ならび_1,[_n|R4],_残り数ならび) :- select(_n,_数ならび_1,_数ならび_2), 魔方陣の一行を得る(Ln,_数ならび_2,R4,_残り数ならび). 魔方陣列検査(_行列,_行_列の合計) :- 転置(_行列,_転置行列), 行の合計が全て一致する(_転置行列,_行_列の合計). 行の合計が全て一致する([],_). 行の合計が全て一致する([L|R],S) :- sum_list(L,S), 行の合計が全て一致する(R,S). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは # S(1≦S≦10) # L(100≦L≦100) # 標準入力から以下の形式で与えられる # S L # # 例を参考にoとxを配置せよ # # 例 # 3 2 # oooxxx # oooxxx # oooxxx # xxxooo # xxxooo # xxxooo # # 2 3 # ooxxoo # ooxxoo # xxooxx # xxooxx # ooxxoo # ooxxoo # # 1 1 # o # # 2 1 # oo # :- dynamic(行パターン,1). 白(白). 黒(黒). '_行数 is S * L, S(1≦S≦10) L(100≦L≦100) 標準入力から以下の形式で与えられる S L' :- 'S Lを得る'(_s,_l), 表示パターンの形成(_s,_l,LL1), 出力する(LL1). 表示パターンの形成(_s,_l,_表示パターン) :- 行パターンの定義(_s,_l), 表の形成(_s,_l,_表示パターン), 転置して具体値を埋める(_表示パターン). 行パターンの定義(_s,_l) :- 白(_白), 黒(_黒), 行パターンの生成(_白,_黒,_s,_l), 行パターンの生成(_黒,_白,_s,_l). 行パターンの生成(_文字_1,_文字_2,_s,_l) :- length(Ln,_l), findall(文字,( 同一文字列トグル(Ln,_s,_文字_1,_文字_2,_文字)), _行パターン), assertz(行パターン(_行パターン)). 同一文字列トグル([_|_],_s,_文字,_,_文字) :- between(1,_s,_). 同一文字列トグル([_|Ln],_s,_文字_1,_文字_2,_文字) :- 同一文字列トグル(Ln,_s,_文字_2,_文字_1,_文字). 転置して具体値を埋める([L1|R]) :- 転置([L1|R],LL2), findall(L,( member(L,LL2), 行パターン(L)), LL2). 表の形成(_s,_l,[_行パターン|LL]) :- 行パターン(_行パターン),!, findall(L,( between(2,_l,_), length(L,_s)), LL). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 'S Lを得る'(S,L) :- get_line(Line), split(Line,[' '],[S,L]). 出力する(LL) :- flatten(LL,L), forall(member(A,L),format('~w\n',[A])). % 以下のサイトは 九九表([ [1,2,3,3,4,6,7,8,9], [2,4,6,8,10,12,14,16,18], [3,6,9,12,15,18,21,24,27], [4,8,12,16,20,24,28,32,36], [5,10,15,20,25,30,35,40,45], [6,12,18,24,30,36,42,48,54], [7,14,21,28,35,42,49,56,63], [8,16,24,32,40,48,56,64,72], [9,18,27,36,45,54,63,72,81]]). '「21÷7 の計算は、九九表をどのように辿れば答えがえられますか?」ならば全然問題がないように思いますが。'(_答え,_答えは何段目にある) :- 九九表を得る(_九九表), '7を段から辿るか、列から辿るかを決める'(_段経由または列経由), 九九表から7段目または7列目を取り出す(_段経由または列経由,_九九表,_取り出した段または列), '7段目または7列目経由で21を探しその要素位置が答えである'(_段経由または列経由,_取り出した段または列,_答え,_答えは何段目にある). 九九表を得る(_九九表) :- 九九表(_九九表). '7を段から辿るか、列から辿るかを決める'(段経由) :- 0 is random(7717) mod 2,!. '7を段から辿るか、列から辿るかを決める'(列経由). 九九表から7段目または7列目を取り出す(段経由,_九九表,_取り出した段または列) :- nth1(7,_九九表,_取り出した段または列). 九九表から7段目または7列目を取り出す(列経由,_九九表,_取り出した段または列) :- 転置(_九九表,_転置した九九表), nth1(7,_転置した九九表,_取り出した段または列). '7段目または7列目経由で21を探しその要素位置が答えである'(段経由,_取り出した段または列,_答え,7) :- nth1(_答え,_取り出した段または列,21). '7段目または7列目経由で21を探しその要素位置が答えである'(列経由,_取り出した段または列,_答え,_何段目) :- nth1(_何段目,_取り出した段または列,21), _答え = _何段目. 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは 九九表([ [1,2,3,3,4,6,7,8,9], [2,4,6,8,10,12,14,16,18], [3,6,9,12,15,18,21,24,27], [4,8,12,16,20,24,28,32,36], [5,10,15,20,25,30,35,40,45], [6,12,18,24,30,36,42,48,54], [7,14,21,28,35,42,49,56,63], [8,16,24,32,40,48,56,64,72], [9,18,27,36,45,54,63,72,81]]). '「21÷7 の計算は、九九表をどのように辿れば答えがえられますか?」ならば全然問題がないように思いますが。'(_答え) :- 九九表を得る(_九九表), '7を段から辿るか、列から辿るかを決める'(_段経由または列経由), 九九表から7段目または7列目を取り出す(_段経由または列経由,_九九表,_取り出した段または列), '21を探しその要素位置が答えである'(_取り出した段または列,_答え). 九九表を得る(_九九表) :- 九九表(_九九表). '7を段から辿るか、列から辿るかを決める'(段経由) :- 0 is random(7717) mod 2,!. '7を段から辿るか、列から辿るかを決める'(列経由). 九九表から7段目または7列目を取り出す(段経由,_九九表,_取り出した段または列) :- nth1(7,_九九表,_取り出した段または列). 九九表から7段目または7列目を取り出す(列経由,_九九表,_取り出した段または列) :- 転置(_九九表,_転置した九九表), nth1(7,_転置した九九表,_取り出した段または列). '21を探しその要素位置が答えである'(_取り出した段または列,_答え) :- nth1(_答え,_取り出した段または列,21). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは 九九表([ [1,2,3,3,4,6,7,8,9], [2,4,6,8,10,12,14,16,18], [3,6,9,12,15,18,21,24,27], [4,8,12,16,20,24,28,32,36], [5,10,15,20,25,30,35,40,45], [6,12,18,24,30,36,42,48,54], [7,14,21,28,35,42,49,56,63], [8,16,24,32,40,48,56,64,72], [9,18,27,36,45,54,63,72,81]]). '「21÷7 の計算は、九九表をどのように辿れば答えがえられますか?」ならば全然問題がないように思いますが。'(_答え) :- 九九表を得る(_九九表), 九九表から7段目または7列目を取り出す(_九九表,_取り出した段または列), '21を探しその要素位置が答えである'(_取り出した段または列,_答え). 九九表を得る(_九九表) :- 九九表(_九九表). 九九表から7段目または7列目を取り出す(_九九表,_取り出した段または列) :- nth1(7,_九九表,_取り出した段または列). 九九表から7段目または7列目を取り出す(_九九表,_取り出した段または列) :- 転置(_九九表,_転置した九九表), nth1(7,_転置した九九表,_取り出した段または列). '21を探しその要素位置が答えである'(_取り出した段または列,_答え) :- nth1(_答え,_取り出した段または列,21). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは 九九表([ [1,2,3,3,4,6,7,8,9], [2,4,6,8,10,12,14,16,18], [3,6,9,12,15,18,21,24,27], [4,8,12,16,20,24,28,32,36], [5,10,15,20,25,30,35,40,45], [6,12,18,24,30,36,42,48,54], [7,14,21,28,35,42,49,56,63], [8,16,24,32,40,48,56,64,72], [9,18,27,36,45,54,63,72,81]]). '「21÷7 の計算は、九九表をどのように辿れば答えがえられますか?」ならば全然問題がないように思いますが。'(_答え) :- 九九表を得る(_九九表), '21÷7 の計算は、九九表をどのように辿れば答えがえられますか?'(_九九表,_答え). '21÷7 の計算は、九九表をどのように辿れば答えがえられますか?'(_九九表,_答え) :- 九九表から7段目を取り出す(_九九表,_7段目), '7段目から21を探し列数を得る'(_7段目,_列数). '列数がすなわち答えである'(_列数,_答え),!. '21÷7 の計算は、九九表をどのように辿れば答えがえられますか?'(_九九表,_答え) :- 九九表から7列目を取り出す(_九九表,_7列目), '7列目から21を探し段数を得る'(_7列目,_段数). '段数がすなわち答えである'(_列数,_答え). 九九表を得る(_九九表) :- 九九表(_九九表). 九九表から7段目を取り出す(_九九表,_7段目) :- nth1(7,_九九表,_7段目). 九九表から7列目を取り出す(_九九表,_7列目) :- 転置(_九九表,_転置した九九表), nth1(7,_転置した九九表,_7列目). '7段目から21を探し列数を得る'(_7段目,_列数) :- nth1(_列数,_7段目,21). '7列目から21を探し段数を得る'(_7列目,_段数) :- nth1(_段数,_7列目,21). 列数がすなわち答えである(A,A). 段数がすなわち答えである(A,A). % 以下のサイトは # # 上部の基壇に幅をもたせたピラミッドの矩形 # # # _向き = 上向き, _頂点の高さ = 2, _上部の基壇の幅 = 3 の場合 # # *** # ***** # # _向き = 右向き, _頂点の高さ = 3, _上部の基壇の幅 = 2 の場合 # # * # ** # *** # *** # ** # * # ピラミッドの矩形(右向き,_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形) :- 下向きピラミッドの矩形を転置する(_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形),!. ピラミッドの矩形(左向き,_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形) :- 上向きピラミッドの矩形を転置する(_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形),!. ピラミッドの矩形(_向き,_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形) :- '上・下向きピラミッドの矩形を描く'(_向き,_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形). 下向きピラミッドの矩形を転置する(_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形) :- ピラミッドの矩形(下向き,_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形_1), 転置(_ピラミッドの矩形_1,_ピラミッドの矩形). 上向きピラミッドの矩形を転置する(_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形) :- ピラミッドの矩形(上向き,_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形_1), 転置(_ピラミッドの矩形_1,_ピラミッドの矩形). '上・下向きピラミッドの矩形を描く'(_向き,_頂点の高さ,_上部基壇の幅,_ピラミッドの矩形) :- _底辺の幅 is _頂点の高さ * 2 + _上部基壇の幅, length(L,_底辺の幅), findall(L4,( append(L1,L2,L), 行にピラミッドの文様を描く(_向き,_上部基壇の幅,L1,L2,L4)), _ピラミッドの矩形). 行にピラミッドの文様を描く(上向き,_上部基壇の幅,[A|L1],L2,L4) :- length(L0,_上部基壇の幅), append(L0,L1,L), 行にピラミッドの文様を描く(L,L2,L4). 行にピラミッドの文様を描く(下向き,_上部基壇の幅,L1,[A|L2],L4) :- length(L0,_上部基壇の幅), append(L0,L2,L), 行にピラミッドの文様を描く(L,L1,L4). 行にピラミッドの文様を描く(L1,L2,L4) :- all(L1,'*'), all(L2,' '), append(L3,L3,L2), append(L3,L1,L3,L4). ピラミッドの矩形を表示する([]). ピラミッドの矩形を表示する([L|R]) :- atomic_list_concat(L,A), writef('%t\n',[A]), ピラミッドの矩形を表示する(R). all([],_). all([A|R],A) :- all(R,A). append([],L2,L3,L4) :- append(L2,L3,L4). append([U|L1],L2,L3,[U|L4]) :- append(L1,L2,L3,L4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは ピラミッドの矩形(右向き,_頂点の高さ,_ピラミッドの矩形) :- 下向きピラミッドの矩形を転置する(_頂点の高さ,_ピラミッドの矩形),!. ピラミッドの矩形(左向き,_頂点の高さ,_ピラミッドの矩形) :- 上向きピラミッドの矩形を転置する(_頂点の高さ,_ピラミッドの矩形),!. ピラミッドの矩形(_向き,_頂点の高さ,_ピラミッドの矩形) :- '上・下向きピラミッドの矩形を描く'(_向き,_頂点の高さ,_ピラミッドの矩形). 下向きピラミッドの矩形を転置する(_頂点の高さ,_ピラミッドの矩形) :- ピラミッドの矩形(下向き,_頂点の高さ,_ピラミッドの矩形_1), 転置(_ピラミッドの矩形_1,_ピラミッドの矩形). 上向きピラミッドの矩形を転置する(_頂点の高さ,_ピラミッドの矩形) :- ピラミッドの矩形(上向き,_頂点の高さ,_ピラミッドの矩形_1), 転置(_ピラミッドの矩形_1,_ピラミッドの矩形). '上・下向きピラミッドの矩形を描く'(_向き,_頂点の高さ,_ピラミッドの矩形) :- _底辺の幅 is _頂点の高さ * 2 - 1, length(L,_底辺の幅), findall(L4,( append(L1,L2,L), 行にピラミッドの文様を描く(_向き,L1,L2,L4)), _ピラミッドの矩形). 行にピラミッドの文様を描く(上向き,[A|L1],L2,L4) :- all([A|L1],'*'), all(L2,' '), append(L3,L3,L2). append(L3,[A|L1],L3,L4). 行にピラミッドの文様を描く(下向き,L1,[A|L2],L4) :- all([A|L2],'*'), all(L1,' '), append(L3,L3,L1), append(L3,[A|L2],L3,L4). ピラミッドの矩形を表示する([]). ピラミッドの矩形を表示する([L|R]) :- atomic_list_concat(L,A), writef('%t\n',[A]), ピラミッドの矩形を表示する(R). all([],_). all([A|R],A) :- all(R,A). append([],L2,L3,L4) :- append(L2,L3,L4). append([U|L1],L2,L3,[U|L4]) :- append(L1,L2,L3,L4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは # 出題場所 :: http://toro.2ch.net/test/read.cgi/db/1371476534/487 # 次のようなデータがあります。 # tozai nihon # 関東 関東 # 関西 関西 # −− 関西 # 関西 関東 # −− 関東 # −− −− # 関東 関東 # 関西 関西 # # (−−)は空のデータ # # # tozaiとnihonではtozaiが優先されます。 # 例えば、tozai=関西,nihon=関東となっていた場合、tozaiが優先されるので「関西」と見なされます。 # この条件で、関東と関西のデータがそれぞれ何件あるか調査する為に次の3つのSQL文を出しました。 # これらを一つの文にまとめたいのですが、どのようにしたらよいでしょうか? # # select count(*) from hoge where tozai='関東' or (tozai='' and nihon='関東'); # 結果=3 # # select count(*) from hoge where tozai='関西' or (tozai='' and nihon='関西'); # 結果=4 # # select count(*) from hoge where tozai='' and nihon=''; # 結果=1 # # 'tozaiとnihonではtozaiが優先されます。 例えば、tozai=関西,nihon=関東となっていた場合、tozaiが優先されるので「関西」と見なされます。 この条件で、関東と関西のデータがそれぞれ何件あるか調査する為に次の3つのSQL文を出しました。 これらを一つの文にまとめたいのですが、どのようにしたらよいでしょうか?'(_関東,_関西,_どちらでもない) :- findall([N1,N2,N3], 'hogeのtozai,nohonからhoge_tableの値をえる'(N1,N2,N3),LL), 縦列を合計する(LL,_関東,_関西,_どちらでもない). 'hogeのtozai,nohonからhoge_tableの値をえる'(N1,N2,N3) :- hoge(_tozai,_nihon), hoge_select(_tozai,_hihon,N1,N2,N3). 縦列を合計する(LL,_関東,_関西,_どちらでもない) :- 転置(LL,[L1,L2,L3]), '転置された三つの行から_関東,_関西,_どちらでもないを求める'(L1,L2,L3,_関東,_関西,_どちらでもない). '転置された三つの行から_関東,_関西,_どちらでもないを求める'(L1,L2,L3,_関東,_関西,_どちらでもない). '転置された1行目の合計が_関東となる'(L1,_関東), '転置された2行目の合計が_関西となる'(L2,_関西), '転置された3行目の合計が_どちらでもないとなる'(L3,_どちらでもない), '転置された1行目の合計が_関東となる'(L1,_関東) :- sum_list(L1,_関東). '転置された2行目の合計が_関西となる'(L2,_関西) :- sum_list(L2,_関西). '転置された3行目の合計が_どちらでもないとなる'(L3,_どちらでもない) :- sum_list(L3,_どちらでもない). hoge_select('','',0,0,1). hoge_select('',関東,1,0,0). hoge_select('',関西,0,1,0). hoge_select(関東,_,1,0,0). hoge_select(関西,_,0,1,0). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは 加算の覆面演算行列([S,E,N,D,M,O,R,E,M,O,N,E,Y],[[0,S,E,N,D],[0,M,O,R,E],[M,O,N,E,Y]]). 加算の覆面算(_覆面ならび) :- 覆面に数字を当てはめる(_覆面ならび,[1,2,3,4,5,6,7,8,9,0]), 転置した覆面演算を反転したもの(_覆面ならび,LL), 加算(0,LL). 加算(_,[]). 加算(O,[L|R]) :- append(L0,[S],L2), list_sum(L0,S0), S is S0 mod 10, S2 is S0 // 10, 加算(S2,R). 覆面に数字を当てはめる([],_). 覆面に数字を当てはめる([_変数|R1],_数字ならび) :- 変数の場合は数字ならびから一つ数字を選択する(_変数,R1,_数字ならび). 覆面に数字を当てはめる([A|R1],_数字ならび) :- 既に定数の場合は読み飛ばす(A,R1,_数字ならび). 変数の場合は数字ならびから一つ数字を選択する(_変数,R1,_数字ならび,_残り数字ならび) :- var(_変数), select(_変数,_数字ならび,_残り数字ならび), 覆面に数字を当てはめる(R1,_残り数字ならび). 既に定数の場合は読み飛ばす(A,R1,_数字ならび) :- \+(var(A)), 覆面に数字を当てはめる(R1,_数字ならび). 転置した覆面演算を反転したもの(_覆面ならび,LL) :- 加算の覆面演算行列(_覆面ならび,LL1), 転置(LL1,LL2), reverse(LL2,LL). % 以下のサイトは # お題: # 入力 # AND # # 出力 # DDDDD # DNNND # DNAND # DNNND # DDDDD # 囲み(_入力) :- atom_chars(_入力,[_中心の文字|_囲み文字ならび]), 囲み(_囲み文字ならび,[[_中心の文字]],_囲み), 出力(_囲み). 囲み([],_囲み,_囲み) :- !. 囲み([_文字|R],_囲み_1,_囲み) :- 文字で囲む(_文字,_囲み_1,_囲み_2), 囲み(R,_囲み_2,_囲み). 文字で囲む(_文字,_囲み_1,_囲み_2) :- 囲みの先頭と末尾に_文字の行を付加する(_文字,_囲み_1,_先頭と末尾に_文字の行を付加された囲み_1), 囲みの各行の先頭と末尾に_文字を付加する(_文字,_先頭と末尾に_文字の行を付加された囲み_1,_囲み_2). 囲みの先頭と末尾に_文字の行を付加する(_文字,_囲み,_先頭と末尾に_文字の行を付加された囲み_1) :- 転置(_囲み_1,_転置された囲み_1), 行の先頭と末尾に文字を付加する(_文字,_転置された囲み_1,_行の先頭と末尾に_文字を付加された転置された囲み_1), 転置(_行の先頭と末尾に文字を付加された転置された囲み_1,_先頭と末尾に_文字の行を付加された囲み_1). 囲みの各行の先頭と末尾に_文字を付加する(_文字,_囲み,_行の先頭と末尾に_文字を付加された囲み) :- findall(_先頭と末尾に_文字を付加された行,( member(_行,_囲み), append([_文字|_行],[_文字],_先頭と末尾に_文字を付加された行)), _行の先頭と末尾に_文字を付加された囲み). 出力(_囲み) :- forall(member(_行,_囲み),(atomic_list_concat(_行,_行文字列),writef('%t\n',[_行文字列])). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % 以下のサイトは 行列から行を取り出す(_行列,_行) :- 行列から行を取り出す(_行列,_,_行). 行列から行を取り出す(_行列,_行目,_行) :- nth1(_行目,_行列,_行). 行列から列を取り出す(_行列,_列) :- 行列から列を取り出す(_行列,_nth1,_列). 行列から列を取り出す(_行列,_列目,_列) :- 転置(_行列,_転置された行列), nth1(_列目,_転置された行列,_列). 行列の位置要素を取り出す(_行列,_行目,_列目,_要素) :- nth1(_行目,_行列,_行), nth1(_列目,_行,_要素). 行列の要素を置換する(_行列,_置換対象値,_置換値,_置換された行列) :- findall(_置換された行,( member(_行,_行列), 行を全置換する(_行,_置換対象値,_置換値,_置換された行)), _置換された行列). 行を全置換する([],_,_,[]). 行を全置換する([A|R1],A,B,[B|R4]) :- 行を全置換する(R1,A,B,R4),!. 行を全置換する([C|R1],A,B,[C|R4]) :- 行を全置換する(R1,A,B,R4). 行列の位置要素を置換する(_行列,_行目,_列目,_値,_置換された行列) :- 行を取り出す(_行列,_行目,_それまでの行ならび,_行,_それより後の行ならび), 行の列要素を置換する(_行,_列目,_値,_置換された行),!, append(_それまでの行ならび,[_置換された行|_それより後の行ならび],_置換された行列). 行を取り出す(_行列,_行目,_それまでの行ならび,_行,_それより後の行ならび) :- _行目_1 is _行目 - 1, length(_それまでの行ならび,_行目_1), append(_それまでの行ならび,[_行|_それより後の行ならび],_行列). 行の列要素を置換する(_行,_列目,_値,_置換された行) :- _列目_1 is _列目 - 1, length(L0,_列目_1), append(L0,[_|R],_行), append(L0,[_値|R],_置換された行). 行列の行を入れ替える(_行列,_行目_1,_行目_2,_入れ替えた行列) :- _行目_1 > _行目_2, 行列の行を入れ替える(_行列,_行目_2,_行目_1,_入れ替えた行列). 行列の行を入れ替える(_行列,_行目_1,_行目_2,_入れ替えた行列) :- _行目_1 < _行目_2, 行列の行を取り出す(_行列,_行目_2,_前ならび_2,_行_2,_後ろならび_2), 行列の行を取り出す(_前ならび_2,_行目_1,_前ならび_1,_行_1,_後ろならび_1), append(_前ならび_1,[_行_2|_後ろならび_1],_前ならび_2_2), append(_前ならび_2_2,[_行_1|_後ろならび_2],_入れ替えた行列). 行列の行を取り出す(_行列,_行目_2,_前ならび_2,_行_2,_後ろならび_2) :- _行目_2_1 is _行目_2 - 1, length(_前ならび_2,_行目_2_1), append(_前ならび_2,[_行_2|_後ろならび_2],_行列). 行列の行を取り出す(_前ならび_2,_行目_1,_前ならび_1,_行_1,_後ろならび_1) :- _行目_1_1 is _行目_1 - 1, length(_前ならび_1,_行目_1_1), append(_前ならび_1,[_行_1|_後ろならび_1],_前ならび_2). 行列の列を入れ替える(_行列,_列目_1,_列目_2,_入れ替えた行列) :- 転置(_行列,_転置された行列), 行列の行を入れ替える(_転置された行列,_列目_1,_列目_2,_入れ替えた転置された行列), 転置(_入れ替えた転置された行列,_入れ替えた行列). 行全体をn倍する(_行列,_行目,_n倍,_行がn倍された行列) :- _行目_1 is _行目 - 1, length(L0,_行目_1), append(L0,[_行|R],_行列), 行要素全てをn倍する(_行,_n倍,_全ての要素がn倍された行), append(L0,[_全ての要素がn倍された行|R],_行がn倍された行列). 行要素全てをn倍する([],_,[]) :- !. 行要素全てをn倍する([A|R1],_n倍,[B|R2]) :- B is A * _n倍, 行要素全てをn倍する(R1,_n倍,R2). 列全体をn倍する(_行列,_列目,_n倍,_列がn倍された行列) :- 転置(_行列,_転置された行列), 行全体をn倍する(_転置された行列,_列目,_n倍,_行がn倍された転置された行列), 転置(_行がn倍された転置された行列,_列がn倍された行列). 二つの行のある列要素がそれぞれの最小公倍数になるように二つの行を倍する(_行列,_行目_1,_行目_2,_列目,_変形した行列) :- 行列の位置要素を取り出す(_行列,_行目_1,_列目,_要素_1), 行列の位置要素を取り出す(_行列,_行目_2,_列目,_要素_2), 最小公倍数を取る(_要素_1,_要素_2,_最小公倍数), _行目_1の倍数 is _最小公倍数 // _要素_1, _行目_2の倍数 is _最小公倍数 // _要素_2, 行全体をn倍する(_行列,_行目_1,_行目_1の倍数,_行列_2), 行全体をn倍する(_行列,_行目_2,_行目_2の倍数,_変形した行列). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1377511459/294 # # 縦横6マスのボックスがあります。 # 全てのマスを○×で埋めます。 # ○と×はそれぞれ連続2個まで繋がっててOK。 # 縦横の各列は○と×の数は同じにならなければいけない。 # ○と×の並び方が他の列と重複するのはNG。(縦と横を比較して同じなのはOK。縦と縦、横と横が同じ並びって言うのがNG) # これはどうやって解けばいいのか教えてください。 # # '縦横6マスのボックスがあります。 全てのマスを○×で埋めます。 ○と×はそれぞれ連続2個まで繋がっててOK。 縦横の各列は○と×の数は同じにならなければいけない。 ○と×の並び方が他の列と重複するのはNG。(縦と横を比較して同じなのはOK。縦と縦、横と横が同じ並びって言うのがNG) これはどうやって解けばいいのか教えてください。'(LL) :- 行候補ならびを得る(_行候補ならび), 面を規定する(LL), 転置(LL,_転置されたLL), 面候補を得る(_行候補ならび,LL), 転置診断(_転置されたLL,_行候補ならび). 行候補ならびを得る(_行候補ならび) :- findall(L,( 順列([○,○,○,×,×,×],6,L), \+(append(_,[A,A,A|_],L))), _重複があり得る行候補ならび), sort(_重複があり得る行候補ならび,_行候補ならび). 面を規定する(LL) :- length(LL,6), findall(L,( member(L,LL), length(L,6)), LL). 面候補を得る(_行候補ならび,[L1,L2,L3,L4,L5,L6]) :- member(L1,_行候補ならび), member(L2,_行候補ならび), member(L3,_行候補ならび), member(L4,_行候補ならび), member(L5,_行候補ならび), member(L6,_行候補ならび), sort([L1,L2,L3,L4,L5,L6],[_,_,_,_,_,_]). 転置診断(_転置されたLL,_行候補ならび) :- sort(_転置されたLL,[_,_,_,_,_,_]), findall(_,( member(L,_転置されたLL), member(L,_行候補ならび), \+(append(_,[A,A,A|_],L))), [_,_,_,_,_,_]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 順列(Y,0,[]). 順列(Y,N,[A|X]) :- del(A,Y,Z), M is N - 1, 順列(Z,M,X). del(A,[A|X],X). del(A,[B|X],[B|Y]) :- del(A,X,Y). % 以下のサイトは # # キーボードからNを入力し、Sum = 1の4乗 + 2の4乗 + ... + Nの4乗 を表示しなさい # 'キーボードからNを入力し、Sum = 1の4乗 + 2の4乗 + ... + Nの4乗 を表示しなさい' :- 'キーボードからNを入力し、'(_N), 'Sum = 1の4乗 + 2の4乗 + ... + Nの4乗 を表示しなさい'(_N). 'キーボードからNを入力し、'(_N) :- 整数を得る('N',_N > 2,_N). 'Sum = 1の4乗 + 2の4乗 + ... + Nの4乗 を計算して、表示しなさい'(_N) :- 'Sum = 1の4乗 + 2の4乗 + ... + Nの4乗 を計算して、'(_N,_式表示文字列,_Sum), 表示しなさい(_Sum,_式表示文字列). 'Sum = 1の4乗 + 2の4乗 + ... + Nの4乗 を計算して、'(_N,_式表示文字列,_Sum) :- '1の4乗 + 2の4乗 + ... + Nの4乗 を'(_N,_式文字列,_式表示文字列), 計算して(_式文字列,_Sum). '1の4乗 + 2の4乗 + ... + Nの4乗 を'(_N,_式文字列,_式表示文字列) :- findall([_4乗項文字列,_4乗表示文字列],( between(1,_M,_N), atomic_list_concat([_M,の4乗],_4乗表示文字列), atomic_list_concat([_M,' ^ ',4],_4乗項文字列)), LL), 式文字列と式表示文字列を分離(LL,_式文字列,_式表示文字列). 式文字列と式表示文字列を分離(LL,_式文字列,_式表示文字列) :- 転置(LL,[L1,L2]), atomic_list_concat(L1,' + ',_式文字列), atomic_list_concat(L2,' + ',_式表示文字列). 計算して(_式文字列,_Sum) :- atom_to_term(_式文字列,_式,_), _Sum is _式. 表示しなさい(_Sum,_式表示文字列) :- writef('%t = %t\n',[_Sum,_式文字列]). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1232627790/958 # # 【 課題 】テキストファイルから文字列5行を読み込み、別のテキストへ右縦書きで書き出す # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 期限 】7/14 am6:00 # 【 Ver  】Eclipse Version: 3.4.2 # 【 補足 】 # あいう # かきく # さしす # 上記のようなテキストファイルを読み込み、 # さかあ # しきい # すくう # のように別のテキストファイルに書き出す感じです。 'テキストファイルから文字列5行を読み込み、別のテキストへ右縦書きで書き出す'(InFile,OutFile) :- テキストファイルから文字列5行を読み込み(Infile,_文字列5行), 別のテキストへ右縦書きで(_文字列5行,_右書き用に置換された文字列ならび), 書き出す(OutFile,_右書きように置換された文字列ならび), テキストファイルから文字列5行を読み込み(Infile,_文字列5行) :- open(InFile,read,Instream), findall(_行,( between(1,5,N), get_line(Instream,_行)), _文字列5行), close(InFile). 別のテキストへ右縦書きで(_文字列5行,_右書き用に置換された文字列ならび) :- findmax(_行の長さ,( member(_行,_文字列5行), atom_length(_行,_行の長さ), _最長文字数), 空白文字を付加して文字数一致させる(_最長文字数,_文字列5行,_空白文字を付加して矩形にした文字列5行), 右書き用に置換する(_空白文字を付加して矩形にした文字列5行,_右書き用に置換された文字列ならび). 右書き用に置換する(_空白文字を付加して矩形にした文字列5行,_右書き用に置換された文字列ならび) :- 行を反転しながら転置する(_空白文字を付加して矩形にした文字列5行,_右書き用に置換された文字列ならび). 行を反転しながら転置する(_空白文字を付加して矩形にした文字列5行,_右書き用に置換された文字列ならび) :- '一旦文字ならびに変換して、行を反転して転置する'(_空白文字を付加して矩形にした文字列5行,LL2), 文字列に戻す(LL2,_右書き用に置換された文字列ならび). '一旦文字ならびに変換して、行を反転して転置する'(_空白文字を付加して矩形にした文字列5行,LL2) :- findall(L,( member(_行,_空白文字を付加して矩形にした文字列5行), atom_chars(_行,Chars), reverse(Chars,L)), LL1), 転置(LL1,LL2). 文字列に戻す(LL2,_右書き用に置換された文字列ならび) :- findall(_文字列,( member(Chars,LL2), atom_chars(_文字列,Chars)), _右書き用に置換された文字列ならび). 空白文字を付加して文字数を一致させる(_最大文字数,_文字列5行,_空白を付加した文字列5行) :- findall(_空白を付加された文字列,( member(_文字列,_文字列5行), atom_length(_文字列,_文字列長さ), 空白文字を付加する(_最大文字数,_文字列の長さ,_文字列,_空白を付加された文字列)), _空白を付加された文字列5行). 空白文字を付加する(_最大文字数,_文字列の長さ,_文字列,_空白を付加された文字列) :- _空白文字数 is _最大文字数 - _文字列の長さ, findall(' ',between(1,_空白文字数,_),_空白文字ならび), atomic_list_concat([_文字列|_空白文字ならび],_空白を付加された文字列). 書き出す(OutFile,_右書き用に置換された文字列ならび) :- open(OutFile,write,Outstream), append(_,[_行|R],_右書き用に置換された文字列ならび), writef(Outstream,'%t\n',[_行]), R = [], close(Outstream). % % この符にはfindall/3だけで表現するという主題がある。 % % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1361082416/727 # # [1] 授業単元: 暇つぶし # [2] 問題文:迷路を解くプログラム。 #  下記のようなテキストを入力とし、スタートからゴールまでの道を表示してください。 # ----- ここからテキスト ----- # 5 5 # sxrrr # rxrrr # rrrxr # rrxgr # ----- ここまでテキスト ----- #  テキストの1行目は順番に迷路の横幅と縦幅を表します。 #  二行目以降は迷路を表しており、sはスタート、gはゴール、xは壁、rは道を表します。 #  壁は通り抜けることはできず、道を通る必要があります。迷路の端は壁として扱います。 #  表示の仕様は以下の通り。ゴールまでの道がないと判断した場合はNot Foundと表示。 # 1 step # sxrrr # +xrrr # rrrxr # rrxgr # <中略> # 9 step # sxrrr # +x+++ # +++x+ # rrxg+ # '問題文:迷路を解くプログラム。  下記のようなテキストを入力とし、スタートからゴールまでの道を表示してください。 ----- ここからテキスト ----- 5 5 sxrrr rxrrr rrrxr rrxgr ----- ここまでテキスト -----  テキストの1行目は順番に迷路の横幅と縦幅を表します。  二行目以降は迷路を表しており、sはスタート、gはゴール、xは壁、rは道を表します。  壁は通り抜けることはできず、道を通る必要があります。迷路の端は壁として扱います。  表示の仕様は以下の通り。ゴールまでの道がないと判断した場合はNot Foundと表示。 1 step sxrrr +xrrr rrrxr rrxgr <中略> 9 step sxrrr +x+++ +++x+ rrxg+ '(_テキスト) :- 'テキストを入力とし、スタートからゴールまでの道を表示してください。'(_テキスト). 'テキストを入力とし、スタートからゴールまでの道を表示してください。'(_テキスト) :- テキストを入力とし(_テキスト,LL1,LL2), スタートからゴールまでの(LL1,LL2,_スタートからゴールまでの道順), '道を表示してください。'(_スタートからゴールまでの道順,LL1). スタートからゴールまでの(LL1,LL2,_スタートからゴールまでの道順) :- スタートを探す(LL1,LL2,_スタートの行,_スタートの列), ゴールを探す(LL1,LL2,_ゴールの行,_ゴールの列), 隣に移動する(_スタートの行,_スタートの列,_ゴールの行,_ゴールの列,LL1,LL2,[],_スタートからゴールまでの道順). テキストを入力とし(_テキスト,LL1,LL2) :- get_lines(_テキスト,[_不要要素|_行ならび]), findall(_文字ならび,( member(_一行,_行ならび), atom_chars(_一行,_文字ならび)), LL1), 転置(LL1,LL2). スタートを探す(LL1,LL2,_スタートの行,_スタートの列) :- nth1(_スタートの行,LL1,L), nth1(_スタートの列,L,s). ゴールを探す(LL1,LL2,_ゴールの行,_ゴールの列) :- nth1(_ゴールの行,LL1,L), nth1(_ゴールの列,L,g). 隣に移動する(_ゴールの行,_ゴールの列,_ゴールの行,_ゴールの列,LL1,LL2,_,[[_ゴールの行,_ゴールの列]]). 隣に移動する(_行,_列,_ゴールの行,_ゴールの列,LL1,LL2,_履歴1,[[_行,_列]|R]) :- 移動可能な隣接点を得る(_行,_列,LL1,LL2,_隣の行,_隣の列), \+(member([_隣の行,_隣の列],_履歴1)), 隣に移動する(_隣の行,_隣の列,_ゴールの行,_ゴールの列,LL1,LL2,[[_行,_列]|_履歴1],R). 移動可能な隣接点を得る(_行,_列,LL1,LL2,_行,_隣の列) :- 行の移動可能な隣接点(_行,_列,LL1,LL2,_行,_隣の列). 移動可能な隣接点を得る(_行,_列,LL1,LL2,_行,_隣の列) :- 列の移動可能な隣接点(_行,_列,LL1,LL2,_行,_隣の列). 行の移動可能な隣接点(_行,_列,LL1,LL2,_行,_隣の列) :- nth1(_行,LL1,L), length([_|L0],_列), append(L0,[_|R],L), 移動可能な隣接点(L0,R,_隣の列). 列の移動可能な隣接点(_行,_列,LL1,LL2,_隣の行,_隣の列) :- nth1(_列,LL2,L), length([_|L0],_行), append(L0,[_|R],L), 移動可能な隣接点(L0,R,_隣の行). 移動可能な隣接点(L0,R,_隣) :- last(L0,r), length(L0,_隣). 移動可能な隣接点(L0,R,_隣) :- R = [r|_], length([_,_|L0],_隣). '道を表示してください。'(_スタートからゴールまでの道順,LL) :- append(LL0,[[_行,_列]|RR],_スタートからゴールまでの道順), length([_|LL0],_ステップ), write('%t\n',[_ステップ]), '通過点を+に置換してLLを表示する'(_行,_列,LL), R = []. '通過点を+に置換してLLを表示する'(_行,_列,LL) :- append(L0,[L1|R],LL), length([_|L0],_行_1), 列の置換(_行_1,_行,_列,L1,L2), ならびを文字列に変換して表示(L2), R = []. 列の置換(_行,_行,_列,L1,L2) :- length([_|L0],_列), append(L0,[_|R],L1), append(L0,[+|R],L2),!. 列の置換(_,_,_,L,L). ならびを文字列に変換して表示(L) :- atomic_list_concat(L,S), writef('%t\n',[S]). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは # # ある専門学校の受験資格のデシジョンテーブル # # <条件> 1 2 3 4 5 6 7 8 # # 体重が軽い N N N N Y Y Y Y # 体が柔らかい N N Y Y N Y N Y # 敏捷である N Y Y N N N Y Y # # <行動> # # 受験資格がある X # 受験資格がない X X X X X X X 体重が軽い(偽,偽,偽,偽,真,真,真,真). 体が柔らかい(偽,偽,真,真,偽,真,偽,真). 敏捷である(偽,真,真,偽,偽,偽,真,真). 受験資格がある(偽,偽,偽,偽,偽,偽,偽,真). 受験資格がない(真,真,真,真,真,真,真,偽). デシジョンテーブル(_アリティ,_条件述語名ならび,_真偽値ならび,_行動述語名ならび,_nth1,_行動ならび) :- デシジョンテーブル引数を取得して転置する(_アリティ,_条件述語名ならび,LL2), nth1(_nth1,LL2,_真偽値ならび), 行動述語から行動ならびを得る(_アリティ,_nth1,_行動述語名ならび,_行動ならび). デシジョンテーブル引数を取得して転置する(_アリティ,_条件述語名ならび,LL2) :- findall(_引数ならび,( member(_条件述語名,_条件述語名ならび), length(_引数ならび,_アリティ), P =.. [_条件述語名|_引数ならび], call(P)), LL2), 転置(LL1,LL2). 行動述語から行動ならびを得る(_アリティ,_nth1,_行動述語名ならび,_行動ならび) :- findall(_行動,( '行動述語の_nth1引数を得る'(_アリティ,_nth1,_行動述語名ならび,_行動)), _行動ならび). '行動述語の_nth1引数を得る'(_アリティ,_nth1,_行動述語名ならび,_行動) :- member(_行動述語名,_行動述語名ならび), length(L,_アリティ), P =.. [_行動述語名|L], call(P), nth1(_nth1,L,_行動). 転置([],[],[]):- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]):- 転置(R2,R3,R4). 転置([[]|_],[]):- !. 転置(L,[L1|R2]):- 転置(L,L2,L1), 転置(L2,R2) . % % ?- デシジョンテーブル(8,[体重が軽い,体が柔らかい,敏捷である],[真,偽,真],[受験資格がある],_nth1,_行動ならび). % % _nth1 = 7, % _行動ならび = [偽] % % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/140 # # [1] 授業単元: Cプロ # [2] 問題文(含コード&リンク): # 3行3列の行列aを入力後、余因子行列で行列値|a|を求める # '3行3列の行列aを入力後、余因子行列で行列値|a|を求める' :- '3行3列の行列aを入力'(_a), '余因子行列で行列値|a|を求める'(_a,_行列式_aの値), writef('行列値|a|は%tです。\n',[_行列式_aの値]). '3行3列の行列aを入力'(_a) :- length(_a,3), findall(L,( nth1(_nth1,_a,L), length(L,3), '3列入力する'(_nth1,1,L)), _a). '3列入力する'(_,_,[]). '3列入力する'(_行位置,_列位置,[V|R]) :- writef('列入力[%t][%t] : ',[_行位置,_列位置]), get_line(Line), atom_to_term(Line,V,_), _列位置_2 is _列位置 + 1, '3列入力する'(_行位置,_列位置_2,R). '余因子行列を使って逆行列を得る'(_n,_正方行列,_逆行列) :- '余因子行列で行列値|a|を求める'(_正方行列,_行列式の値), 余因子行列(_n,_正方行列,_余因子行列), 転置(_余因子行列,_転置された余因子行列), 行列のすべての要素に値を掛ける(1,_n,_転置された余因子行列,1 / _行列式の値,_逆行列). 行列のすべての要素に値を掛ける(_行目,_n,LL,_,LL) :- _行目 > _n,!. 行列のすべての要素に値を掛ける(_行目,_n,LL1,_乗数 / _除数,LL2) :- '行基本変形'(_乗数 / _除数 # _行目,LL1,LL3), _行目_2 is _行目 + 1, 行列のすべての要素に値を掛ける(_行目_2,_n,LL3,_乗数 / _除数,LL2). '余因子行列で行列値|a|を求める'(_a,_行列式_aの値) :- 余因子行列(_a,_余因子行列), _a = [_aの第一行|_], _余因子行列 = [_余因子行列の第一行|_], '二つのならびの積の和'(_aの第一行,_余因子行列の第一行,_行列式_aの値). '二つのならびの積の和'([],[],0). '二つのならびの積の和'([A|R1],[B|R2],S) :- '二つのならびの積の和'(R1,R2,S_1), S is S_1 + A * B. 余因子行列(_正方行列,_余因子行列) :- length(_正方行列,_n), 余因子行列(_n,_正方行列,_余因子行列). 余因子行列(_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). 行列式の値(1,[[_]],1) :- !. 行列式の値(2,_正方行列,_行列式の値) :- 二つの対角要素の積の差を得る(_n,_正方行列,_行列式の値),!. 行列式の値(_n,_正方行列,_行列式の値) :- '余因子行列で行列値|a|を求める'(_正方行列,_行列式の値). 余因子(_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列を取り除いた行列式の値'(_n,_正方行列,_i,_j,_n_1次正方行列の行列式の値), 'i,jから乗数を得る'(_i,_j,_乗数), _余因子 is _乗数 * _n_1次正方行列の行列式の値. '正方行列からi行j列を取り除いた行列式の値'(_n,_正方行列,_i,_j,_n_1次正方行列の行列式の値) :- '正方行列から第i行と第j列を取り除く'(_正方行列,_i,_j,_n_1次正方行列), _n_1 is _n - 1, 行列式の値(_n_1,_n_1次正方行列,_n_1次正方行列の行列式の値). '正方行列から第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行が取り除かれた行列). 二つの対角要素の積の差を得る(0,[],1) :- !. 二つの対角要素の積の差を得る(1,[[N]],N) :- !. 二つの対角要素の積の差を得る(_n,_正方行列,_二つの対角要素の積の差) :- 二つの対角要素の積を得る(_正方行列,_右下がり対角要素の積,_右上がり対角要素の積), _二つの対角要素の積の差 is _右下がり対角要素の積 - _右上がり対角要素の積. 二つの対角要素の積を得る(_正方行列,_右下がり対角要素の積,_右上がり対角要素の積) :- 二つの対角要素を得る(_正方行列,_右下がり対角要素ならび,_右上がり対角要素ならび), 対角要素の掛算(_右下がり対角要素ならび,_右下がり対角要素の積), 対角要素の掛算(_右上がり対角要素ならび,_右上がり対角要素の積). 二つの対角要素を得る(_正方行列,_右下がり対角要素ならび,_右上がり対角要素ならび) :- 右下がり対角要素ならび(_正方行列,_右下がり対角要素ならび), 右上がり対角要素ならび(_正方行列,_右上がり対角要素ならび). 右下がり対角要素ならび(_正方行列,_右下がり対角要素ならび) :- findall(V,( nth1(_nth1,_正方行列,L), nth1(_nth1,L,V)), _右下がり対角要素ならび). 右上がり対角要素ならび(_正方行列,_右上がり対角要素ならび) :- reverse(_正方行列,_行を逆転した正方行列), 右下がり対角要素ならび(_行を逆転した正方行列,_右上がり対角要素ならび). 左下がり対角要素ならび(_正方行列,_左下がり対角要素ならび) :- findall(V,( nth1(_nth1,_正方行列,L), length([_|R],_nth1), append(_,[V|R],L)), _左下がり対角要素ならび),!. 左上がり対角要素ならび(_正方行列,_左上がり対角要素ならび) :- reverse(_正方行列,_行を逆転した正方行列), 左下がり対角要素ならび(_行を逆転した正方行列,_左上がり対角要素ならび). '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. 'n次正方行列の要素を行・列順序で取り出す'(_n,_正方行列,_i行,_j列,_正方行列の要素) :- between(1,_n,_i行), nth1(_i行,_正方行列,L), nth1(_j列,L,_正方行列の要素). 'n次正方行列の要素を列・行順序で取り出す'(_n,_正方行列,_i行,_j列,_正方行列の要素) :- between(1,_n,_j列), nth1(_i行,_正方行列,L), nth1(_j列,L,_正方行列の要素). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1361082416/311 # # [1] 授業単元:プログラミング演習 # [2] 問題文(含コード&リンク): # 以下のような入力が与えられたときに # 3 # 11010 # 01111 # 10101 # 01110 # 01100 # # 01011 # 01010 # 00100 # 00110 # 10100 # # 11110 # 01110 # 01101 # 01110 # 00001 # # 以下のように出力されるプログラムを作成してください。よろしくお願いします。 # 4 # 3 # 8 # '以下のような入力が与えられたときに 3 11010 01111 10101 01110 01100 01011 01010 00100 00110 10100 11110 01110 01101 01110 00001 以下のように出力されるプログラムを作成してください。よろしくお願いします。 4 3 8'(LL) :- プログラム(LL,_解), writef('%t\n',[_解]). プログラム(LL,_解) :- 転置(LL,LL1), '1の最大連続数を得る'(LL1,_最大連続数), '最大連続数の連続は何か所にあるか'(LL1,_最大連続数,_何か所), _解 is _最大連続数 * _何か所. '1の最大連続数を得る'(LL1,_最大連続数) :- '1の最大連続数を得る'(LL1,0,_最大連続数). '1の最大連続数を得る'([],_最大連続数,_最大連続数) :- !. '1の最大連続数を得る'([L|R],_最大連続数_1,_最大連続数) :- 'Lの最大連続数'(L,_連続数), _連続数 > _最大連続数_1, '1の最大連続数を得る'(R,_連続数,_最大連続数),!. '1の最大連続数を得る'([_|R],_最大連続数_1,_最大連続数) :- '1の最大連続数を得る'(R,_最大連続数_1,_最大連続数). 'Lの最大連続数'(L,_Lの最大連続数) :- findmax(_連続数,( append(L1,L2,L3,L), '1の連続数'(L1,L2,L3,_連続数)), _Lの最大連続数). '1の連続数'(L1,L2,L3,_連続数) :- all(L2,1), \+(last(L1,1)), \+(L3 = [1|_]), length(L2,_連続数). '最大連続数の連続は何か所にあるか'([],_最大連続数,0) :- !. '最大連続数の連続は何か所にあるか'([L|R],_最大連続数,_何か所) :- length(L2,_最大連続数), count(( append(L1,L2,L3,L), '1の連続数'(L1,L2,L3,_最大連続数)), Count), '最大連続数の連続は何か所にあるか'(R,_最大連続数,_何か所_1), _何か所 is _何か所_1 + Count. % 以下のサイトは 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2), 行列の転置(R2,R1),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1357748713/595 # # [1] 授業単元: C言語 # [2] 問題文(含コード&リンク): # 5列5行の多次元配列(0または1が適当に並べられているもの)を用意し # 1がある配列の上下左右の配列のうち2または3個1が存在するならその配列を0に変更し # そうでない場合は1のままにする この操作を10回行った配列を求めるプログラムを作成する # またこの配列は上下左右繋がっていて1,1の配列の場合上は1,5、左は5.1である # '5列5行の多次元配列(0または1が適当に並べられているもの)を用意し 1がある配列の上下左右の配列のうち2または3個1が存在するならその配列を0に変更し そうでない場合は1のままにする この操作を10回行った配列を求めるプログラムを作成する またこの配列は上下左右繋がっていて1,1の配列の場合上は1,5、左は5.1である'(_5列5行の多次元配列,_変換された5列5行の多次元配列) :- '5列5行の多次元配列(0または1が適当に並べられているもの)を用意し1がある配列の上下左右の配列のうち2または3個1が存在するならその配列を0に変更しそうでない場合は1のままにするこの操作を10回行った配列を求める'(_5列5行の多次元配列,_変換された5列5行の多次元配列). '5列5行の多次元配列(0または1が適当に並べられているもの)を用意し1がある配列の上下左右の配列のうち2または3個1が存在するならその配列を0に変更しそうでない場合は1のままにするこの操作を10回行った配列を求める'(_5列5行の多次元配列,_変換された5列5行の多次元配列) :- 前後左右の配列に1が2または3個存在するならこの配列の列全体を0に置換する(0,_5列5行の多次元配列,_変換された5列5行の多次元配列). 前後左右の配列に1が2または3個存在するならこの配列の列全体を0に置換することを10回繰り返す(10,_5列5行の多次元配列,_5列5行の多次元配列) :- !. 前後左右の配列に1が2または3個存在するならこの配列の列全体を0に置換することを10回繰り返す(N,_5列5行の多次元配列_1,_変換された5列5行の多次元配列) :- 前後左右の配列に1が2または3個存在するならこの配列の列全体を0に置換する(_5列5行の多次元配列_1,_5列5行の多次元配列_2), N_2 is N + 1, 前後左右の配列に1が2または3個存在するならこの配列の列全体を0に置換することを10回繰り返す(N2,_5列5行の多次元配列_2,_変換された5列5行の多次元配列). 前後左右の配列に1が2または3個存在するならこの配列の列全体を0に置換する(_5列5行の多次元配列_1,_5列5行の多次元配列_2) :- 列の置換(_5列5行の多次元配列_1,_置換された5列5行の多次元配列_1), 行の置換(_5列5行の多次元配列_1,_置換された5列5行の多次元配列_2), 二つの配列の論理積を取る(_置換された5列5行の多次元配列_1,_置換された5列5行の多次元配列_2,_5列5行の多次元配列_2). 行の置換(_5列5行の多次元配列,_置換された5列5行の多次元配列) :- '最終行を前、第一行を後ろに付加した5列6行の多次元配列'(_5列5行の多次元配列,_5列7行の多次元配列), findall(L,( append(L0,[_前の行,_行,_後の行|R],_5列7行の多次元配列), '1が2または3個存在するならこの配列の列全体を0に置換する'(_前の行,_行,_後の行,L)), _置換された5列5行の多次元配列). 列の置換(_5列5行の多次元配列,_置換された5列5行の多次元配列) :- 転置(_5列5行の多次元配列,_転置された5列5行の多次元配列), 行の置換(_転置された5列5行の多次元配列,_置換された転置された5列5行の多次元配列_1), 転置(_置換された転置された5列5行の多次元配列_1,_置換された5列5行の多次元配列). '最終行を前、第一行を後ろに付加した5列7行の多次元配列'(_5列5行の多次元配列,_5列7行の多次元配列) :- last(_5列5行の多次元配列,_最終行), _5列5行の多次元配列 = [_第一行|_], append([_最終行|_5列5行の多次元配列],[_第一行],_5列7行の多次元配列),!. '1が2または3個存在するならこの配列の列全体を0に置換する'(_前の行,_行,_後の行,[0,0,0,0,0]) :- count(member(1,_前の行),_前の行の1の個数), between(2,3,_前の行の1の個数),!. '1が2または3個存在するならこの配列の列全体を0に置換する'(_前の行,_行,_後の行,[0,0,0,0,0]) :- count(member(1,_後の行),_後の行の1の個数), between(2,3,_後の行の1の個数),!. '1が2または3個存在するならこの配列の列全体を0に置換する'(_,_行,_,_行). 二つの配列の論理積を取る([],[],[]) :- !. 二つの配列の論理積を取る([L1|R1],[L2|R2],[L3|R3]) :- '2つのならび要素の論理積'(L1,L2,L3), 二つの配列の論理積を取る(R1,R2,R3). '2つのならび要素の論理積'([],[],[]) :- !. '2つのならび要素の論理積'([N1|R1],[N2|R2],[N3|R3]) :- N3 is N1 /\ N2, '2つのならび要素の論理積'(R1,R2,R3). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1357748713/528 # # [1] 授業単元: C言語入門 # [2] 問題文(含コード&リンク): # 入力された数値の回数分だけ乱数を使ってコイン投げを行い, # 表裏が出る枚数をカウントして表示させるプログラム を作りなさい。 # '入力された数値の回数分だけ乱数を使ってコイン投げを行い,表裏が出る枚数をカウントして表示させる' :- '入力された数値の'(_入力された数値), '数値の回数分だけ乱数を使ってコイン投げを行い,表裏が出る枚数をカウントして'(_入力された数値,_表が出た枚数,_裏が出た枚数), 表示させる(_表が出た枚数,_裏が出た枚数). '入力された数値の'(_入力された数値) :- 整数を得る(コイン投げをする回数,_入力された数値 > 0,_入力された数値). '数値の回数分だけ乱数を使ってコイン投げを行い,表裏が出る枚数をカウントして'(_入力された数値) :- findall([_表,_裏],( between(1,_入力された数値,_), '乱数を使ってコイン投げを行い'(_表,_裏)), LL), 列要素の加算(LL,[_表が出た枚数,_裏が出た枚数]), '乱数を使ってコイン投げを行い'(1,0) :- 1 is random(2),!. '乱数を使ってコイン投げを行い'(0,1). 列要素の加算(LL,_合計ならび) :- 転置(LL,LL2), findall(_合計,( member(L,LL2), sum(L,_合計)), _合計ならび). 表示させる(_表が出た枚数,_裏が出た枚数) :- writef('表が出た枚数 = %t, 裏が出た枚数 = %t\n',[_表が出た枚数,_裏が出た枚数]). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1359210850/199 # # テキストで # 11111 # 22222 # 33333 # 44444 # 55555 # # というのを # # 12345 # 12345 # 12345 # 12345 # 12345 # # という風に90度変更したようにする方法を教えてください # # 'テキストで 11111 22222 33333 44444 55555 というのを 12345 12345 12345 12345 12345 という風に90度変更したようにする方法を教えてください' :- 'テキストで 11111 22222 33333 44444 55555 というのを'(LL1), '12345 12345 12345 12345 12345 という風に90度変更する'(LL1,_転置された文字列). 'テキストで 11111 22222 33333 44444 55555 というのを'(LL) :- split('11111 22222 33333 44444 55555',['\n'],L1), findall(L,( member(_文字列,L1), atom_chars(_文字列,L)), LL). '12345 12345 12345 12345 12345 という風に90度変更する'(LL1,_転置された文字列) :- 転置(LL1,LL2), findall(S,( member(L,LL2), atomic_list_concat(L,S)), L4), atomic_list_concat(L4,'\n',_転置された文字列). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1357748713/281 # # [1] 授業単元: プログラミング論 # [2] 問題文(含コード&リンク): # # 次のA・Bの行列をA×Bの計算をして、その結果を表示するプログラムを作成しなさい。 # # A=[5 3] B=[7 1 5 4] #   [3 8]     [1 9 2 8] #   [1 6] #   [9 1] # # 解の表示) [38 32 31 44] #       [29 75 31 76] #       [13 55 17 52] #       [64 18 47 44] # # '次のA・Bの行列をA×Bの計算をして、その結果を表示するプログラムを作成しなさい。 A=[5 3]   [3 8]   [1 6]   [9 1] B=[7 1 5 4]   [1 9 2 8] 解の表示) [38 32 31 44]       [29 75 31 76]       [13 55 17 52]       [64 18 47 44]'(_A, _B,_その結果) :- '次のA・Bの行列をA×Bの計算をして、'('A=[5 3]   [3 8]   [1 6]   [9 1] B=[7 1 5 4]   [1 9 2 8] ',_その結果), その結果を表示する(_その結果). '次のA・Bの行列をA×Bの計算をして、'(_文字列,_その結果) :- '次のA・Bの行列を'(_文字列,_A,_B), 転置(_B,_B_2), 行列の掛け算_1(_A,_B_2,_その結果). '次のA・Bの行列を'(_文字列,_A,_B) :- split(_文字列,[' ',' ','[',']'],L), '次のA・Bの行列を'(L,_A,_B). '次のA・Bの行列を'([A,=|R1],L2,L3) :- 'Aの行列'(R1,L2,R), 'Bの行列'(R,L3). 'Aの行列'([B,=|R1],[],[B,=|R1]) :- !. 'Aの行列'(L1,[L|R2],R) :- 'Aの行'(L,L1,R1), 'Aの行列'(R1,R2,R). 'Aの行'(['\n'|R],[],R). 'Aの行'([N|R1],[N|R2],R) :- 'Aの行'(R1,R2,R). 'Bの行列を'([B,=|R1],LL) :- 'Bの行列'(R1,LL). 'Bの行列'([],[]) :- !. 'Bの行列'(L1,[L|R2]) :- 'Bの行'(L1,L,R1), 'Bの行列'(R1,R2). 'Bの行'(['\n'|R],[],R). 'Bの行'([N|R1],[N|R2],R) :- 'Bの行'(R1,R2,R). その結果を表示する(_その結果) :- append(_,[L|R],_その結果), atomic_list_concat(L,' ',_行表示), writef('\t[%t]\n',[_行表示]), R = []. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1357748713/281 # # [1] 授業単元: プログラミング論 # [2] 問題文(含コード&リンク): # # 次のA・Bの行列をA×Bの計算をして、その結果を表示するプログラムを作成しなさい。 # # A=[5 3] B=[7 1 5 4] #   [3 8]     [1 9 2 8] #   [1 6] #   [9 1] # # 解の表示) [38 32 31 44] #       [29 75 31 76] #       [13 55 17 52] #       [64 18 47 44] # # '次のA・Bの行列をA×Bの計算をして、その結果を表示する'(_A, _B,_その結果) :- '次のA・Bの行列をA×Bの計算をして、'(_A, _B,_その結果), その結果を表示する(_その結果). '次のA・Bの行列をA×Bの計算をして、'(_A, _B,_その結果) :- _A = [[5,3],[3,8],[1,6],[9,1]], _B = [[7,1,5,4],[1,9,2,8]], 転置(_B,_B_2), 行列の掛け算_1(_A,_B_2,_その結果). その結果を表示する(_その結果) :- append(_,[L|R],_その結果), atomic_list_concat(L,' ',_行表示), writef('\t[%t]\n',[_行表示]), R = []. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1357748713/227 # # [1] 授業単元: 配列の整列 # [2] 問題文(含コード&リンク):字数超えてしまったのでリンク張ります。 # [ http://ime.nu/codepad.org/YCoV3saL ] # # /* # # 2次元配列の整列 # # ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。 # # | 学生番号 | 問1の点数 | 問2の点数 | 問3の点数 | 問4の点数 |問5の点数 | # # これを入力し、学生ごとの合格点と、問ごと合計点を求めて表示する(整列前) # 次に、問の合計点の降順に左から右に向かって整列し、さらに、学生の合計点で照準に整列して表示する(整列後)。 # # 【実行例】 # # 整列前 # 番号 問1  問2 問3 問4 問5 合計 # 1001 20 30 49 41 90 230 # 1002 50 30 24 0 95 199 # 1003 20 33 55 35 90 233 # 1004 93 55 56 61 90 355 #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ # 1025 80 90 52 50 91 363 # 合計 1145 1015 1297 978 2292 # # 整列後 # 番号 問5  問3 問1 問2 問4 合計 # 1025 91 52 80 90 50 363 # 1004 90 56 93 55 61 355 # 1003 90 50 94 50 49 233 # 1004 100 49 70 30 62 311 #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ # 1015 90 53 20 20 0 183 # 合計 2292 1297 1145 1015 978 # # ※実行例が長くなってしまうので途中省略しています。 # # */ 'ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。 | 学生番号 | 問1の点数 | 問2の点数 | 問3の点数 | 問4の点数 |問5の点数 | これを入力し、学生ごとの合格点と、問ごと合計点を求めて表示する(整列前) 次に、問の合計点の降順に左から右に向かって整列し、さらに、学生の合格点で照準に整列して表示する(整列後)。' :- 'ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。これを入力し、'(LL1), '学生ごとの合格点と、問ごと合計点を求めて表示する'(LL1,LL2), '次に、問の合計点の降順に左から右に向かって整列し、さらに、学生の合格点で照準に整列して表示する(整列後)。'(LL2). 'ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。これを入力し、'(LL1) :- get_split_lines('seiseki.dat',[' '],LL1). '学生ごとの合格点と、問ごと合計点を求めて表示する'(LL1,LL2) :- '行列を列の合計で降順に整列して列位置を交換し(LL1,LL2), 問いごとの合計を表示する(LL2). 列の合計で降順に整列して列位置を交換し(LL,LL1) :- 転置(LL,_転置されたLL), findall([_合計,_nth1|L],( nth1(_nth1,_転置されたLL,L), sum(L,_合計)), _転置され合計を付加されたLL), 降順バブルソート(_転置され合計と列位置が付加されたLL,_降順に整列された転置され合計と列位置が付加されたLL), 転置(_降順に整列された転置され合計と列位置が付加されたLL,LL1). 問いごとの合計を表示する(LL2) :- between(1,6,_nth), nth0(_nth,LL2,[_合計|_]), atomic_list_concat([問,_nth,' = ',_合計],S), writef(' %t,',[S]), _nth = 6, write('\n'). '次に、問の合計点の降順に左から右に向かって整列し、さらに、学生の合格点で照準に整列して表示する(整列後)。'(LL1) :- 列の合計で降順に整列して列位置を交換し(LL1,LL2), 行合計で降順に整列する(LL2,_降順に整列された各行の先頭列に合計が付加され各列の先頭行から合計と列位置が付加されたLL), 表示する(_降順に整列された各行の先頭列に合計が付加され各列の先頭行から合計と列位置が付加されたLL). 行合計で降順に整列する(LL1,_降順に整列された各行の先頭列に合計が付加され各列の先頭行から合計と列位置が付加されたLL) :- findall([_合計|L2],( member(L,LL1), 要素の合計を最終要素に付加(L,_合計,L2)), LL2), 降順バブルソート(LL2,_降順に整列された各行の先頭列に合計が付加され各列の先頭行から合計と列位置が付加されたLL). 要素の合計を最終要素に付加(L1,_合計,L2) :- 要素の合計を最終要素に付加(L1,0,_合計,L2). 要素の合計を最終要素に付加([],_合計,_合計,[_合計]). 要素の合計を最終要素に付加([N|R1],_合計_1,_合計,[N|R2]) :- _合計_2 is _合計 + N, 要素の合計を最終要素に付加(R1,_合計_2,_合計,R2). 表示する(LL2) :- 最終見出しを得る(LL2,_見出し), writef('%t\n',[_見出し]), 行列部分の表示(LL2), 最終合計の表示(LL2). 行列部分の表示(LL) :- append(_,[[_|L]|R],LL), writef('%5l%5r%5r%5r%5r%5r%5r\n',L), R = []. 最終合計の表示([_最終合計ならび|_]) :- writef(' %5r%5r%5r%5r%5r%5r\n',_最終合計ならび). 合計点の表示(_順位づけられた合計点ならび) :- findall(_合計点,( member([_合計点,_],_順位づけられた合計点ならび)), _合計点ならび), writef(' %5r%5r%5r%5r%5r%5r\n',_合計点ならび). 最終見出しを得る([_,L|_],_最終見出し) :- findall(S,( member(N,L), atomic_list_concat(['問',_nth1,' '],S)), L), atomic_list_concat(['番号 '|L],_最終見出し). 降順バブルソート(L1,L2) :- append(L0,[A,B|R],L1), A @< B, append(L0,[B,A|R],L3), 降順バブルソート(L3,L2),!. 降順バブルソート(L,L). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1357748713/227 # # [1] 授業単元: 配列の整列 # [2] 問題文(含コード&リンク):字数超えてしまったのでリンク張ります。 # [ http://ime.nu/codepad.org/YCoV3saL ] # # /* # # 2次元配列の整列 # # ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。 # # | 学生番号 | 問1の点数 | 問2の点数 | 問3の点数 | 問4の点数 |問5の点数 | # # これを入力し、学生ごとの合格点と、問ごと合計点を求めて表示する(整列前) # 次に、問の合計点の降順に左から右に向かって整列し、さらに、学生の合計点で照準に整列して表示する(整列後)。 # # 【実行例】 # # 整列前 # 番号 問1  問2 問3 問4 問5 合計 # 1001 20 30 49 41 90 230 # 1002 50 30 24 0 95 199 # 1003 20 33 55 35 90 233 # 1004 93 55 56 61 90 355 #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ # 1025 80 90 52 50 91 363 # 合計 1145 1015 1297 978 2292 # # 整列後 # 番号 問5  問3 問1 問2 問4 合計 # 1025 91 52 80 90 50 363 # 1004 90 56 93 55 61 355 # 1003 90 50 94 50 49 233 # 1004 100 49 70 30 62 311 #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ #  ・    ・  ・  ・   ・    ・   ・ # 1015 90 53 20 20 0 183 # 合計 2292 1297 1145 1015 978 # # ※実行例が長くなってしまうので途中省略しています。 # # */ 'ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。 | 学生番号 | 問1の点数 | 問2の点数 | 問3の点数 | 問4の点数 |問5の点数 | これを入力し、学生ごとの合格点と、問ごと合計点を求めて表示する(整列前) 次に、問の合計点の降順に左から右に向かって整列し、さらに、学生の合格点で照準に整列して表示する(整列後)。' :- 'ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。これを入力し、'(LL1), '学生ごとの合格点と、問ごと合計点を求めて表示する(整列前)'(LL1,_問いごとの合計点ならび,_転置された学生の合格点付き点数行列), 'さらに、学生の合格点で照準に整列して表示する(整列後)。'(_問いごとの合計点ならび,転置された学生の合格点付き点数行列). 'ファイル"seiseki.dat"[ http://db.tt/GRBKqdNF ]には、テストの各問の点数が以下のフォーマットで記録されている。これを入力し、'(LL1) :- get_split_lines('seiseki.dat',[' '],LL1). '学生ごとの合格点と、問ごと合計点を求めて表示する(整列前)'(LL1,LL4,_問いごとの合計点ならび,_転置された学生の合格点付き点数行列) :- '学生ごとの合格点と、'(LL1,_学生の合格点付き点数行列), '問ごと合計点を求めて'(_学生の合格点付き点数行列,_問いごとの合計点ならび,_転置された学生の合格点付き点数行列), 表示する(_学生の合格点付き点数行列,_問いごとの合計点ならび). '学生ごとの合格点と、'([],[]). '学生ごとの合格点と、'([[_学生番号|L1]|R1],[[_学生番号|L2]|R2]) :- sum(L1,_sum), 学生ごとの合格点(L1,0,L2), '学生ごとの合格点と、'(R1,R2). 学生ごとの合格点([],_合計点,[_合計点]). 学生ごとの合格点([A|R1],_合計点_1,[A|R2]) :- _合計点2 is A + _合計点_1, 学生ごとの合格点(R1,R2). 問ごと合計点を求めて(_学生の合格点付き点数行列,_問いごとの合計点ならび,_転置された学生の合格点付き点数行列) :- 転置(_学生の合格点付き点数行列,_転置された学生の合格点付き点数行列), 問ごと合計点(_転置された学生の合格点付き点数行列,_問いごとの合計点ならび). 問ごと合計点([],[]). 問ごと合計点([L1|R1],[S|R2]) :- sum(L1,S), 問ごと合計点(R1,R2). 表示する(_学生の合格点付き点数行列,_問いごとの合計点ならび) :- write('番号 問1  問2 問3 問4 問5 合計\n'), append(_,[L|R],_学生の合格点付き点数行列), writef('%5l%5r%5r%5r%5r%5r%5r\n',L), R = [], writef(' %5r%5r%5r%5r%5r%5r\n',_問いごとの合計点ならび). '次に、問の合計点の降順に左から右に向かって整列し、さらに、学生の合格点で照準に整列して表示する(整列後)。'(_転置された学生の合格点付き点数行列,_問いごとの合計点ならび) :- '次に、問の合計点の降順に左から右に向かって整列し、'(_転置された学生の合格点付き点数行列,_問いごとの合計点ならび,LL_1), 'さらに、学生の合格点で照準に整列して'(LL_1,LL_2), 表示する_2(_問いごとの合計点ならび,LL_2). '次に、問の合計点の降順に左から右に向かって整列し、'(_転置された学生の合格点付き点数行列,_問いごとの合計点ならび) :- 順位づけする(_問いごとの合計点ならび,_順位づけされた合計点ならび), findall(L,( between(1,5,N), nth1(N,_順位づけされた合計点ならび,[_,_項目番号]), nth1(_項目番号,_転置された学生の合格点付き点数行列,L)), LL_1), 転置([_学生番号ならび|LL_1],LL_2). 'さらに、学生の合格点で照準に整列して'(LL1,LL2) :- findall([A|L],( member(L,LL1), last(L,A)), LL3), 整列(LL3,LL4), 鍵を切り離して逆順にならび替え(LL4,[],LL2). 鍵を切り離して逆順にならび替え([],LL,LL). 鍵を切り離して逆順にならび替え([[A|L]|R1],L_1,LL) :- 鍵を切り離して逆順にならび替え(R1,[L|L_1],LL). 順位づけする(_問いごとの合計点ならび,_順位づけされた合計点ならび) :- findall([_合計点,_nth1],( between(1,5,_nth1), nth1(_nth1,_問いごとの合計点ならび,_合計点)), LL1), 降順整列(LL1,_順位づけされた合計点ならび). 降順整列(LL1,_順位づけされた合計点ならび) :- 整列(LL1,LL2), reverse(LL2,_順位づけされた合計点ならび). 表示する_2(LL_2,_順位づけられた合計点ならび) :- 見出し表示(_順位づけられた合計点ならび), 行列部分の表示(LL_2), 合計点の表示(_順位づけられた合計点ならび). 見出し表示(_順位づけられた合計点ならび) :- findall(_項目番号,( member([_,_項目番号],_順位づけられた合計点ならび)), _項目番号ならび), writef('番号 %5r%5r%5r%5r%5r%5r合計\n',_項目番号ならび). 行列部分の表示(LL) :- append(_,[L|R],LL), writef('%5l%5r%5r%5r%5r%5r%5r\n',L), R = []. 合計点の表示(_順位づけられた合計点ならび) :- findall(_合計点,( member([_合計点,_],_順位づけられた合計点ならび)), _合計点ならび), writef(' %5r%5r%5r%5r%5r%5r\n',_合計点ならび). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1354070278/717 # # [1] 授業単元: C演習 # [2] 問題文(含コード&リンク): # (問題文)http://imgur.com/bAeG1 # (途中まで書いたコード)://codepad.org/nwwt2hgU # (使用するテキストファイル、結果含む) # http://s2.muryo-de.mydns.jp/~c_cpp_homework/cgi-bin/joyful/joyful.cgi? のNo.396 # :- dynamic(転置索引/2). テキストのダウンロード(_サイトファイル名,_出力ファイル名) :- atomic_list_concat(['w3m -dump ',_サイトのファイル名],S), popen(S,Chars), open(_出力ファイル名,write,Outstream), ファイルに書き込む(Outstream,Chars), close(Outstream). ファイルに書き込む(Outstream,[]). ファイルに書き込む(Outstream,[C|R]) :- put_char(Outstream,C), ファイルに書き込む(Outstream,R). 転置索引を作る(_ファイル名) :- open(_ファイル名,read,Instream), ストリームから転置索引を作る(Instream,0), close(Instream). ストリームから転置索引を作る(Instream,_) :- at_end_of_stream(Instream),!. ストリームから転置索引を作る(Instream,N) :- get_line(Instream,Line), N_2 is N + 1, 語彙を転置索引に登録する(Line,N), ストリームから転置索引を作る(Instream,N_2). 語彙を転置索引に登録する(Line,N) :- split(Line,[' ',',','.',':','(',')'],L), member(_語彙,L), \+(転置索引(_語彙,N)), assertz(転置索引(_語彙,N)), fail. 語彙を転置索引に登録する(_,_). popen(Command,Chars) :- open(pipe(Command),read,Instream), get_char(Instream,Char), popen(Instream,Char,Chars), close(Instream),!. popen(Instream,end_of_file,[]) :- !. popen(Instream,Char,[Char|R]) :- get_char(Instream,Char2), popen(Instream,Char2,R). shs(Command,X) :- popen(Command,L), shs_3(L,X). shs_3(L,[S|R]) :- append(L0,['\n'|R1],L), atom_chars(S,L0), shs_3(R1,R). shs_3([],[]) :- !. shs_3(L,[S]) :- atom_chars(S,L). % 以下のサイトは # 出典:: 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',_行表示形式). % 以下のサイトは ヒストグラムを出力する(_標本ならび) :- ヒストグラムの用意(_標本ならび,LL1), 転置(LL1,LL2), 出力する(LL2). ヒストグラムの用意(_標本ならび,LL1) :- 最大値(_標本ならび,_最大値), length(L1,_最大値), findall(L1,( 星のリストに変換(L,L1)), LL1). 星のリストに変換(L,L1) :- member(N,L), length(R,N), append(L0,R,L1), all(L0,' '), all(R,*). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 出力する([]). 出力する([L|R]) :- atomic_list_concat(L,S), writef('%t\n',[S]), 出力する(R). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1354070278/7 # # [1] 授業単元:問題1:二次元配列 問題2:関数 # [2] 問題文(含コード&リンク): # 問題1:ファイルから入力した英小文字a-zの頻度のヒストグラムを # 出力するプログラムを書いてください。入力ファイルはプログラムファイルを使えば良い。 # # 問題2:1文字を引数としてそれが小文字であれば大文字にして返し # そうでなければそのまま文字を返す関数を作成しキーボードから # 文字入力としてこの関数の動作を確認せよ。 # [3.1] OS: windows vista #  [3.2] コンパイラ名とバージョン:visual studio2010 #  [3.3] 言語: C言語 # [4] 期限: 11月30日 # [5]ポインタはやってません。宜しくお願いします 。 # # 'ファイルから入力した英小文字a-zの頻度のヒストグラムを出力するプログラムを書いてください。入力ファイルはプログラムファイルを使えば良い。' :- get_chars('c161_7.html',Chars), '英小文字a-zの頻度の'(Chars,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]), ヒストグラムを出力する([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]). '英小文字a-zの頻度の'([],[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z],[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]). '英小文字a-zの頻度の'([_文字|_残りならび],L1,L) :- 英小文字ならば頻度を更新(_文字,L1,L2), '英小文字a-zの頻度の'(_残りならび,L2,L),!. '英小文字a-zの頻度の'([_|_残りならび],L1,L) :- '英小文字a-zの頻度の'(_残りならび,L1,L). 英小文字ならば頻度を更新(_文字,L1,L2) :- nth0(Nth0,[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z],_文字), length(L0,Nth0), append(L0,[S|R],L1), S2 is S + 1, append(L0,[S2|R],L2). ヒストグラムを出力する(L) :- ヒストグラムの用意(L,LL1), 転置(LL1,LL2), 出力する(LL2). ヒストグラムの用意(L,LL1) :- 最大値(L,_最大値), length(L1,_最大値), findall(L1,( 星のリストに変換(L,L1)), LL1). 星のリストに変換(L,L1) :- member(N,L), length(R,N), append(L0,R,L1), all(L0,' '), all(R,*). 出力する([]). 出力する([L|R]) :- atomic_list_concat(L,S), writef('%t\n',[S]), 出力する(R). % 以下のサイトは # 出典:: 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). % 以下のサイトは # 出典 :: C言語の宿題片付けます 160代目 #400 # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク): http://ime.nu/codepad.org/QdOnaWYm # # /* # ビンゴゲームを作る # # 仕様 # ・5×5のビンゴカードをint型の2次元配列として宣言する # ・ビンゴカードの数字は重複しない1〜100の乱数を作り、それから先頭の25個をビンゴカードに適用 # ・最初にビンゴカード作成に使うための重複しない100個の乱数を見やすい形で表示 # ・値を交換する処理は関数化する # ・実際のビンゴゲームのようにガラガラで1つずつ数字が出てくる # ・ガラガラは1〜100までの重複しない乱数を作る機械であり、ビンゴカード作成に用いた乱数列とガラガラで使う乱数列は別物である # ・ビンゴカード作成用の乱数とガラガラ用の乱数はヒープ領域に確保した配列に格納 # ・カードの縦、横、斜めのいずれかがそろったらゲーム終了 # */ # :- dynamic(賞品/1). ビンゴ参加者(ケイスケ). ビンゴ参加者(ユウヤ). ビンゴ参加者(タダシ). ビンゴ参加者(マッチ). ビンゴ参加者(トオル). 賞品('フェラーリ(模型)'). 賞品('コルト45(模型)'). 賞品(西竹一の使っていた拍車). 賞品(ティーボールセット). 賞品(ビンゴセット). ビンゴゲーム :- findall(_ビンゴ参加者,ビンゴ参加者(_ビンゴ参加者),_ビンゴ参加者ならび), ビンゴゲーム(_ビンゴ参加者ならび). ビンゴゲーム(_ビンゴ参加者ならび) :- ゲーム参加者のビンゴカード(_ビンゴ参加者ならび,_ビンゴカードならび), 'ガラガラは1〜100までの重複しない乱数を作る機械であり、ビンゴカード作成に用いた乱数列とガラガラで使う乱数列は別物である'(_ガラガラで使う乱数列), 参加者全員がビンゴとなるまでガラガラを繰り返す(_ビンゴカードならび,_ガラガラで使う乱数列). 参加者全員がビンゴとなるまでガラガラを繰り返す([],_) :- write('ビンゴ終了\nご苦労さまでした\n'),!. 参加者全員がビンゴとなるまでガラガラを繰り返す(_参加者ビンゴカードならび,L1) :- ガラガラ(L1,_数,L2), ビンゴになったカードを探し賞品を渡してそのカードを削除(_数,_参加者ビンゴカードならび,_ビンゴになった人を削除した参加者ビンゴカードならび), 参加者全員がビンゴとなるまでガラガラを繰り返す(_ビンゴになった人を削除した参加者ビンゴカードならび,L2). '5×5のビンゴカードをint型の2次元配列として宣言する'(_ビンゴカード) :- length(_ビンゴカード,5), findall(L,( member(L,_ビンゴカード), length(L,5)),_ビンゴカード). ゲーム参加者のビンゴカード(_ビンゴ参加者ならび,_ビンゴカードならび) :- findall([_ビンゴ参加者,_ビンゴカード],( member(_ビンゴ参加者,_ビンゴ参加者ならび), 'ビンゴカードの数字は重複しない1〜100の乱数を作り、それから先頭の25個をビンゴカードに適用'(_ビンゴカード)),_ビンゴカードならび). 'ビンゴカードの数字は重複しない1〜100の乱数を作り、それから先頭の25個をビンゴカードに適用'(_ビンゴカード) :- 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(L), それから先頭の25個をビンゴカードに適用(L,_ビンゴカード). 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(L) :- findall(N,between(1,100,N),L1), 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(100,L1,L). 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(0,_,[]) :- !. 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(Nth,L1,[N|R2]) :- '重複しない1〜100の乱数'(Nth,L1,N,L2), Nth_1 is Nth - 1, 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(Nth_1,L2,R2). '重複しない1〜100の乱数'(Nth,L1,N,L2) :- Nth0 is random(Nth), length(L0,Nth0), append(L0,[N|R1],L1), append(L0,R1,L2),!. それから先頭の25個をビンゴカードに適用(_重複しない100個の乱数ならび,_ビンゴカード) :- ビンゴカード(_重複しない100個の乱数ならび,_ビンゴカード). ビンゴカード(_重複しない100個の乱数ならび,_ビンゴカード) :- _ビンゴカード=[[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]], flatten(_ビンゴカード,L), append(L,_,_重複しない100個の乱数ならび). 'ガラガラは1〜100までの重複しない乱数を作る機械であり、ビンゴカード作成に用いた乱数列とガラガラで使う乱数列は別物である'(_ガラガラで使う乱数列) :- 'ビンゴカードの数字は重複しない1〜100の乱数を作り'(_ガラガラで使う乱数列),!. ビンゴになったカードを探し賞品を渡してそのカードを削除(_,[],[]). ビンゴになったカードを探し賞品を渡してそのカードを削除(_数字,[[_ビンゴ参加者,_ビンゴカード_1]|R1],R) :- 一致した数字があったら穴をあける(_数字,_ビンゴカード_1,_ビンゴカード_2), ビンゴになったカードを探し賞品を渡してそのカードを削除_2(_数字,[[_ビンゴ参加者,_ビンゴカード_2]|R1],R). ビンゴになったカードを探し賞品を渡してそのカードを削除_2(_数字,[[_ビンゴ参加者,_ビンゴカード_1]|R1],R) :- ビンゴだったら賞品を渡してその人は上がり(_ビンゴカード_1,_ビンゴ参加者), ビンゴになったカードを探し賞品を渡してそのカードを削除(_数字,R1,R),!. ビンゴになったカードを探し賞品を渡してそのカードを削除_2(_数字,[[_ビンゴ参加者,_ビンゴカード_1]|R1],[[_ビンゴ参加者,_ビンゴカード_1]|R]) :- ビンゴになったカードを探し賞品を渡してそのカードを削除(_数字,R1,R). ビンゴだったら賞品を渡してその人は上がり(_ビンゴカード,_ビンゴ参加者) :- ビンゴ(_ビンゴカード), ビンゴ表示(_ビンゴカード), 賞品を渡す(_ビンゴ参加者),!. 一致した数字があったら穴をあける(_数字,_ビンゴカード_1,_ビンゴカード_2) :- findall(L2,( member(L,_ビンゴカード_1), 一致した場合だけ穴を開ける(_数字,L,L2)),_ビンゴカード_2). 一致した場合だけ穴を開ける(_数字,L,L2) :- append(L0,[_数字|R],L), append(L0,[穴|R],L2),!. 一致した場合だけ穴を開ける(_,L,L). ビンゴ([穴,_,_,_,_],[_,穴,_,_,_,_],[_,_,穴,_,_],[_,_,_,穴,_],[_,_,_,_,穴]) :- !. ビンゴ([_,_,_,_,穴],[_,_,_,穴,_],[_,_,穴,_,_],[_,穴,_,_,_,_],[穴,_,_,_,_]) :- !. ビンゴ(_ビンゴカード) :- member(L,_ビンゴカード), all(L,穴),!. ビンゴ(_ビンゴカード) :- 転置(_ビンゴカード,_ビンゴカード_2), member(L,_ビンゴカード_2), all(L,穴),!. ビンゴ表示(_ビンゴカード) :- forall(member(L,_ビンゴカード),ビンゴ行表示(L)). ビンゴ行表示([]) :- write('\n'). ビンゴ行表示([A|R]) :- 表示変換(A,B), writef('%w ',[B]), ビンゴ行表示(R). 表示変換(穴,穴) :- !. 表示変換(N,A) :- N < 10, atomic_list_concat([' ',N],A),!. 表示変換(N,A) :- atom_number(A,N). 賞品を渡す(_参加者) :- retract(賞品(_賞品)), writef('%t君はビンゴになりました。賞品は %t です!\n',[_参加者,_賞品]),!. all([],_). all([A|R],A) :- all(R,A). ガラガラ(L1,_数字,L2) :- length(L1,_nth_1), Nth is random(_nth_1) + 1, '重複しない1〜100の乱数'(Nth,L1,_数字,L2). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1349527750/161 # # [1] 授業単元:プログラミング言語 # [2] 問題文 # 1.空白、タブ、改行を数えるプログラムを書け。 # 2.二つ以上の空白を一つの空白に置き換えながら、入力を出力にコピーするプログラムを書け。 # '空白、タブ、改行を数える'(_文字列,_空白数,_タブ数,_改行数) :- findall(L,( sub_atom(_文字列,_,1,_,_文字), 数える(_文字,L1)), _集計行列), '集計行列から空白、タブ、改行を数える'(_集計行列,_空白数,_タブ数,_改行数). 数える(' ',[1,0,0]) :- !. 数える('\t',[0,1,0]) :- !. 数える('\n',[0,0,1]). '集計行列から空白、タブ、改行を数える'(_集計行列,_空白数,_タブ数,_改行数) :- 転置(_集計ならび,[L1,L2,L3]), sum(L1,_空白数), sum(L2,_タブ数), sum(L3,_改行数). % 以下のサイトは # 出典:: 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). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1342966104/466 # # # [1] 授業単元:C言語 # [2] 問題文:プレイフェア暗号の作成 #       参考:http://ime.nu/www.tamagaki.com/math/PlayfairCipher.html # # #  プレイフェア暗号(Playfair cipher) # # プレイフェア暗号はイギリス人サー・チャールズ・ホイートストン(Sir Charles Wheatstone)により開発されライアン・プレイフェア(Lyon Playfair)が普及させました。プレイフェア暗号を用いて暗号化するとき、まずキーワードまたはキーフレーズをあらかじめ決めておきます。仮にキーワードをPlayfairとします。次にこのキーワードをアルファベットが重複することなく下の5×5の表に入れていきます。 # # ここで残りのセルに余ったアルファベットを挿入していくわけですが、アルファベットは26文字あって5×5では一字余ります。そこで I と J は同じセルに入れるとあらかじめ決めておきます。そこで新たに作られた表が下のようになります。 # # 準備ができたところで、次のメッセージを暗号化してみましょう。 # # メッセージ Abandon hope, all ye who enter here. # # このメッセージをまず二文字ずつ区切っていきます。 # # Ab-an-do-nh-op-ea-ll-ye-wh-oe-nt-er-he-re # # ここで7番目に ll と同じ文字が重複しているので間に x を入れます。 # # Ab-an-do-nh-op-ea-lx-ly-ew-ho-en-te-rh-er-e # # そうすると最後に e が一つ余ります。ここにもやはり x を入れておきます。 # # Ab-an-do-nh-op-ea-lx-ly-ew-ho-en-te-rh-er-ex # # まず最初の二文字 ab を暗号化してみましょう。ab は先ほど作った表では同じ列にあります。このときは ab の列のすぐ下の文字で置き換えます。 # # つまり ab は BH に変わります。ただし一番下の文字例えば w は一番上の文字 A に変換されます。 # # 同様に同じ行に入る二文字も出てきたとします。例えば ap などは右隣の文字に置き換えます。 # # つまり ap は YL になるわけですね。この場合も一番右の文字例えば f は一番左の文字 p に変換されます。 # # 最後に行も列も違う二文字が出てきた場合は次のようにします。例えば an を考えます。下の表のように a n それぞれの行および列を塗り分け、その交点となる文字を見ます。この場合、P と Q になります。 # # そこで a は、a h と同じ行の P に、n は、n と同じ行の Q に変換します。つまり、 # # do → RT # # nh → QE # # op → NL # # となるわけです。このルールに従って、先ほどのメッセージを暗号化すると、 # # 平文  Ab-an-do-nh-op-ea-lx-ly-ew-ho-en-te-rh-er-ex # # 暗号文 BH PQ RT QE NL HP YV AF HU GQ NU NM BG GI KU # # これでプレイフェア暗号による暗号化が終了したわけです。 # # この暗号はイギリスがボーア戦争(ブール戦争 BoreWar)で使用したといわれています。 プレイフェア暗号表の作成(_鍵文,_暗号表) :- 鍵文を25要素のならびに拡張して(_鍵文,_25要素ならび,_鍵文字以外の変数ならび), 'Jを除いたA-Zならびを切る'(_Jを除いたA_Zならび), 変数を埋める(_Jを除いたA_Zならび,Chars,_鍵文字以外の変数ならび), 'N個組'(5,_25要素のならび,_暗号表). 鍵文を25要素のならびに拡張して(_鍵文,_25要素ならび,_鍵文字ならび,_鍵文字以外の変数ならび) :- length(_25要素ならび,25), atom_chars(_鍵文,_鍵文字ならび), append(_鍵文字ならび,_鍵文字以外の変数ならび,_25要素ならび). 'A-Zならびを切る'(_Jを除いたA_Zならび) :- _切る回数 is random(113) + 1, トランプを切るようにならびを切る(_切る回数,25,['A','B','C','D','E','F','G','H','I','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'],_Jを除いたA_Zならび). 変数を埋める(_,_,[]). 変数を埋める(L_1,Chars,[V|R]) :- select(V,L_1,L_R), \+(member(V,Chars)), 変数を埋める(L_R,Chars,R). プレイフェア暗号による暗号化(_平文,_暗号文) :- メッセージをまず二文字ずつ区切っていきます(_平文,_二文字ずつに区切られたならび), プレイフェア暗号化(_二文字ずつに区切られたならび,_暗号文字ならび), atomic_list_concat(_暗号文字ならび,_暗号文). メッセージをまず二文字ずつ区切っていきます(_平文,_二文字ずつに区切られたならび) :- atom_chars(_平文,Chars), すべての文字を大文字に変換(Chars,_大文字の文字ならび), メッセージをまず二文字ずつ区切っていきます(_大文字の文字ならび,_二文字ずつに区切られたならび). メッセージをまず二文字ずつ区切っていきます([],[]). メッセージをまず二文字ずつ区切っていきます(['J'|R1],[['J','J']|R2]) :- メッセージをまず二文字ずつ区切っていきます(R1,R2). メッセージをまず二文字ずつ区切っていきます([A],[[A,'X']]). メッセージをまず二文字ずつ区切っていきます([A,A|R1],[[A,'X']|R2]) :- メッセージをまず二文字ずつ区切っていきます([A|R1],R2). メッセージをまず二文字ずつ区切っていきます([A,B|R1],[[A,B]|R2]) :- \+(A=B), メッセージをまず二文字ずつ区切っていきます(R1,R2). プレイフェア暗号化(_二文字ずつに区切られたならび,_暗号文字ならび) :- 暗号表(_暗号表), 転置(_暗号表,_転置された暗号表), プレイフェア暗号化(_二文字ずつに区切られたならび,_暗号表,_転置された暗号表,_暗号文字ならび). プレイフェア暗号化([],_,_,[]). プレイフェア暗号化([['J','J']|R1],_暗号表,_転置された暗号表,['J'|R2]) :- プレイフェア暗号化(R1,_暗号表,_転置された暗号表,R2). プレイフェア暗号化([[A,B]|R1],_暗号表,_転置された暗号表,[C,D|R2]) :- 暗号に変換(A,B,_暗号表,C,D), プレイフェア暗号化(R1,_暗号表,_転置された暗号表,R2). 暗号に変換(A,B,_暗号表,_転置された暗号表,C,D) :- member(L,_転置された暗号表), 'A,Bが暗号表の同一行または列にある'(A,B,L,C,D). 暗号に変換(A,B,_暗号表,_転置された暗号表,C,D) :- member(L,_暗号表), 'A,Bが暗号表の同一行にある'(A,B,L,C,D). 暗号に変換(A,B,_暗号表,_転置された暗号表,C,D) :- 暗号コードは矩形を仮想した時の他の二角(A,B,_暗号表,C,D). 'A,Bが暗号表の同一行または列にある'(A,B,L,C,D) :- member(A,L), member(B,L), 'A,Bの次の要素'(L,A,C), 'A,Bの次の要素'(L,B,D). 'A,Bの次の要素'(L,X,Y) :- append([Y|_],[X],L). 'A,Bの次の要素'(L,X,Y) :- append(_,[X,Y|_],L). 暗号コードは矩形を仮想した時の他の二角(A,B,_表,C,D) :- 'A,Bの行と列位置を得る'(A,B,_表,L_1,_列_A,L_2,_列_B), nth1(_列_B,L_1,C), nth1(_列_A,L_2,D). 'A,Bの行と列位置を得る'(A,B,_表,L_1,_列_A,L_2,_列_B) :- nth1(_行_A,_表,L_1), nth1(_列_A,L_1,A), nth1(_行_B,_表,L_2), nth1(_列_B,L_2,B). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1276873238/829 # # 問題 # 数独の解答が9行9列の文字列で与えられたとき正しいかどうか判定せよ。 # # '数独の解答が9行9列の文字列で与えられたとき正しいかどうか'(_文字列) :- '数独の解答が9行9列の文字列で与えられたとき'(_文字列,LL), 数独の回答が正しい(LL). '数独の解答が9行9列の文字列で与えられたとき'(_9行9列の文字列,LL) :- split(9行9列の文字列,['\n'],_行ならび), '9行9列の行ならびを行列に変換'(_行ならび,LL). '9行9列の行ならびを行列に変換'([],[]). '9行9列の行ならびを行列に変換'([_行|R1],[L|R2]) :- findall(N,( sub_atom(_行,_,1,_,A), atom_number(A,N)), L), '9行9列の行ならびを行列に変換'(R1,R2). 数独の回答が正しい(LL) :- '行・列要素の数独の解答は正しい'(LL), 矩形要素の数独の解答も正しい(LL). '行・列要素の数独の解答は正しい'(LL) :- 行要素の数独診断(LL), 転置(LL,LL2), 行要素の数独診断(LL2). 行要素の数独診断([]). 行要素の数独診断([L1|R]) :- 一意の数が9個(L1), 行要素の数独診断(R). 矩形要素の数独の解答も正しい([]). 矩形要素の数独の解答も正しい([L1,L2,L3|R1],L) :- 転置([L1,L2,L3],LL1), 矩形要素診断(LL1), 矩形要素の数独の解答も正しい(R1,R2). 矩形要素診断([]). 矩形要素診断([L1,L2,L3|R]) :- append(L1,L2,L3,L), 一意の数が9個(L), 矩形要素診断(R). 一意の数が9個(L1) :- sort(L1,L2), length(L2,9). % 以下のサイトは ガウス法による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/db/1316769778/881 # # 入庫、出庫、締め用のテーブルがあるとし、それぞれ、HEADER、DETAILがあり # HEADERには、入出庫、締め番号、日付、ACTIVE(該当月Y/N)など # DETAILには、アイテムと数量が入っているとします # そこでDAILY MOVEMENTを作成したいのですが、 # 1~31のように固定ではなく、トランザクションがあった日のみ、つまり # SELECT TRANS_DATE FROM # (SELECT TRANS_DATE FROM INCOMING WHERE ACTIVE='Y' # UNION ALL # SELECT TRANS_DATE FROM OUTGOING WHERE ACTIVE='Y') T_DATE # group by TRANS_DATE ORDER BY 1 # でTRANS_DATE抽出しておきます # 結果をREPORT WRITEとかWEBを用いずに # TRANS_DATEが横方向に1行目に表され、 # 2行目1カラムは、アイテム、2カラム目はOPENING数量で、 # 3カラム以降はIN又はOUTの数量を表記したいのですが # JUL/8はトランザクションがありませんので表記されていません # 最後のカラムは、その月の現在までのSUMMARY # #   JUL/7  JUL/9           JUL # IN OUT IN OUT IN OUT CLOSE #    3 5   3 3 8  15 # # みなさんなら、どうSQLを書きますか、教えてください # # % % 入庫(_入出庫,_締め番号,_日付,_ACTIVE,_アイテム,_数量). % % 出庫(_入出庫,_締め番号,_日付,_ACTIVE,_アイテム,_数量). % % 締め用(_入出庫,_締め番号,_日付,_ACTIVE,_アイテム,_数量). % みなさんならどう書きますか :- 重複のない入出庫日付ならび(_重複のない入出庫日付ならび), 表を作成する(_重複のない入出庫日付ならび,_表), '入庫・出庫・締め用数量合計'(_入庫数量合計,_出庫数量合計,_締め用数量合計), 転置(_表,_転置された表), 表を出力する(_転置された表,_入庫数量合計,_出庫数量合計,_締め用数量合計). 重複のない入出庫日付ならび(_重複のない入出庫日付ならび) :- setof(_日付_1,[_入出庫,_締め番号,_日付,_ACTIVE,_アイテム,_数量] ^ ( 入庫(_入出庫,_締め番号,_日付_1,'Y',_アイテム,_数量)),_入庫日付ならび), setof(_日付_2,[_入出庫,_締め番号,_日付,_ACTIVE,_アイテム,_数量] ^ ( 出庫(_入出庫,_締め番号,_日付_2,'Y',_アイテム,_数量)),_出庫日付ならび), append(_入庫日付ならび,_出庫日付ならび,_入出庫日付ならび), setof(_日付,member(_日付,_入出庫日付ならび),_重複のない入出庫日付ならび). 表を作成する(_重複のない入出庫日付ならび,_表) :- findall([_日付,_入庫数量,_出庫数量],( member(_日付,_重複のない入出庫日付ならぴ), 入庫数量を得る(_日付,_入庫数量), 出庫数量を得る(_日付,_出庫数量), 表示パターン(_入庫数量,_出庫数量,_表示パターン)), _表). 入庫数量を得る(_日付,_入庫数量) :- 入庫(_入出庫,_締め番号,_日付,'Y',_アイテム,_入庫数量),!. 入庫数量を得る(_日付,0.0). 出庫数量を得る(_日付,_出庫数量) :- 入庫(_入出庫,_締め番号,_日付,'Y',_アイテム,_出庫数量),!. 出庫数量を得る(_日付,0.0). '入庫・出庫・締め用数量合計'(_入庫数量合計,_出庫数量合計,_締め用数量合計) :- findsum(_数量,( 入庫(_入出庫,_締め番号,_日付,'Y',_アイテム,_数量)), _入庫数量合計), findsum(_数量,( 出庫(_入出庫,_締め番号,_日付,'Y',_アイテム,_数量)), _出庫数量合計), findsum(_数量,( 締め用(_入出庫,_締め番号,_日付,'Y',_アイテム,_数量)), _締め用数量合計). 表示パターン(_入庫数量,0.0,1) :- \+(_入庫数量 = 0.0),!. 表示パターン(0.0,_出庫数量,2) :- \+(_出庫数量 = 0.0),!. 表示パターン(_,_,3). 表を出力する([_日付ならび,_パターンならび,_入庫数量ならび,_出庫数量ならび],_入庫数量合計,_出庫数量合計,_締め用数量合計) :- 日付を表示する(_日付ならび), '入庫・出庫・合計見出し'(_パターンならび), 数量ならびを表示する(_入庫数量ならび,_出庫数量ならび), '入庫数量合計・出庫数量合計・締め用数量合計表示'(_入庫数量合計,_出庫数量合計,_締め用数量合計). 日付を表示する([]) :- write('\n'). 日付を表示する([_日付|R]) :- 日付表示文字列(_日付,_日付表示文字列), write('%12c',[_日付表示文字列]), 日付を表示する(R). 日付表示文字列(_日付,_日付表示文字列) :- sub_atom(_日付,4,2,_月), sub_atom(_日付,6,2,_日), atomic_list_concat([_月,'/',_日],_日付表示文字列). '入庫・出庫・合計見出し'([]) :- writef(' 入庫 出庫 締め用 \n'). '入庫・出庫・合計見出し'([_パターン|R]) :- '入庫・出庫・合計見出し表示文字列'(_パターン,_表示文字列), writef('%t',[_表示文字列]), '入庫・出庫・合計見出し'(R). '入庫・出庫・合計見出し表示文字列'(1,' 入庫 '). '入庫・出庫・合計見出し表示文字列'(2,' 出庫 '). '入庫・出庫・合計見出し表示文字列'(3,' 入庫 出庫 '). 数量ならびの表示([]) :- 数量ならびを表示する([_入庫|R1],[_出庫|R2]) :- 数量表示文字列(_入庫数量,_出庫数量,_入庫表示文字列,_出庫表示文字列), writef(' %t %t ',[_入庫表示文字列,_出庫表示文字列]), 数量ならびを表示する(R1,R2). 数量表示文字列(0.0,_出庫数量,' ',_出庫表示文字列) :- swritef(_出荷表示文字列,' %4r ',[_出庫数量]),!. 数量表示文字列(0.0,_入庫数量,_入庫表示文字列,' ') :- swritef(_入庫表示文字列,' %4r ',[_入庫数量]),!. 数量表示文字列(_入荷数量,_出庫数量,_入庫数量文字列,_出庫表示文字列) :- swritef(_入庫表示文字列,' %4r ',[_入庫数量]), swritef(_出庫表示文字列,' %4r ',[_出庫数量]),!. '入庫数量合計・出庫数量合計・締め用数量合計表示'(_入庫数量合計,_出庫数量合計,_締め用数量合計) :- writef(' %4r %4r %4r\n',[_入庫数量合計,_出庫数量合計,_締め用数量合計]). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1337692704/123 # # 【 課題 】6〜13行目を変更してマップを自動作成する。 # 【 形態 】1. Javaアプリケーション(main()で開始)/【 GUI  】制限なし # 【 期限 】6月28日 午前10時 《必須》 # 【 Ver  】java javac jEdit # 【 補足 】このソースコードを改変して下さい # # import java.util.Scaner; # class Array8{ # public static void main(String[] args){ # //司法にダミーの0を置いているmapの作成. # int[][] map = { # {0, 0, 0, 0, 0, 0,}, # {0, 1, 1, 1, 0, 0,}, # {0, 1, 0, 1, 0, 0,}, # {0, 0, 1, 1, 0, 0,}, # {0, 1, 0, 0, 1, 0,}, # {0, 0, 0, 0, 0, 0,}, # }; # while(true){ # int x = 0; # int y = 0; # int sum = 0; '四方にダミーの0を置いているmapの作成'(_map,_四方にダミーの0を置いているmap) :- 'mapを転置して行の最初と最後に0を付加する'(_map,_転置して行の最初と最後に0を付加されたmap), 'mapを転置して行の最初と最後に0を付加する'(_転置して行の最初と最後に0を付加されたmap,_四方にダミーの0を置いているmap). 'mapを転置して行の最初と最後に0を付加する'(_map,_転置して行の最初と最後に0を付加されたmap) :- 転置(_map,_転置されたmap), findall(_最初と最後に0を付加された行,( member(_行,_転置されたmap), 行の最初と最後に0を付加する(_行,_最初と最後に0を付加された行)), _転置して行の最初と最後に0を付加されたmap). 行の最初と最後に0を付加する(_行,_最初と最後に0を付加された行) :- append([0|_行],[0],_最初と最後に0を付加された行). % 転置/2 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1339338438/253 # # [1] 授業単元:応用情報処理I # [2] 問題文: 正規分布を計算して結果をグラフとして出力するプログラムを作成しなさい # f(_x,_y) :- _x_1 is 2 * pi * (_x / 100.0) - pi, _y is truncate(1.0 / ( (2.0 * pi) ^ 2 * exp(-1 * (_x_1 * _x_1 / 2.0))) * 100.0). '正規分布を計算して結果をグラフとして出力するプログラムを作成しなさい' :- 表にグラフを描く(LL1), 転置(LL1,LL2), グラフ表示(LL2). 表にグラフを描く(LL1) :- findall(L,( for(0,_x,100), length(L,101), f(_x,_y), append(L0,[*|R],L), length(L0,_y)), LL1). グラフ表示([]). グラフ表示([L|R]) :- 変数要素を空白に変換(L), atom_chars(A,L), writef('%t\n',[A]), グラフ表示(R). 変数要素を空白に変換([]). 変数要素を空白に変換([' '|R]) :- 変数要素を空白に変換(R). 変数要素を空白に変換([_|R]) :- 変数要素を空白に変換(R). % 以下のサイトは # 出典:: 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/125 # # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク): # 2x+3y−z=1 # x+y+2z=0 # 3x−y+z=2 # 上記方程式を掃き出し法を用いて解くプログラム # '2x+3y−z=1 x+y+2z=0 3x−y+z=2 上記方程式を掃き出し法を用いて解く'(_x,_y,_z) :- 既約ガウス行列に変形([[2,3,-1,1],[1,1,2,0],[3,-1,1,2]],LL), 解の取り出し(LL,[_x,_y,_z]). 解の取り出し(LL,L) :- 転置(LL,LL2), last(LL2,L). % 以下のサイトは 分数の計算と表示 :- 分数を2項読み込む([一,分子,一,分母,二,分子,二,分母],[_分子_1,_分母_1,_分子_2,_分母_2]), _答え仮分数分子 is _分子_1 * _分母_2 + _分子_2 * _分母_1, _答え仮分数分母 is _分母_1 * _分母_2, 最大公約数(_答え仮分数分子,_答え仮分数分母,_最大公約数), _答え仮分数分子_2 is _答え仮分数分子 // _最大公約数, _答え仮分数分母_2 is _答え仮分数分母 // _最大公約数, 帯分数(_答え仮分数分子_2,_答え仮分数分母_2,_答え整数部分, _答え分子,_答え分母), 分数計算表示(_分子_1,_分子_2,_答え分子,_答え整数部分,_分母_1,_分母_2,_答え分母). 分数を2項読み込む([],[]). 分数を2項読み込む([A,B|R1],[C|R2]) :- writef('第%t項の%tを整数で入力してください : ',[A,B]), get_integer(C), 分数を2項読み込む(R1,R2). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, \+(_答えの分子=0), writef(' %2r %2r %2r \n',[_分子_1,_分子_2,_答え分子]), writef('---- + ---- =%2r---- \n',[_整数部分]), writef(' %2r %2r %2r \n',[_分母_1,_分母_2,_答え分母]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 >= 1, 答えの分子=0, writef(' %2r %2r\n',[_分子_1,_分子_2]), writef('---- + ---- = %2r \n',[_整数部分]), writef(' %2r %2r\n',[_分母_1,_分母_2]). 分数計算表示(_分子_1,_分子_2,_答え分子,_整数部分,_分母_1,_分母_2,_答え分母) :- _整数部分 = 0, writef(' %2r %2r %2r \n',[_分子_1,_分子_2,_答え分子]]), write('---- + ---- = ---- \n'), writef(' %2r %2r %2r \n',[_分母_1,_分母_2,_答え分子]]). 帯分数(_仮分数分子,_仮分数分母,_帯分数整数部分, _帯分数分子,_帯分数分母) :- _帯分数整数部分 is _仮分数分子 // _仮分数分母, _帯分数分子 is _仮分数分子 mod _仮分数分母. _帯分数分母 = _仮分数分母. % 行列の掛算の中での分数 行列の掛算(L1,L2,X) :- 転置(L2,L4), 行列の掛算_1(L1,L4,X). 行列の掛算_1([],_,[]) :-!. 行列の掛算_1([A|R1],L,[S1|R3]) :- 行列の掛算_2(A,L,S1), 行列の掛算_1(R1,L,R3). 行列の掛算_2(_,[],[]) :-!. 行列の掛算_2(A,[B|R2],[C|R3]) :- 行列の掛算_3(A,B,C), 行列の掛算_2(A,R2,R3). 行列の掛算_3([],[],0) :-!. 行列の掛算_3([A|R1],[B|R2],S) :- 分数を含む掛算(A,B,S1), 行列の掛算_3(R1,R2,S2), 分数を含む加算(S1,S2,S),!. 分数を含む加算(A1 / A2,B1 / B2,C) :- S1 is A1 * B2 + A2 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む加算(A1 / A2,B,C) :- S1 is A1 + A2 * B, 約分(S1 / A2,C),!. 分数を含む加算(A,B1 / B2,C) :- S1 is B1 + B2 * A, 約分(S1 / B2,C),!. 分数を含む加算(A,B,C) :- C is A + B. 分数を含む掛算(A1 / A2,B1 / B2,C) :- S1 is A1 * B1, S2 is A2 * B2, 約分(S1 / S2,C),!. 分数を含む掛算(A1 / A2,B,C) :- S1 is A1 * B, 約分(S1 / A2,C),!. 分数を含む掛算(A,B1 / B2,C) :- S1 is B1 * A, 約分(S1 / B2,C),!. 分数を含む掛算(A,B,C) :- C is A * B. 約分(B / A,X) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C, 約分の二(_分子,_分母,X),!. 約分の二(_分子,1,_分子) :- !. 約分の二(_分子,1.0,_分子) :- !. 約分の二(_分子,_分母,_分子 / _分母). 最大公約数(M,N,X) :- 最大公約数をユークリッドの互除法で求める(M,N,X),!. 最大公約数をユークリッドの互除法で求める(M,N,N) :- 0 is M mod N,!. 最大公約数をユークリッドの互除法で求める(M,N,X) :- Mod is M mod N, 最大公約数をユークリッドの互除法で求める(N,Mod,X). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % get_numberのなかでの分数 get_number(_数値) :- get_line(Line), get_number_診断(Line,_数値),!. get_number(_数値) :- get_number(_数値). get_number_診断(Line,_数値,_) :- atom_to_term(Line,_数値,_), 数値か(_数値),!. get_number_診断(Line,_数値,_) :- writef('入力された %t からは数値が得られません。再入力をお願いします。\n',[Line]), fail. 数値か(_分子/_分母) :- integer(_分子), integer(_分母),!. 数値か(_数値) :- number(_数値). % '1/3 + 3/5 + 7/9 + 9/11 + 11/13+..........+95/97 + 97/99 を合計する' :- 分子ならび(_分子ならび), 分母ならび(_分母ならび), 分子(_分子ならび,_分母ならび,_分子), 分母(_分母ならび,_分母), _合計 is _分子 / _分母, writef('合計は %t です\n',[_合計]). 分子([N],_分母ならび,_分子) :- '重複のないならびからNを取り除く'(N,_分母ならび,L), 全てを掛ける([N|L],_分子),!. 分子([N|R1],_分母ならび,_分子) :- '重複のないならびからNを取り除く'(N,_分母ならび,L), 全てを掛ける(L,_分子_1), 分子式(R1,_分母ならび,_分子_2), _分子 is _分子_1 + _分子_2. 分子ならび(_分子ならび) :- findall(N,( for(1,N,97), 1 is N mod 2), _分子ならび). 分母([X],X) :- !. 分母([A|R],_分母) :- 分母(R,_分母_1) _分母 is A * _分母_1. 分母ならび(_分母ならび) :- findall(N,( for(3,N,99), 1 is N mod 2), _分母ならび). '重複のないならびからNを取り除く'(N,L,R) :- append(L0,[N|R1],L), append(L0,R1,R),!. % 分数の加算 分数の加算(_分子1/_分母1,_分子2/_分母2,_分子/_分母) :- A is _分母1 * _分母2, B is _分子1 * _分母2 + _分子2 * _分母1, 約分(B/A,_分子/_分母). 約分(B/A,_分子/_分母) :- 最大公約数(B,A,C), _分子 is B // C, _分母 is A // C. % 荷重移動平均 加重移動平均(_データならび,_サンプル数,_加重移動平均) :- reverse(_データならび,_反転したデータならび), length(L0,_サンプル数), append(L0,L1,_反転したデータならび), _分母 is _サンプル数 * (_サンプル数 + 1) / 2, 加重移動平均分子の計算(_サンプル数,L0,_分子), _加重移動平均 is _分子 / _分母,!. 加重移動平均分子の計算(_,[],0) :- !. 加重移動平均分子の計算(N,[A|R],S) :- N1 is N - 1, V is A * N, 加重移動平均分子の計算(N1,R,S1), S is S1 + V. % '2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求める'(_確率) :- '左からi番目のカードに書かれた数がi以上の度数'(1,2,0,0,_分子,_分母), \+(_分母 = 0), _確率 is _分子 / _分母,!. '左からi番目のカードに書かれた数がi以上の度数'(5,_カード,X,Y,X,Y) :- _カード > 6,!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード > 6, _i2 is _i + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i2,2,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分子2 is _分子1 + 1, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母2,_分子,_分母),!. '2,3,4,5,6の数が書かれたカードが1枚ずつ、合計5枚ある。これらのカードを無作為に横一列に並べたとき、どのi=1,2,3,4,5に対しても左からi番目のカードに書かれた数がi以上となる確率を求める'(_確率) :- '左からi番目のカードに書かれた数がi以上の度数'(1,2,0,0,_分子,_分母), \+(_分母 = 0), _確率 is _分子 / _分母,!. '左からi番目のカードに書かれた数がi以上の度数'(5,_カード,X,Y,X,Y) :- _カード > 6,!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード > 6, _i2 is _i + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i2,2,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分子2 is _分子1 + 1, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子2,_分母2,_分子,_分母),!. '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母1,_分子,_分母) :- _カード >= _i, _分母2 is _分母1 + 1, '左からi番目のカードに書かれた数がi以上の度数'(_i,_カード,_分子1,_分母2,_分子,_分母),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1335517816/994 # # [1] 授業単元:C # [2] 問題文(含コード&リンク): # まずテストを受けた生徒の人数を入力し、 # それから各生徒の国語・数学・英語の点数(0〜100点の整数値)を入力して # 2次元の配列に格納したうえで、生徒別の合計点・平均点と科目別の合計点・平均点とを # 小数点以下まで計算して表示するプログラムを作成しなさい。 # ただしテストを受ける生徒の人数は20人以下とする。 # 'まずテストを受けた生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)、それから各生徒の国語・数学・英語の点数(0〜100点の整数値)を入力して2次元の配列に格納したうえで、生徒別の合計点・平均点と科目別の合計点・平均点とを小数点以下まで計算して表示する。' :- 'まずテストを受けた生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)'(_生徒の人数), 'それから各生徒の国語・数学・英語の点数(0〜100点の整数値)を入力して2次元の配列に格納したうえで'(_生徒の人数,_生徒の二次元得点ならび), '生徒別の合計点・平均点と科目別の合計点・平均点とを小数点以下まで計算して表示する'(_生徒の人数,_生徒の二次元得点ならび). 'まずテストを受けた生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)'(_生徒の人数) :- get_line(Line), '診断: 生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)'(Line,_生徒の人数),!. 'まずテストを受けた生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)'(_生徒の人数) :- 'まずテストを受けた生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)'(_生徒の人数). '診断: 生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)'(Line,_生徒の人数) :- atom_to_term(Line,_生徒の人数), ただしテストを受ける生徒の人数は20人以下(_生徒の人数),!. '診断: 生徒の人数を入力し(ただしテストを受ける生徒の人数は20人以下)'(Line,_生徒の人数) :- writef('入力された %t からは20人以下の生徒数が得られません。再入力をお願いします。\n',[Line]), fail. ただしテストを受ける生徒の人数は20人以下(_生徒の人数) :- integer(_生徒の人数), _生徒の人数 > 0, _生徒の人数 =< 20. 'それから各生徒の国語・数学・英語の点数(0〜100点の整数値)を入力して2次元の配列に格納したうえで'(_生徒の人数,_生徒の二次元得点ならび) :- length(_生徒の二次元得点ならび,_生徒の人数), findall([_国語の点数,_数学の点数,_英語の点数],( append(Ln,[_|_],_生徒の二次元得点ならび), '国語・数学・英語の点数(0〜100点の整数値)を入力して'(Ln,_国語の点数,_数学の点数,_英語の点数)), _生徒の二次元得点ならび). '国語・数学・英語の点数(0〜100点の整数値)を入力して'(Ln,_国語の点数,_数学の点数,_英語の点数) :- length([_|Ln],_何番目), writef('%t番目の生徒の国語・数学・英語の点数をカンマ区切りで入力してください : ',[_何番目]), get_line(Line), '診断: 国語・数学・英語の点数(0〜100点の整数値)を入力して'(Ln,Line,_国語の点数,_数学の点数,_英語の点数),!. '国語・数学・英語の点数(0〜100点の整数値)を入力して'(Ln,_国語の点数,_数学の点数,_英語の点数) :- '国語・数学・英語の点数(0〜100点の整数値)を入力して'(Ln,_国語の点数,_数学の点数,_英語の点数). '診断: 国語・数学・英語の点数(0〜100点の整数値)を入力して'(Ln,Line,_国語の点数,_数学の点数,_英語の点数) :- split(Line,[',',' '],[_国語の点数,_数学の点数,_英語の点数]), '0〜100点の整数値'(_国語の点数), '0〜100点の整数値'(_数学の点数), '0〜100点の整数値'(_英語の点数),!. '0〜100点の整数値'(_国語の点数) :- integer(_点数), _点数 >= 0, _点数 =< 100. '生徒別の合計点・平均点と科目別の合計点・平均点とを小数点以下まで計算して表示する'(_生徒の人数,_生徒の二次元得点ならび) :- '生徒別の合計点・平均点を小数点以下まで計算して表示する'(_生徒の人数,_生徒の二次元得点ならび), '科目別の合計点・平均点とを小数点以下まで計算して表示する'(_生徒の人数,_生徒の二次元得点ならび), '生徒別の合計点・平均点を小数点以下まで計算して表示する'(_生徒の人数,_生徒の二次元得点ならび) :- append(Ln,[_生徒の得点ならび|R],_生徒の二次元得点ならび), length([_|Ln],_何番目), sum(_生徒の得点ならび,_生徒の合計点), _生徒の平均点 is _生徒の合計点 / 3, writef('%t番目の生徒の合計点は %t, 平均点は %t です。\n',[_生徒の合計点,_生徒の平均点]), R = []. '科目別の合計点・平均点とを小数点以下まで計算して表示する'(_生徒の人数,_生徒の二次元得点ならび) :- 転置(_生徒の二次元得点ならび,[_国語の得点ならび,_数学の得点ならび,_英語の得点ならび]), 国語の合計点と平均点を表示する(_生徒の人数,_国語の得点ならび), 数学の合計点と平均点を表示する(_生徒の人数,_数学の得点ならび), 英語の合計点と平均点を表示する(_生徒の人数,_英語の得点ならび). 国語の合計点と平均点を表示する(_生徒の人数,_国語の得点ならび) :- sum(_国語の得点ならび,_国語の合計点), _国語の平均点 is _国語の合計点 / _生徒の人数, writef('国語の合計点は %t, 国語の平均点は %t です\n',[_国語の合計点,_国語の平均点]). 数学の合計点と平均点を表示する(_生徒の人数,_数学の得点ならび) :- sum(_数学の得点ならび,_数学の合計点), _数学の平均点 is _数学の合計点 / _生徒の人数, writef('数学の合計点は %t, 数学の平均点は %t です\n',[_数学の合計点,_数学の平均点]). 英語の合計点と平均点を表示する(_生徒の人数,_英語の得点ならび) :- sum(_英語の得点ならび,_英語の合計点), _英語の平均点 is _英語の合計点 / _生徒の人数, writef('英語の合計点は %t, 英語の平均点は %t です\n',[_英語の合計点,_英語の平均点]). % sum/2 % 以下のサイトは # 出典:: 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. % 以下のサイトは # # 述語経路/2を定義するための述語 経路定義/1 を定義しなさい。 # # 仕様として図.2のような格子状グラフが述語'図2.1'で定義されています。 # これを図.2.2で表されるグラフに対応する 述語 経路/1として定義します。 # 節の名称は"あ-と"を述語 節の命名順/1 の引数リストから受け取って # 順に振っていきます。 # # P-+-+-+ あーいーうーえ # | | | | | | | |  # +-+-+-+ おーかーきーく # | | | |   | | # +-+-+ + けーこーさ し # | | | | | | | | # +-+ +-+ すーせ そーた # | | | | | | | | # +-+-+-Q ちーつーてーと # # 図.2 図.2.2 # # この図.2から 図.2.2 に対応する述語 経路/2 を以下のように定義するための # 述語を定義します。 # # 経路(あ,い). # 経路(あ,お). # 経路(い,う). # 経路(い,か). # 経路(う,え). # 経路(う,き). # 経路(え,く). # 経路(お,か). # 経路(お,け). # 経路(か,き). # 経路(き,く). # 経路(き,さ). # 経路(く,し). # 経路(け,こ). # 経路(け,す). # 経路(こ,さ). # 経路(こ,せ). # 経路(さ,そ). # 経路(し,た). # 経路(す,せ). # 経路(す,ち). # 経路(せ,つ). # 経路(そ,た). # 経路(ち,つ). # 経路(つ,て). # 経路(て,と). # 節の命名順([あ,い,う,え,お,か,き,く,け,こ,さ,し,す,せ,そ,た,ち,つ,て,と]). '図.2.1'([['P',-,+,-,+,-,+], ['|',' ','|',' ','|',' ','|'], [+,-,+,-,+,-,+], ['|',' ',' ',' ','|',' ','|'], [+,-,+,-,+,' ',+], ['|',' ','|',' ','|',' ','|'], [+,-,+,' ',+,-,+], ['|',' ','|',' ','|',' ','|'], [+,-,+,-,+,-,'Q']]). % '図.2.1'([['あ',-,い,-,う,-,え], % ['|',' ','|',' ','|',' ','|'], % [お,-,か,-,き,-,く], % ['|',' ',' ',' ','|',' ','|'], % [け,-,こ,-,さ,' ',し], % ['|',' ','|',' ','|',' ','|'], % [す,-,せ,' ',そ,-,た], % ['|',' ','|',' ','|',' ','|'], % [ち,-,つ,-,て,-,と]]). 接続定義 :- '図.2.1'(_グラフ), 節に名前を振る(_グラフ,_命名された節をもつグラフ), 接続定義(_命名された節をもつグラフ). 節に名前を振る(_グラフ,_命名された節をもつグラフ) :- 節の命名順(_節の命名順), 節に名前を振る(_グラフ,_節の命名順,_命名された節をもつグラフ). 節に名前を振る([],_,[]). 節に名前を振る([L1|R1],L2,[L1_2|R3]) :- 節に名前を振る(L1,L2,R,L1_2), 節に名前を振る(R1,R,R3). 節に名前を振る([],R2,R2,[]). 節に名前を振る(['P'|R1],[A|R2],R,[A|R4]) :- assertz(出発点(A)), 節に名前を振る(R1,R2,R,R4). 節に名前を振る(['Q'|R1],[A|R2],R,[A|R4]) :- assertz(終着点(A)), 節に名前を振る(R1,R2,R,R4). 節に名前を振る(['+'|R1],[A|R2],R,[A|R4]) :- 節に名前を振る(R1,R2,R,R4),!. 節に名前を振る([' '|R1],L2,R,[' '|R4]) :- 節に名前を振る(R1,L2,R,R4),!. 節に名前を振る([_記号|R1],L2,R,[_記号|R4]) :- 節に名前を振る(R1,L2,R,R4). 右と下両方向の接続定義(_命名された節をもつグラフ) :- 接続定義(_命名された節をもつグラフ), 転置(_命名された節をもつグラフ,_転置された命名された節をもつグラフ), 接続を定義する(_転置された命名された節をもつグラフ). 接続定義([]) :- !. 接続定義([L|R]) :- 一列の接続の定義(L), 接続定義(R). 一列の接続の定義([]). 一列の接続の定義([A,-,C|R]) :- \+(空白か記号(A)), \+(空白か記号(C)), assertz(接続(A,B)), 一列の接続の定義([C|R]),!. 一列の接続の定義([A,'|',C|R]) :- \+(空白か記号(A)), \+(空白か記号(C)), assertz(接続(A,B)), 一列の接続の定義([C|R]),!. 一列の接続定義([A|R]) :- 接続の定義(R). 空白か記号(' ') :- !. 空白か記号(A) :- member(A,[-,'|']). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1328276597/309 # # 1から5の間の自然数を10個入力する。このとき入力された数の個数を棒グラフで次のように表示させる。 # 例: 1の入力が4回、2では2回、3では3回、4では0回、5では1回の場合 # * # * * # * * * # * * * * # 1 2 3 4 5 # という感じです。全くできないので助けてください # '1から5の間の自然数を10個入力する。このとき入力された数の個数を棒グラフで次のように表示させる' :- '1から5の間の自然数を10個入力する'(L), 横方向棒グラフを作る(L,LL1), 転置(LL1,LL2), 棒グラフ表示(LL2). '1から5の間の自然数を10個入力する'(L) :- length(L,10), findall(N,( append(L0,[N|_],L), '1から5の間の自然数を'(L0,N)), L). '1から5の間の自然数を'(L0,_自然数分の星ならび) :- length([_|L0],M), concat_atom([M,'1から5の間の自然数([',M,'/10] : '],_催促文), '1から5の間の自然数を'(_催促文,M,N),!. '1から5の間の自然数を'(_催促文,M,N) :- writef('%t',[_催促文]), get_line(Line), '1から5の間の自然数入力診断'(Line,N),!. '1から5の間の自然数を'(_催促文,M,N) :- '1から5の間の自然数を'(_催促文,M,N). '1から5の間の自然数入力診断'(Line,N) :- atom_to_term(Line,N,_), integer(N), N >= 1, N =< 5,!. '1から5の間の自然数入力診断'(Line,N) :- writef('入力された%tからは1から5の間の自然数が得られません\n',[Line]), fail. 横方向棒グラフを作る([],[]). 横方向棒グラフを作る([N|R1],[L|R2]) :- length(L,5), length(L1,N), all(L1,'*'), append(L0,L1,L), all(L0,' '), 横方向棒グラフを作る(R1,R2). 棒グラフ表示(LL) :- append(_,[L|R],LL), concat_atom(L,' ',_行表示文字列), writef('%t\n',[_行表示文字列]), R = [], write('1 2 3 4 5\n'). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1309076891/729 # # 【 課題 】<プログラムの仕様> # ・N人の、M科目の成績が書かれたCSVファイルを読み込む # ・平均点、最高点、最低点、度数分布を各科目毎に出力する # ・各科目、総合点のランキングリストを出力する # ・成績の処理結果をテキストファイルに出力する # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 GUI  】4. 制限なし # 【 期限 】1/26(木) 20:00 # 【 Ver  】java version "1.7.0" # 【 補足 】http://ime.nu/www1.axfc.net/uploader/Sc/so/311237.zip #       上記のリンクが、課題のCSVファイルと、 #       参考資料としてあげられていたCSVファイルの読み込み・書き込みを行うプログラムです。 #       CSVファイルは編集してはならないとのことです。 #       CSVファイルは、左から順番に、 #       「国語」「数学」「英語」「社会」「理科」「美術」「工芸」「書道」「音楽」「体育」の科目で、 #       上から順番に「生徒1」「生徒2」・・・「生徒100」となっております。 #       よろしくお願いいたします。 # '・N人の、M科目の成績が書かれたCSVファイルを読み込む ・平均点、最高点、最低点、度数分布を各科目毎に出力する ・各科目、総合点のランキングリストを出力する ・成績の処理結果をテキストファイルに出力する'(_CSVファイル,_書き込みテキストファイル) :- get_split_lines(_CSVファイル,[','],LL), 転置(LL,_転置LL), '平均点、最高点、最低点、度数分布を各科目毎に集約する'([国語,数学,英語,社会,理科,美術,工芸,書道,音楽,体育],_転置LL,_集約リスト), 総合点のランキングリスト(LL,_総合点のランキングリスト), 出力する(_書き込みテキストファイル,_集約リスト,_総合点のランキングリスト). '平均点、最高点、最低点、度数分布を各科目毎に集約する'([],[],[]). '平均点、最高点、最低点、度数分布を各科目毎に集約する'([_科目|R1],[_列|R2],[[_科目,_平均点,_最高点,_最低点,_度数分布,_ランキングリスト]|R3]) :- 最高点(_列,_最高点), 最低点(_列,_最低点), 平均点(_列,_平均点), 度数分布(_列,_度数分布), 科目毎のランキングリスト(_列,_ランキングリスト), '平均点、最高点、最低点、度数分布を各科目毎に集約する'(R1,R2,R3). 総合点のランキングリスト(LL,_ランキングリスト) :- 総合点集約(1,LL,LL1), sort(LL1,LL2), reverse(LL3,_ランキングリスト). 総合点集約(_,[],[]). 総合点集約(N,[_行|R1],[[_合計点,N]|R2]) :- sum(_行,_合計点), N2 is N + 1, 集合点集約(N2,R1,R2). 度数分布(_列,_度数分布) :- findall(_度数,( member([_点数下限,_点数上限],[[0,19],[20,39],[40,59],[60,79],[80,100]]), count(( member(_点数,_列), _点数 >= _点数下限, _点数 =< _点数上限), _度数分布). 科目毎のランキングリスト(_列,_ランキングリスト), 整列用ランキングリスト(1,_列,_整列用ランキングリスト), sort(_整列用ランキングリスト,_整列済みランキングリスト), reverse(_整列済みランキングリスト,_ランキングリスト). 整列用ランキングリスト(_,[],[]). 整列用ランキングリスト(N,[_得点|R1],[[_得点,N]|R2]) :- N2 is N + 1, 整列用ランキングリスト(N2,R1,R2). 出力する(_書き込みテキストファイル,_集約リスト,_総合点のランキングリスト) :- open(_書き込みテキストファイル,write,Outstream), 科目別項目の書き込み(Outstream,_集約リスト), 総合点のランキングの書き込み(Outstream,_総合点ランキングリスト), close(Outstream). 科目別項目の書き込み(Outstream,_集約リスト) :- append(_,[[_科目,_平均点,_最高点,_最低点,_度数分布,_ランキングリスト]|R],_集約リスト), writef(Outstream,'科目 %t\n',[_科目]), writef(Outstream,'平均点 %4r\n最高点 %4r\n最低点 %4r\n',[_平均点,_最高点,_最低点]), writef(Outstream,'0~19点 %4r\n20~39点 %4r\n40~59点 %4r\n60~79点 %4r\n80~100点 %4r\n',_度数分布), write('%tランキングリスト\n',[_科目]), ランキングリストの書き込み(Outstream,_ランキングリスト), R = []. ランキングリストの書き込み(Outstream,_ランキングリスト) :- ランキングリストの書き込み(Outstream,1,1,_ランキングリスト). ランキングリストの書き込み(Outstream,_,_,[]) :- !. ランキングリストの書き込み(Outstream,_順位,_順位_1,[[_得点,_生徒番号_1],[_得点,_生徒番号_2]|R]) :- writef(Outstream,'%4r 生徒%2l %4r\n',[_順位,_生徒番号_1,_得点]), _順位_2 is _順位_1 + 1, ランキングリストの書き込み(Outstream,_順位,_順位_2,[[_得点,_生徒番号_2]|R]). ランキングリストの書き込み(Outstream,_順位,_順位_1,[[_得点,_生徒番号]|R]) :- write(Outstream,N1,N2,'科目毎ランキング\n'), writef(Outstream,'%4r 生徒%2l %4r\n',[_順位,_生徒番号,_得点]), _順位_2 is _順位_1 + 1, ランキングリストの書き込み(Outstream,_順位_2,_順位_2,R). 総合点のランキングの書き込み(Outstream,_総合点ランキングリスト) :- write('総合点ランキング\n'), ランキングリストの書き込み(Outstream,_総合点ランキングリスト). % 以下のサイトは バイナリファイル (標準入力) に一致しました % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/610 # # 【質問テンプレ】 # [1] 授業単元:情報技術 # [2] 問題文(含コード&リンク): # 以下の2つの要件を満たす、3行3列の行列の積を計算し、表示するプログラムmultiply.cを作成せよ。 # # (1)整数型の行列A,Bおよびそれらの行列積A*Bを、以下の配列名で宣言する(A,Bの値は各個人で自由に設定)。 # # int matrix_a[3][3]={{1,2,3},{4,5,6},{7,8,9}};/*行列A*/ # int matrix_b[3][3]={{10,11,12},{13,14,15},{16,17,18}};/*行列B*/ # int matrix_multiply_a_by_b[3][3]={{0,0,0},{0,0,0},{0,0,0}};/*計算結果代入用の行列*/ # # (2)行列の積A*Bのi行j列目の要素の計算を、for文を用いて行うこと。 # # matrix_a([[1,2,3],[4,5,6],[7,8,9]]). matrix_b([[10,11,12],[13,14,15],[16,17,18]]). '行列の積A*Bのi行j列目の要素の計算を、for文を用いて行うこと。'(_i行,_j列,_i行j列の要素) :- 'matrix_aのi行とmatrix_bのj列'(_i行目,_j列目,L1,L2), findsum(S,( for(1,N,3), nth1(N,L1,A), nth1(N,L2,B), S is A * B), _i行j列の要素). 'matrix_aのi行とmatrix_bのj列'(_i行目,_j列目,L1,L2) :- matrix_a(LL1), matrix_b(LL2), nth1(_i行,LL1,L1), 'matrix_bのj列ならび'(_j列目,LL2,L2). 'matrix_bのj列ならび'(_,_,[],[]). 'matrix_bのj列ならび'(_j列目,[L1|R1],[X|R2]) :- nth1(_j列目,L1,X), 'matrix_bのj列ならび'(_j列目,R1,R2). findsum(A,B,C) :- findall(A,B,L), sum(L,C). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% '行列の積A*Bのi行j列目の要素の計算'(_i行,_j列,_i行j列の要素) :- 'matrix_aのi行とmatrix_bのj列'(_i行目,_j列目,L1,L2), 'i行j列目の要素は'(L1,L2,_i行j列目の要素). 'i行j列目の要素は'([A],[B],S) :- S is A * B,!. 'i行j列目の要素は'([A|R1],[B|R2],S) :- 'i行j列目の要素は'(R1,R2,S_2), S is A * B + S_2. 'matrix_aのi行とmatrix_bのj列'(_i行目,_j列目,L1,L2) :- matrix_a(LL1), matrix_b(LL2), 転置(LL2,LL2_2), nth1(_i行,LL1,L1), nth1(_j列,LL2_2,L2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% '行列の積A*Bのi行j列目の要素の計算'(_i行,_j列,_i行j列の要素) :- matrix_a(LL1), matrix_b(LL2), '3×3の行列の掛算演算表'(LL1,LL2,LL3), nth1(_i行,LL3,L), nth1(_j列,L,_式), _i行j列の要素 is _式. '3×3の行列の掛算演算表'([ [A11,A12,A13], [A21,A22,A23], [A31,A32,A33]], [[B11,B12,B13], [B21,B22,B23], [B31,B32,B33]], [[A11*B11+A12*B21+A13*B31,A11*B12+A12*B22+A13*B32,A11*B13+A12*B23+A13*B33], [A21*B11+A22*B21+A23*B31,A21*B12+A22*B22+A23*B32,A21*B13+A22*B23+A23*B33], [A31*B11+A32*B21+A33*B31,A31*B12+A32*B22+A33*B32,A31*B13+A32*B23+A33*B33]]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/481 # # # [1] 授業単元:プログラミング # [2] 問題文(含コード&リンク):(1,10,5) (1,20,10)...というテキストデータを読み込み、一番左の数字(ここでいう1と1)を一つの配列として表示と書きこみをするプログラム。(真ん中も右の数字も同じように処理する) #  [3.1] OS: (Windows/Linux/等々) Linux #  [3.2] コンパイラ名とバージョン: (gcc 3.4 VC 6.0等) gcc #  [3.3] 言語: (C/C++/どちらでも可 のいずれか) c言語 # [4] 期限: ([yyyy年mm月dd日hh:mmまで] または [無期限] のいずれか) 11月23日 15時 # [5] その他の制限: (どこまで習っているか、標準ライブラリは使ってはいけない等々) 何でもおk # # '(1,10,5) (1,20,10)...というテキストデータを読み込み、一番左の数字(ここでいう1と1)を一つのならびとして表示と書きこみをする'(_何列目) :- get_line(_テキスト), '各構造の一番左の数字(ここでいう1と1)を一つのならびとして'(_テキスト,_括弧内の列で並べ直した行列), 括弧内の列で並べ直した行列を書きだす(_括弧内の列で並べ直した行列), 列データを順に表示する(_何列目,_括弧内の列で並べ直した行列). 括弧内の列で並べ直した行列を書きだす(_何列目,_括弧内の列で並べ直した行列) :- assertz(括弧内の列で並べ直した行列(_何列目,_括弧内の列で並べ直した行列)). 列データを順に表示する(_何列目,_括弧内の列で並べ直した行列) :- append(L0,[_ならび|_],_括弧内の列で並べ直した行列), length([_|L0],_何列目), writef('%t: %t\n',[_何列目,_ならび]). '一番左の数字(ここでいう1と1)を一つのならびとして'(_テキスト,_括弧内の列で並べ直した行列) :- 括弧構造を行列に変換(_テキスト,_行列), 転置(_行列,_括弧内の列で並べ直した行列). 括弧構造を行列に変換(_テキスト,_行列) :- split(_テキスト,['(',')'],L), findall(L1,( append(_,[S|_],L), split(S,[','],L1)), LL). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは # 出典:: 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/399 # # [1] 授業単元:C言語入門 # [2] 問題文(含コード&リンク):http://ime.nu/i.imgur.com/UwzPZ.jpg # # # 下の例のような、学生の4科目の(数学、物理、科学、英語)の試験点数(100点満点)を # 書いたファイルがある。(学生数は100名以下) # # ファイルを読んで、右のように、学生の科目の一覧と、各学生の平均点、 # 各科目の平均点を表示するプログラムを作成する。 # # ・ 科目名(6文字未満)を入れる文字列(文字の一次元配列)を4つ用意する。 # # ・ 学籍番号と点数を一緒に入れる二次元整数配列を用意する # 例 int tensu[ ? ][ ? ] # # 最初に二次元配列を表示して、実行例のように点数を表示し、次に各学生の # 平均点、各科目の平均点を表示する。 # # ただし、ファイルの先頭には学生数(この例では5名)があり、つぎに4科目の # 科目名(数学、物理、科学、英語)が記述され、続いて、1行目に指定した学生数分 # の学籍番号と各試験点数が書かれている。 # # # ファイルの例(5名の例) # # 5 # Math Phys Chem Eng # 8001 78 64 88 90 # 8004 34 40 52 67 # 8013 83 77 89 93 # 8035 98 81 69 77 # 8062 56 63 47 23 # # 表示例 # # 点数 :::: # 8001 78 64 88 90 # 8004 34 40 52 67 # 8013 83 77 89 93 # 8035 98 81 69 77 # 8062 56 63 47 23 # # 学生平均 :::: # 8001 : 80.0 # 8004 : 48.25 # 8013 : 85.50 # 8035 : 81.25 # 8062 : 47.25 # # 科目平均 # 数学 : 69.8 # 物理 : 65.0 # 科学 : 69.0 # 英語 : 70.0 # 'ファイルを読んで、右のように、学生の科目の一覧と、各学生の平均点、書く科目の平均点を表示する'(_ファイル名) :- 'ファイルを読んで'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび), '学生の科目の一覧と、各学生の平均点、書く科目の平均点を表示する'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび). 'ファイルを読んで'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび) :- get_lines(_ファイル名,Lines), 'ファイルの先頭には学生数(この例では5名)があり'(Lines,_学生数), 'つぎに4科目の科目名(数学、物理、科学、英語)が記述され'(Lines,_科目名ならび), '続いて、1行目に指定した学生数分の学籍番号と各試験点数が書かれている'(Lines,_学生数,_学籍番号と各試験点数ならび),!. 'ファイルの先頭には学生数(この例では5名)があり'(Lines,_学生数) :- Lines = [_学生数文字列|_], atom_to_term(_学生数文字列,_学生数,_), integer(_学生数),!. 'つぎに4科目の科目名(数学、物理、科学、英語)が記述され'(Lines,_科目名ならび) :- Lines = [_,_二行目文字列|_], split(_二行目文字列,[' ',','],_科目名ならび),!. '続いて、1行目に指定した学生数分の学籍番号と各試験点数が書かれている'(Lines,_学生数,_学籍番号と各試験点数ならび) :- length(_学籍番号と各試験点数ならび,_学生数), Lines = [_,_|_残りLines], findall(_学籍番号と各点数,( append(_,[_学籍番号と各点数文字列|_],_残りLines), aplit(_学籍番号と各点数文字列,[' ',','],_学籍番号と各点数)), _学籍番号と各試験点数ならび). '学生の科目の一覧と、各学生の平均点、書く科目の平均点を表示する'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび) :- 学生の科目の一覧を表示(_学籍番号と各試験点数ならび), '各学生の平均点、各科目の平均点を表示する'(_科目名ならび,_学籍番号と各試験点数ならび). 学生の科目の一覧を表示(_学籍番号と各試験点数ならび) :- append(_,[_学籍番号と各試験点数|R],_学籍番号と各試験点数ならび), concat_atom(_学籍番号と各試験点数,' ',_表示文字列), writef('%t\n',[_表示文字列]), R = []. '各学生の平均点、各科目の平均点を表示する'(_科目名ならび,_学籍番号と各試験点数ならび) :- 各学生の平均点(_学籍番号と各試験点数ならび,_各学生の平均点ならび), 各科目の平均点(_科目名ならび,_学籍番号と各試験点数ならび,_各科目の平均点ならび), 各学生の平均点を表示する(_各学生の平均点ならび), 各科目の平均点を表示する(_各科目の平均点ならび). 各学生の平均点(_学籍番号と各試験点数ならび,_各学生の平均点ならび) :- findall([_学籍番号,_平均点],( append(_,[[_学籍番号|L]|_],_学籍番号と各試験点数ならび), 相加平均(L,_平均点)), _各学生の平均点ならび). 各科目の平均点(_科目名ならび,_学籍番号と各試験点数ならび,_各科目の平均点ならび) :- 転置(_学籍番号と各試験点数ならび,[_|_科目別点数ならび]), findall([_科目名,_平均点],( 科目名と点数ならびを得る(_科目名ならび,_学籍番号と各試験点数ならび,_科目名,_点数ならび), 相加平均(_点数ならび,_平均点)), _各科目の平均点ならび). 科目名と点数ならびを得る(_科目名ならび,_学籍番号と各試験点数ならび,_科目名,_点数ならび) :- append(L0,[_科目名|_],_科目名ならび), length(L0,Len), nth1(Len,_科目別点数ならび,_点数ならび). 各学生の平均点を表示する(_各学生の平均点ならび) :- write('\n学生平均 ::::\n'), append(_,[[_学籍番号,_平均点]|R],_各学生の平均点ならび), writef('%8r : %5r\n',[_学籍番号,_平均点]), R = []. 各科目の平均点を表示する(_各科目の平均点ならび) :- write('\n科目平均 ::::\n'), append(_,[[_科目名,_平均点]|R],_各科目の平均点ならび), writef('8r : %5r\n',[_科目名,_平均点]), R = []. % % http://nojiriko.asia/prolog/c153_399.html の % 各学生の平均点以下の述語定義と比較して、 % どちらが、理解しやすいかを問う。 % % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/399 # # [1] 授業単元:C言語入門 # [2] 問題文(含コード&リンク):http://ime.nu/i.imgur.com/UwzPZ.jpg # # # 下の例のような、学生の4科目の(数学、物理、科学、英語)の試験点数(100点満点)を # 書いたファイルがある。(学生数は100名以下) # # ファイルを読んで、右のように、学生の科目の一覧と、各学生の平均点、 # 各科目の平均点を表示するプログラムを作成する。 # # ・ 科目名(6文字未満)を入れる文字列(文字の一次元配列)を4つ用意する。 # # ・ 学籍番号と点数を一緒に入れる二次元整数配列を用意する # 例 int tensu[ ? ][ ? ] # # 最初に二次元配列を表示して、実行例のように点数を表示し、次に各学生の # 平均点、各科目の平均点を表示する。 # # ただし、ファイルの先頭には学生数(この例では5名)があり、つぎに4科目の # 科目名(数学、物理、科学、英語)が記述され、続いて、1行目に指定した学生数分 # の学籍番号と各試験点数が書かれている。 # # # ファイルの例(5名の例) # # 5 # Math Phys Chem Eng # 8001 78 64 88 90 # 8004 34 40 52 67 # 8013 83 77 89 93 # 8035 98 81 69 77 # 8062 56 63 47 23 # # 表示例 # # 点数 :::: # 8001 78 64 88 90 # 8004 34 40 52 67 # 8013 83 77 89 93 # 8035 98 81 69 77 # 8062 56 63 47 23 # # 学生平均 :::: # 8001 : 80.0 # 8004 : 48.25 # 8013 : 85.50 # 8035 : 81.25 # 8062 : 47.25 # # 科目平均 # 数学 : 69.8 # 物理 : 65.0 # 科学 : 69.0 # 英語 : 70.0 # 'ファイルを読んで、右のように、学生の科目の一覧と、各学生の平均点、書く科目の平均点を表示する'(_ファイル名) :- 'ファイルを読んで'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび), '学生の科目の一覧と、各学生の平均点、書く科目の平均点を表示する'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび). 'ファイルを読んで'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび) :- get_lines(_ファイル名,Lines), 'ファイルの先頭には学生数(この例では5名)があり'(Lines,_学生数), 'つぎに4科目の科目名(数学、物理、科学、英語)が記述され'(Lines,_科目名ならび), '続いて、1行目に指定した学生数分の学籍番号と各試験点数が書かれている'(Lines,_学生数,_学籍番号と各試験点数ならび),!. 'ファイルの先頭には学生数(この例では5名)があり'(Lines,_学生数) :- Lines = [_学生数文字列|_], atom_to_term(_学生数文字列,_学生数,_), integer(_学生数),!. 'つぎに4科目の科目名(数学、物理、科学、英語)が記述され'(Lines,_科目名ならび) :- Lines = [_,_二行目文字列|_], split(_二行目文字列,[' ',','],_科目名ならび),!. '続いて、1行目に指定した学生数分の学籍番号と各試験点数が書かれている'(Lines,_学生数,_学籍番号と各試験点数ならび) :- length(_学籍番号と各試験点数ならび,_学生数), Lines = [_,_|_残りLines], findall(_学籍番号と各点数,( append(_,[_学籍番号と各点数文字列|_],_残りLines), aplit(_学籍番号と各点数文字列,[' ',','],_学籍番号と各点数)), _学籍番号と各試験点数ならび). '学生の科目の一覧と、各学生の平均点、書く科目の平均点を表示する'(_学生数,_科目名ならび,_学籍番号と各試験点数ならび) :- write('\n'), 学生の科目の一覧を表示(_学籍番号と各試験点数ならび), '各学生の平均点、各科目の平均点を表示する'(_科目名ならび,_学籍番号と各試験点数ならび). 学生の科目の一覧を表示(_学籍番号と各試験点数ならび) :- append(_,[_学籍番号と各試験点数|R],_学籍番号と各試験点数ならび), concat_atom(_学籍番号と各試験点数,' ',_表示文字列), writef('%t\n',[_表示文字列]), R = []. '各学生の平均点、各科目の平均点を表示する'(_科目名ならび,_学籍番号と各試験点数ならび) :- 各学生の平均点(_学籍番号と各試験点数ならび,_各学生の平均点ならび), 各科目の平均点(_科目名ならび,_学籍番号と各試験点数ならび,_各科目の平均点), write('\n学生平均 ::::\n'), 各学生の平均点を表示する(_各学生の平均点ならび), write('\n科目平均 ::::\n'), 各科目の平均点を表示する(_各科目の平均点). 各学生の平均点([],[]). 各学生の平均点([[_学籍番号|L]|R1],[[_学籍番号,_平均点]|R2]) :- 相加平均(L,_平均点), 各学生の平均点(R1,R2). 各科目の平均点(_科目名ならび,_学籍番号と各試験点数ならび,_各科目の平均点) :- 転置(_学籍番号と各試験点数ならび,[_|_科目別点数ならび]), 転置された点数ならびから科目別平均点を得る(_科目名ならび,_科目別点数ならび,_各科目の平均点). 転置された点数ならびから科目別平均点を得る([],[],[]). 転置された点数ならびから科目別平均点を得る([_科目名|R1],[L|R2],[[_科目名,_平均点]|R3]) :- 相加平均(L,_平均点), 転置された点数ならびから科目別平均点を得る(R1,R2,R3). 各学生の平均点を表示する([]). 各学生の平均点を表示する([[_学籍番号,_平均点]|R]) :- writef('%8r : %5r\n',[_学籍番号,_平均点]), 各学生の平均点を表示する(R). 各科目の平均点を表示する([]). 各科目の平均点を表示する([[_科目名,_平均点]|R]) :- writef('8r : %5r\n',[_科目名,_平均点]), 各科目の平均点を表示する(R). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/421 # # [1] 授業単元:C言語 # [2] 問題文:ガウスの消去法を使ってn元連立方程式を解け # http://ime.nu/ideone.com/2GwBp # ガウスの消去法を使ってn元連立方程式を解け(_n元,_解ならび) :- 拡大係数行列を得る(_n元,_拡大係数行列), 既約ガウス行列に変形(_拡大係数行列,_既約ガウス行列), 最終列を取り出す(_既約ガウス行列,_解ならび). 拡大係数行列を得る(_n元,_拡大係数行列) :- M is _n元 + 1, length(_拡大係数行列,_n元), findall(_行,( append(Ln,[_行|R],_拡大係数行列), length(_行,M), length([_|Ln],_何行目), 係数の入力(_何行目,1,_n元,_行)), _拡大係数行列). 係数の入力(_何行目,1,_n元,_行) :- writef('%t行目 : ',[_何行目]), findall(_係数,( for(1,N,_n元), writef('A * X[%t] : ',[N]), 数を得る(_係数)), _係数ならび), write(' = A :'), 数を得る(_最後の係数), append(_係数ならび,[_最後の係数],_行),!. 最終列を取り出す(_行列,_最終列) :- 転置(_行列,_最終列), append(_,[_最終列],_転置された行列). 数を得る(_数) :- get_line(Line), 数を得る診断(Line,_数),!. 数を得る(_数) :- 数を得る(_数). 数を得る診断(Line,_数) :- atom_to_term(Line,_数,_), 数の形式検査(_数),!. 数を得る診断(Line,_数) :- writef('入力された %t からは適切な係数が得られませんでした。再入力をお願いします。\n',[Line]), fail. 数の形式検査(_数) :- number(_数),!. 数の形式検査(_数1 / _数2) :- number(_数1), number(_数2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/328 # # 【質問テンプレ】 # [1] 授業単元:多次元配列 # [2] 問題文(含コード&リンク): 要素が整数からなる3x3の表データを scanf()関数を用いて読み込み、対角線を軸と して要素を入れ替えた表を表示するプログラ ムを作りなさい。 '要素が整数からなる3x3の表データを scanf()関数を用いて読み込み、対角線を軸として要素を入れ替えた表を表示する'(_対角線を軸として要素を入れ替えた表) :- '要素が整数からなる3x3の表データを scanf()関数を用いて読み込み'(_表), '対角線を軸として要素を入れ替えた表を表示する'(_表,_対角線を軸として要素を入れ替えた表). '要素が整数からなる3x3の表データを scanf()関数を用いて読み込み'(_表) :- length(_表,3), findall(L,( append(_,[L|_],_表), write('3列をカンマ区切りで入力して下さい : '), readln(L)), _表). '対角線を軸として要素を入れ替えた表を表示する'(_表,_対角線を軸として要素を入れ替えた表) :- 転置(_表,_対角線を軸として要素を入れ替えた表), 行列を表示する(_対角線を軸として要素を入れ替えた表). '対角線を軸として要素を入れ替えた表を表示する'(_表,_対角線を軸として要素を入れ替えた表) :- 表を180度回転する(_表,_表_2), 転置(_表_2,_対角線を軸として要素を入れ替えた表), 行列を表示する(_対角線を軸として要素を入れ替えた表). '表を180度回転する'(_表,_表_2) :- reverse(_表,_表_1), findall(L2,( append(_,[L1|_],_表_1), reverse(L1,L2)), _表_2). 行列を表示する(_行列) :- append(_,[_行|R],_行列), concat_atom(_行,' | ',_行表示), writef('%t\n',[_行表示]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/328 # # 【質問テンプレ】 # [1] 授業単元:多次元配列 # [2] 問題文(含コード&リンク): 要素が整数からなる3x3の表データを scanf()関数を用いて読み込み、対角線を軸と して要素を入れ替えた表を表示するプログラ ムを作りなさい。 '要素が整数からなる3x3の表データを scanf()関数を用いて読み込み、対角線を軸として要素を入れ替えた表を表示する'(_対角線を軸として要素を入れ替えた表) :- '要素が整数からなる3x3の表データを scanf()関数を用いて読み込み'(_表), '対角線を軸として要素を入れ替えた表を表示する'(_表,_対角線を軸として要素を入れ替えた表). '要素が整数からなる3x3の表データを scanf()関数を用いて読み込み'(_表) :- length(_表,3), findall(L,( append(_,[L|_],_表), write('3列をカンマ区切りで入力して下さい : '), readln(L)), _表). '対角線を軸として要素を入れ替えた表を表示する'(_表,_対角線を軸として要素を入れ替えた表) :- 転置(_表,_対角線を軸として要素を入れ替えた表), 行列を表示する(_対角線を軸として要素を入れ替えた表). '対角線を軸として要素を入れ替えた表を表示する'(_表,_対角線を軸として要素を入れ替えた表) :- 表を180度回転する(_表,_表_2), 転置(_表_2,_対角線を軸として要素を入れ替えた表), 行列を表示する(_対角線を軸として要素を入れ替えた表). '表を180度回転する'(_表,_表_2) :- reverse(_表,_表_1), findall(L2,( append(_,[L1|_],_表_1), reverse(L1,L2)), _表_2). 行列を表示する(_行列) :- append(_,[_行|R],_行列), concat_atom(_行,' | ',_行表示), writef('%t\n',[_行表示]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/307 # # 【質問テンプレ】 # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク):http://ime.nu/iup.2ch-library.com/i/i0478374-1321368771.jpg # # 1. (データの新規追加) 引数を順に名前、電話番号、学籍番号を表す配列 name phone number を用いて実装せよ # 2. (データ項目の削除) 引数で指定されたデータ項目と合致する個人データを住所録から削除する関数 # 3. (データの検索) 引数で指定されたデータ項目を住所録から検索する関数 # 4. 住所録に登録されているすべての個人データを表示するものとする。未使用 # 領域も表示すること。 # '住所録に登録されているすべての個人データを表示するものとする。未使用領域も表示する' :- 住所録(名前,_名前ならび), 住所録(住所,_住所ならび), 住所録(電話番号,_電話番号ならび), 住所録(名前,_学籍番号ならび), 全ての個人データを表示する(_名前ならび,_住所ならび,_電話番号ならび,_学籍番号ならび). 全ての個人データを表示する(_名前ならび,_住所ならび,_電話番号ならび,_学籍番号ならび) :- 転置([_名前ならび,_住所ならび,_電話番号ならび,_学籍番号ならび],_転置された個人データならび), append(_,[[_名前,_住所,_電話番号,_学籍番号]|R],_転置された個人データならび), writef('名前 : %t\n住所 : %t\n電話番号 : %t\n学籍番号 : %t\n\n',[_名前,_住所,_電話番号,_学籍番号]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/140 # # [1] 授業単元: Cプロ # [2] 問題文(含コード&リンク): # 3行3列の行列aを入力後、余因子行列で行列値|a|を求める # '3行3列の行列aを入力後、余因子行列で行列値|a|を求める' :- '3行3列の行列aを入力'(_a), '余因子行列で行列値|a|を求める'(_a,_行列式_aの値), writef('行列値|a|は%tです。\n',[_行列値_aの値]). '3行3列の行列aを入力'(_a) :- length(_a,3), findall(L,( nth1(_nth1,_a,L), length(L,3), '3列入力する'(_nth1,1,L)), _a). '3列入力する'(_,_,[]). '3列入力する'(_行位置,_列位置,[V|R]) :- writef('列入力[%t][%t] : ',[_行位置,_列位置]), get_line(Line), atom_to_term(Line,V,_), _列位置_2 is _列位置 + 1, '3列入力する'(_行位置,_列位置_2,R). '余因子行列を使って逆行列を得る'(_n,_正方行列,_逆行列) :- '余因子行列で行列値|a|を求める'(_正方行列,_行列式の値), 余因子行列(_n,_正方行列,_余因子行列), 転置(_余因子行列,_転置された余因子行列), 行列のすべての要素に値を掛ける(1,_n,_転置された余因子行列,1 / _行列式の値,_逆行列). 行列のすべての要素に値を掛ける(_行目,_n,LL,_,LL) :- _行目 > _n,!. 行列のすべての要素に値を掛ける(_行目,_n,LL1,_乗数 / _除数,LL2) :- '行基本変形'(_乗数 / _除数 # _行目,LL1,LL3), _行目_2 is _行目 + 1, 行列のすべての要素に値を掛ける(_行目_2,_n,LL3,_乗数 / _除数,LL2). '余因子行列で行列値|a|を求める'(_a,_行列式_aの値) :- 余因子行列(_n,_a,_余因子行列), _a = [_aの第一行|_], _余因子行列 = [_余因子行列の第一行|_], '二つのならびの積の和'(_aの第一行,_余因子行列の第一行,_行列式_aの値). '二つのならびの積の和'([],[],0). '二つのならびの積の和'([A|R1],[B|R2],S) :- '二つのならびの積の和'(R1,R2,S_1), S is S_1 + A * B. 余因子行列(_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)), _右上がり対角要素ならび),!. 左下がり対角要素ならび(_n,_正方行列,_左下がり対角要素ならび) :- findall(V,( nth1(_nth1,_正方行列,L), length([_|R],_nth1), append(_,[V|R],L)), _左下がり対角要素ならび),!. 左上がり対角要素ならび(_n,_正方行列,_左下がり対角要素ならび) :- findall(V,( append(_,[L|R1],_正方行列), length([_|R1],_nth1), length([_|R2],_nth1), append(_,[V|R2],L)), _左上がり対角要素ならび),!. '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. 行列式の値(_正方行列,_i,_n,_行列式の値) :- findsum(W,( 'n次正方行列の要素を列・行順序で取り出す'(_n,_正方行列,_i,_j,_正方行列の要素), 余因子(_n,_正方行列,_i,_j,_余因子), W is _正方行列の要素 * _余因子), _行列式の値). 'n次正方行列の要素を行・列順序で取り出す'(_n,_正方行列,_i行,_j列,_正方行列の要素) :- between(1,_n,_i行), nth1(_i行,_正方行列,L), nth1(_j列,L,_正方行列の要素). 'n次正方行列の要素を列・行順序で取り出す'(_n,_正方行列,_i行,_j列,_正方行列の要素) :- between(1,_n,_j列), nth1(_i行,_正方行列,L), nth1(_j列,L,_正方行列の要素). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/978 # # [1] 授業単元:基礎C # [2] 問題文(含コード&リンク):ガウスの消去法を使って、 # n元連立一次方程式をとくプログラミングを作成しろ # 'ガウスの消去法を使って、n元連立一次方程式をとく'(_拡大係数行列,_解ならび) :- 既約ガウス行列に変形(_拡大係数行列,_既約ガウス行列), 転置(_既約ガウス行列,_転置された既約ガウス行列), append(_,[_解ならび],_転置された既約ガウス行列). % 以下のサイトは # # 行列の掛算 # 行列の掛算(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). % 以下のサイトは # # 再帰述語を使わずに行列の転置を定義する。 # 転置(_行列,_転置された行列) :- 列形式を得る(_行列,_列形式), findall(_列ならび,( append(L0,[_列の値|_],_列形式), 列ならびを得る(_行列,L0,_列の値,_列ならび)), _転置された行列). 列形式を得る(_行列,_列形式) :- 列数を得る(_行列,_列数), length(_列形式,_列数). 列数を得る(_行列,_列数) :- _行列 = [_列_1|_], length(_列_1,_列数). 列ならびを得る(_行列,L0,_列の値,_列ならび) :- findall(_列の値,( append(_,[L|_],_行列), 列の値(L,L0,_列の値)), _列ならび). 列の値(L,L0,A) :- append(L0,[A|_],L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/881 # # 【2】 # # # 2次元配列の問題です # m行n列の配列aの # 各行ごとの合計 gyouwa[i] i=0,1,・・・,m # 各列ごとの合計 retuwa[j] j=0,1,・・・,n # を計算するプログラムの作成をお願いします # # •行列サイズ m,n は実行時に 100以内であれば自由に設定してデータを再入力させる機能をつける # ◦配列サイズの上限はプログラム中で配列を宣言するとき「100 個」として下さい。これは,プログラム中で大き目の配列を宣言しておいて,指定されたサイズに応じて必要分を使うための練習です。 # # 【3】c言語 # 【4】10月30日まで # # 'm行n列の配列aの各行ごとの合計 gyouwa[i] i=0,1,・・・,m各列ごとの合計 retuwa[j] j=0,1,・・・,nを計算する'(LL,_行の和ならび,_列の和ならび) :- 行の和ならびを求める(LL,_行の和ならび), 列の和ならびを求める(LL,_列の和ならび). 行の和ならびを求める(LL,_行の和ならび) :- findall(_行の和,( append(_,[L|_],LL), sum(L,_行の和)), _行の和ならび). 列の和ならびを求める(LL,_列の和ならび) :- 転置(LL,LL2), 行の和ならびを求める(LL2,_列の和ならび). '指定したサイズの行列にキーボードから入力して、各行ごとの合計と各列ごとの合計を求める'(_行列,_行の和ならび,_列の和ならび) :- '指定したサイズの行列にキーボードから入力して'(_行列), 行の和ならびを求める(_行列,_行の和ならび), 列の和ならびを求める(_行列,_列の和ならび). '指定したサイズの行列にキーボードから入力して'(_行列) :- 指定したサイズの(_行数,_列数), 行列にキーボードから入力して(_行数,_列数,_行列). '指定したサイズの行列に乱数を使って値を埋め、各行ごとの合計と各列ごとの合計を求める'(_行列,_行の和ならび,_列の和ならび) :- '指定したサイズの行列に乱数を使って値を埋め'(_行列), 行の和ならびを求める(_行列,_行の和ならび), 列の和ならびを求める(_行列,_列の和ならび). '指定したサイズの行列に乱数を使って値を埋め'(_行列) :- 指定したサイズの(_行数,_列数), 行列に乱数を使って値を埋め(_行数,_列数,_行列). 指定したサイズの(_行数,_列数) :- 行数の入力(_行数), 列数の入力(_列数). 行数の入力(_行数) :- write('行数を入力してください : '), get_line(Line), 行数の入力診断(Line,_行数),!. 行数の入力(_行数) :- 行数の入力(_行数). 行数の入力診断(Line,_行数) :- atom_to_term(Line,_行数,_), integer(_行数), _行数 >= 1, _行数 =< 100,!. 行数の入力診断(Line,_行数) :- write('入力された%tからは適切な行数が得られません。再入力をお願いします。\n',[Line]), fail. 列数の入力(_列数) :- write('列数を入力してください : '), get_line(Line), 列数の入力診断(Line,_列数),!. 列数の入力(_列数) :- 列数の入力(_列数). 列数の入力診断(Line,_列数) :- atom_to_term(Line,_列数,_), integer(_列数), _列数 >= 1, _列数 =< 100,!. 列数の入力診断(Line,_列数) :- write('入力された%tからは適切な列が得られません。再入力をお願いします。\n',[Line]), fail. 行列にキーボードから入力して(_行数,_列数,_行列) :- length(_行列,_行数), findall(_行,( append(L01,[_行|_],_行列), 行の値をキーボードから入力する(_行,L01,_列数)), _行列). 行の値をキーボードから入力する(_行,L01,_列数) :- length(_行,_列数), findall(_列の値,( append(L02,[_|_],_行), 行列要素の値の入力(L01,L02,_列の値)), _行). 行列要素の値の入力(L01,L02,_列の値) :- 行列要素の位置を求める(L01,L02,M行,N列), writef('%t行%t列の値 : ',[M行,N列]), get_integer(_列の値). 行列要素の位置を求める(L01,L02,M行,N列) :- length([_|L01],M行), length([_|L02],N列). 行列に乱数を使って値を埋め(_行数,_列数,_行列) :- length(_行列,_行数), findall(_行,( append(_,[_行|_],_行列), 行を乱数値で埋める(_行,_列数)), _行列). 行を乱数値で埋める(_行,_列数) :- length(_行,_列数), findall(_列の値,( append(_,[_|_],_行), '-100~100の範囲の値を入力'(_列の値)), _行). '-100~100の範囲の値を入力'(_列の値) :- _列の値 is (random(200)+1) - 100). % % 行列の転置述語は 転置/2 は http://nojiriko.asia/prolog/gyoretsu_no_tenchi.html % % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/681 # # [1] 授業単元:C言語プログラミング # [2] 問題文(含コード&リンク): # N×Nの行列を入力させ、その転置行列を出力するプログラムを作成せよ. # ただしNはプログラム内で記号定数として定義し,ここでは3とすること.転置行列とは、行と列を入れ替えた行列である. # 実行した時↓ # $ ./kadai # 3 x 3 matrix: # Row 1? 1 4 5 # Row 2? 10 8 9 # Row 3? 7 2 11 # Transposed matrix: # 1 10 7 # 4 8 2 # 5 9 11 # # 'N×N'(3). 'N×Nの行列を入力させ、その転置行列を出力するプログラムを作成せよ.ただしNはプログラム内で記号定数として定義し,ここでは3とすること.転置行列とは、行と列を入れ替えた行列である. ' :- 'N×Nの行列を入力させ'(_行列), 'N×Nの行列の転置行列を'(_行列,_転置行列), 出力する(_転置行列). 'N×Nの行列を入力させ'(_行列) :- 'N×N'(_N) length(_行列,_N), findall(L,( append(_,[L|_],_行列), length(L,_N), 入力する(L)), _行列). 入力する(_N,L) :- writef('%t要素の値をカンマ区切りで入力してください : ',[_N]), readln(L),!. 入力する(_N,L) :- writef('適切な%t項目の値が得られませんでした。再入力をお願いします。\n',[_N]), 入力する(_N,L). 'N×Nの行列の転置行列を'(_行列,_転置行列) :- 'N×N'(_N), 'N×Nの行列の転置行列を'(1,_N,_行列,_転置行列). 'N×Nの行列の転置行列を'(M,_N,_,[]) :- M > _N,!. 'N×Nの行列の転置行列を'(M,_N,_行列,[L|R]) :- findall(E,( append(_,[L|_],_行列), nth1(M,L,E)), L), M2 is M + 1, 'N×Nの行列の転置行列を'(M,_N,_行列,R). 出力する(_転置行列) :- append(_,[L|R1],_転置行列), append(_,[E|R2],L), writef('%5r,',[E]), R2 = [E2], writef('%5r\n',[E2]), R1 = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/563 # # http://ime.nu/codepad.org/bsGYVXWW # # 4名の学生別に3科目の成績を入力してその学生別平均と科目別平均を表示する。 # '4名の学生別に3科目の成績を入力してその学生別平均と科目別平均を表示する' :- '4名の学生別に3科目の成績を入力して'(LL), 'その学生別平均と'(LL,_学生別平均ならび), '科目別平均を'(LL,_科目別平均ならび), '表示する'(_学生別平均ならび,_科目別平均ならび). '4名の学生別に3科目の成績を入力して'(LL) :- '4名の'(LL,4), findall(L,( 学生別に(LL,L), '3科目の成績を入力する'(L)), LL). '4名の'(LL) :- length(LL,4). 学生別に(LL,L) :- append(_,[L|_],LL). '3科目の成績を入力する'(L) :- '3科目の'(L), findall(_成績,( 成績を(L,_成績), 入力する(_成績)), L). '3科目の'(L) :- length(L,3). 成績を(L,_成績) :- append(_,[_成績|_],L). 入力する(_成績) :- get_line(Line), 成績入力検査(Line,_成績),!. 入力する(_成績) :- 入力する(_成績). 成績入力検査(Line,_成績) :- atom_to_term(Line,_成績,_), '成績は0点以上100点以下の整数とする'(_成績),!. 成績入力検査(Line,_成績) :- writef('入力された%tからは科目成績として適切な整数が得られませんでした。再入力をお願いします。\n',[Line]), fail. '成績は0点以上100点以下の整数とする'(_成績) :- integer(_成績), _成績 >= 0, _成績 =< 100. 'その学生別平均と'(LL,_学生別平均ならび) :- findall(_平均,( append(_,[L|_],LL), 相加平均(L,_平均)), _学生別平均ならび). '科目別平均を'(LL,_科目別平均ならび) :- 転置(LL,LL1), findall(_平均,( append(_,[L|_],LL1), 相加平均(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). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/563 # # http://ime.nu/codepad.org/bsGYVXWW # # 4名の学生別に3科目の成績を入力してその学生別平均と科目別平均を表示する。 # # '4名の学生別に3科目の成績を入力してその学生別平均と科目別平均を表示する' :- '4名の学生別に3科目の成績を入力して'(LL), 'その学生別平均と'(LL,_学生別平均ならび), '科目別平均を'(LL,_科目別平均ならび), '表示する'(_学生別平均ならび,_科目別平均ならび). '4名の学生別に3科目の成績を入力して'(LL) :- '4名の'(LL,4), findall(L,( 学生別に(LL,L), '3科目の成績を入力する'(L)), LL). '4名の'(LL) :- length(LL,4). 学生別に(LL,L) :- append(_,[L|_],LL). '3科目の成績を入力する'(L) :- '3科目の'(L), findall(_成績,( 成績を(L,_成績), 入力する(_成績)), L). '3科目の'(L) :- length(L,3). 成績を(L,_成績) :- append(_,[_成績|_],L). 入力する(_科目別成績) :- get_line(Line), 入力検査(Line,_科目別成績),!. 入力する(_科目別成績) :- 入力する(_科目別成績). 入力検査(Line,_科目別成績) :- atom_to_term(Line,_科目別成績,_), integer(_科目別成績), _科目別成績 >= 0, _科目別成績 =< 100,!. 入力検査(Line,_科目別成績) :- writef('入力された%tからは科目成績として適切な整数が得られませんでした。再入力をお願いします。\n',[Line]), fail. 'その学生別平均と'(LL,_学生別平均ならび) :- findall(_平均,( append(_,[L|_],LL), 相加平均(L,_平均)), _学生別平均ならび). '科目別平均を'(LL,_科目別平均ならび) :- 転置(LL,LL1), findall(_平均,( append(_,[L|_],LL1), 相加平均(L,_平均)), _科目別平均ならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/563 # # http://ime.nu/codepad.org/bsGYVXWW # # #include # #define student 4 # #define score 3 # int main(){ # int i, j; # int a[student][score]; # int num[3]; # for(i=0; i= 0, _成績 =< 100,!. 成績入力検査(Line,_成績) :- writef('入力された%tからは科目成績として適切な整数が得られませんでした。再入力をお願いします。\n',[Line]), fail. 'その学生別平均と'(LL,_学生別平均ならび) :- findall(_平均,( append(_,[L|_],LL), 相加平均(L,_平均)), _学生別平均ならび). '科目別平均を'(LL,_科目別平均ならび) :- 転置(LL,LL1), findall(_平均,( append(_,[L|_],LL1), 相加平均(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). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/563 # # http://ime.nu/codepad.org/bsGYVXWW # # #include # #define student 4 # #define score 3 # int main(){ # int i, j; # int a[student][score]; # int num[3]; # for(i=0; i < student; i++){ # for(j=0; j < score; j++){ # printf("学生%d 科目%d :", i+1, j+1); # scanf("%d", &a[j][i]); # } # } # # for(j=0; j < student; j++){ # num[j]=0; # for(i=0; i < score; i++){ # num[j]=num[j]+a[student][score]; # } # } # # for(j=0; j < student; j++){ # for(i=0; i < score; i++){ # printf("学生%d 科目%d:%5.1f\n", i+1, i+1, num[i]/score); # } # } # return 0; # } # # ここまでは出来たんだが、↓のように表示するにはどう加えればいいのですか? # 学生別平均 学生1:0.0 学生2:0.0 学生3:0.0 学生4:0.0 # 科目別平均 科目1:0.0 科目2:0.0 科目3:0.0 # '4名の学生別に3科目の成績を入力してその学生別平均と科目別平均を表示する' :- '4名の学生別に3科目の成績を入力して'(LL), 'その学生別平均と'(LL,_学生別平均ならび), '科目別平均を'(LL,_科目別平均ならび), '表示する'(_学生別平均ならび,_科目別平均ならび). '4名の学生別に3科目の成績を入力して'(LL) :- '4名の'(LL,4), findall(L,( 学生別に(LL,L), '3科目の成績を入力する'(L)), LL). '4名の'(LL) :- length(LL,4). 学生別に(LL,L) :- append(_,[L|_],LL). '3科目の成績を入力する'(L) :- '3科目の'(L), findall(_成績,( 成績を(L,_成績), 入力する(_成績)), L). '3科目の'(L) :- length(L,3). 成績を(L,_成績) :- append(_,[_成績|_],L). 入力する(_科目別成績) :- get_line(Line), 入力検査(Line,_科目別成績),!. 入力する(_科目別成績) :- 入力する(_科目別成績). 入力検査(Line,_科目別成績) :- atom_to_term(Line,_科目別成績,_), integer(_科目別成績), _科目別成績 >= 0, _科目別成績 =< 100,!. 入力検査(Line,_科目別成績) :- writef('入力された%tからは科目成績として適切な整数が得られませんでした。再入力をお願いします。\n',[Line]), fail. 'その学生別平均と'(LL,_学生別平均ならび) :- findall(_平均,( append(_,[L|_],LL), 相加平均(L,_平均)), _学生別平均ならび). '科目別平均を'(LL,_科目別平均ならび) :- 転置(LL,LL1), findall(_平均,( append(_,[L|_],LL1), 相加平均(L,_平均)), _科目別平均ならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1312201995/462 # # [1] C言語演習 # [2] http://ime.nu/codepad.org/eBlxfu2Q のプログラムを以下のように # 改良しなさい。 # 1) 数字を入力して計算できるようにする。(ただし、2次元配列は必ず使用) # 2) 1〜5の合計点及び平均点の最高点、最低点を表の下部分に表示させる。 # 1)は必須、2)はできれば #  [3.1] Windows7 #  [3.3] C言語 # [4] 今日の19時まで # [5] 特になし # わかる方どうかよろしくお願いします。 # # # #include # # #define NUMBER 5 # # int max_of(const int vc[5][3], int no, int x) # { # int i; # int max = vc[0][x]; # for (i = 1; i < no; i++) # if (vc[i][x] > max) # max = vc[i][x]; # return (max); # } # # int min_of(const int vc[5][3],int no, int x) # { # int j; # int min = vc[0][x]; # # for (j = 1; j < no; j++){ # if (vc[j][x] < min) # min = vc[j][x]; # } # # return(min); # } # # double ave_of(int vc[5][3],int no, int x) # { # int k; # double a; # double sum = vc[0][x]; # # for(k = 1; k < no; k++){ # sum += vc[k][x]; # } # a = sum / NUMBER; # # return(a); # } # # int main(void) # { # int i, j, tensu = 0; # int max_j, max_e, max_m; # int min_j, min_e, min_m; # double ave_j, ave_e, ave_m; # double ave = 0; # # int ten[5][3] = {{10,20,30}, # {40,50,60}, # {70,80,90}, # {80,70,60}, # {50,40,30}}; # # max_j = max_of(ten, NUMBER, 0); # max_e = max_of(ten, NUMBER, 1); # max_m = max_of(ten, NUMBER, 2); # min_j = min_of(ten, NUMBER, 0); # min_e = min_of(ten, NUMBER, 1); # min_m = min_of(ten, NUMBER, 2); # ave_j = ave_of(ten, NUMBER, 0); # ave_e = ave_of(ten, NUMBER, 1); # ave_m = ave_of(ten, NUMBER, 2); # # printf("国語の最高点=%d\n", max_j); # printf("英語の最高点=%d\n", max_e); # printf("数学の最高点=%d\n", max_m); # printf("国語の最低点=%d\n", min_j); # printf("英語の最低点=%d\n", min_e); # printf("数学の最低点=%d\n", min_m); # printf("国語の平均点=%.1f\n", ave_j); # printf("英語の平均点=%.1f\n", ave_e); # printf("数学の平均点=%.1f\n", ave_m); # putchar('\n'); # # puts("番号:国 英 数 合計 平均"); # for (i = 0; i < NUMBER; i++) { # tensu = 0; ave = 0; # printf("[%2d]:", i+1); # for (j = 0; j < 3; j++) { # tensu += ten[i][j]; # ave = tensu / 3; # printf("%2d ", ten[i][j]); # } # printf(" %3d %.1f\n", tensu, ave); # } # return (0); # } # # # # Output: # # 国語の最高点=80 # 英語の最高点=80 # 数学の最高点=90 # 国語の最低点=10 # 英語の最低点=20 # 数学の最低点=30 # 国語の平均点=50.0 # 英語の平均点=52.0 # 数学の平均点=54.0 # # 番号:国 英 数 合計 平均 # [ 1]:10 20 30 60 20.0 # [ 2]:40 50 60 150 50.0 # [ 3]:70 80 90 240 80.0 # [ 4]:80 70 60 210 70.0 # [ 5]:50 40 30 120 40.0 # '5人の国語、英語、数学の得点を入力し、一覧表を作成する。個人の合計点、平均点、行末に付加する。科目ごとの合計点、平均点、5人の合計の合計点、平均点を最終行として付加する。さらに各科目の最高点には☆、最低点には★を表示する。' :- '5人の国語、英語、数学の得点を入力し'(_五人の成績ならび), 一覧表の作成(_五人の成績ならび). 一覧表の作成(_五人の成績ならび) :- 転置(_五人の成績ならび,_転置された五人の成績ならび), 国語・英語・数学の最高点(_転置された五人の成績ならび,_国語最高点,_英語最高点,_数学最高点), 国語・英語・数学の最低点(_転置された五人の成績ならび,_国語最低点,_英語最低点,_数学最低点), 国語・英語・数学の平均点(_転置された五人の成績ならび,_国語平均点,_英語平均点,_数学平均点), '個人別合計点・平均点'(_五人の成績ならび,_個人別合計点ならび,_個人別平均点ならび), 総平均点(_個人別合計点ならび,_総平均点), 見出し行, 五人の成績行表示(1,_五人の成績ならび,_個人別合計点ならび,_個人別平均点ならび), 最高点表示(_国語最高点,_英語最高点,_数学最高点), 最低点表示(_国語最低点,_英語最低点,_数学最低点), 平均点表示(_国語平均点,_英語平均点,_数学平均点,_総平均点),!. 五人の成績行表示(_,[],[],[]). 五人の成績行表示(N,[[_国語,_英語,_数学]|R1],[_合計点|R2],[_平均点|R3]) :- writef('[%t] %10r %10r %10r %10r %10r\n',[_国語,_英語,_数学,_合計点,_平均点]), N2 is N + 1, 五人の成績行表示(N2,R1,R2,R3). 最高点表示(_国語最高点,_英語最高点,_数学最高点) :- writef('最高点 %10r %10r %10r\n',[_国語最高点,_英語最高点,_数学最高点]). 最低点表示(_国語最低点,_英語最低点,_数学最低点) :- writef('最低点 %10r %10r %10r\n',[_国語最低点,_英語最低点,_数学最低点]). 平均点表示(_国語平均点,_英語平均点,_数学平均点,_総平均点) :- writef('平均点 %10r %10r %10r %10r %10r\n',[_国語平均点,_英語平均点,_数学平均点,' ',_総平均点]). 総平均点(_個人別合計点ならび,_総平均点) :- 相加平均(_個人別合計点ならび,_総平均点の一), _総平均点 is truncate(_総平均点の一 * 10) / 10. 国語・英語・数学の最高点([_国語点数ならび,_英語点数ならび,_数学点数ならび],_国語最高点,_英語最高点,_数学最高点) :- findall(_科目最高点,( append(_,[_科目点数ならび|_],LL), 最大値(_科目点数ならび,_科目最高点)), [_国語最高点,_英語最高点,_数学最高点]). 国語・英語・数学の最低点([_国語点数ならび,_英語点数ならび,_数学点数ならび],_国語最低点,_英語最低点,_数学最低点) :- findall(_科目最低点,( append(_,[_科目点数ならび|_],LL), 最小値(_科目点数ならび,_科目最低点)), [_国語最低点,_英語最低点,_数学最低点]). 国語・英語・数学の平均点([_国語点数ならび,_英語点数ならび,_数学点数ならび],_国語平均点,_英語平均点,_数学平均点) :- findall(_科目平均点,( append(_,[_科目点数ならび|_],LL), 相加平均(_科目点数ならび,_平均点の一), _科目平均点 is truncate(_平均点の一 * 10) / 10), [_国語平均点,_英語平均点,_数学平均点]). 見出し行 :- write('番号: 国 英 数 合計 平均\n'),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1311089619/943 # # これらが5個の課題です。 # お願いします。 # # (5) 3×3行列に整数のデータを入力し,その縦・横・斜めに足した合計がすべて等しくなるかを確認するプログラムを作成せよ.プログラムは以下を満たすものとする. # 整数のデータの入力では,for文を用いること. # 予め3×3個の整数の要素を持つ二次元配列を準備する. # 縦は3本,横は3本,斜め2本のそれぞれの合計が等しいかを確認する必要がある. # '予め3×3個の整数の要素を持つ二次元配列を準備する'(_二次元配列) :- length(_二次元配列,3), findall(L,( append(L0,[L|_],_二次元配列), length(L,3), findall(_要素,( append(L01,[_要素|_],L), length([_|L0],_何行目), length([_|L01],_何列目), writef('[%t][%t] : ',[_何行目,_何列目]), get_integer(_要素)), L)), _二次元配列), assertz(予め用意した二次元配列(_二次元配列)),!. '3×3行列に整数のデータを入力し,その縦・横・斜めに足した合計がすべて等しくなるかを確認する' :- 予め用意した二次元配列(_二次元配列), 行合計が一致する(_二次元配列,_一致した合計), 転置(_二次元配列,_転置された二次元配列), 行合計が一致する(_転置された二次元配列,_一致した合計), 斜め要素の合計(_二次元配列,_一致した合計). 行合計が一致する(_二次元配列,_一致した合計) :- findsum(_合計,( append(_,[_行|_],_二次元配列), sum(_行,_合計)), L), all(L,_一致した合計). 斜め要素の合計(_二次元配列,_一致した合計) :- findsum(_斜め要素,( for(1,N,3), nth1(N,_二次元配列,_行), nth1(N,_行,_斜め要素)), _一致した合計), findsum(_斜め要素,( for(1,N,3), nth1(N,_二次元配列,_行), reverse(_行,_反転した行), nth1(N,_反転した行,_斜め要素)), _一致した合計),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1308749241/834 # # 【質問テンプレ】 # [1] 授業単元:プログラミング演習 # [2] 問題文:標準入力に現れた数字文字の出現回数を*を使って # 数字の下側に表示するプログラムを作成せよ。 # http://codepad.org/T7Ft26pn # 上記のソースコードを元にして作成していただきたいです。 # # '標準入力に現れた数字文字の出現回数を*を使って数字の下側に表示する' :- 'EOFになるまで標準入力から入力する'(_文字ならび), 現れた数字文字の出現回数(_文字ならび,[],_数字文字の出現回数ならび), '*を使って数字の下側に表示する'(_数字文字の出現回数ならび). 'EOFになるまで標準入力から入力する'(_文字ならび) :- get_chars(_文字ならび). 現れた数字文字の出現回数([],_数字文字の出現回数ならび,_数字文字の出現回数ならび). 現れた数字文字の出現回数([_文字|R],_数字文字の出現回数ならび,_数字文字の出現回数ならび) :- _文字 @>= '0', _文字 @=< '9', 数字文字の出現回数更新(_文字,_数字文字の出現回数ならび1,_数字文字の出現回数ならび2), 現れた数字文字の出現回数(R,[C_数字文字の出現回数ならび2,_数字文字の出現回数ならび). 現れた数字文字の出現回数(R,_数字文字の出現回数ならび1,_数字文字の出現回数ならび) :- \+((_文字 @>= '0',_文字 @=< '9')), 現れた数字文字の出現回数(R,_数字文字の出現回数ならび1,_数字文字の出現回数ならび). 数字文字の出現回数更新(_文字,[],[[_文字,1]]) :- _文字 @>= '0', _文字 @=< '9',!. 数字文字の出現回数更新(_文字,[[_文字,_出現回数1]|R1],[[_文字,_出現回数2]|R2]) :- _文字 @>= '0', _文字 @=< '9', _出現回数2 is _出現回数 + 1, 数字文字の出現回数更新(_文字,R1,R2),!. '*を使って数字の下側に表示する'(_) :- び2,_数字文字の出現回数ならび). 現れた数字文字の出現回数(R,_数字文字の出現回数ならび1,_数字文字の出現回数ならび) :- \+((_文字 @>= '0',_文字 @=< '9')), 現れた数字文字の出現回数(R,_数字文字の出現回数ならび1,_数字文字の出現回数ならび). 数字文字の出現回数更新(_文字,[],[[_文字,1]]) :- _文字 @>= '0', _文字 @=< '9',!. 数字文字の出現回数更新(_文字,[[_文字,_出現回数1]|R1],[[_文字,_出現回数2]|R2]) :- _文字 @>= '0', _文字 @=< '9', _出現回数2 is _出現回数 + 1, 数字文字の出現回数更新(_文字,R1,R2),!. '*を使って数字の下側に表示する'(_数字文字の出現回数ならび) :- 転置(_数字文字の出現回数ならび,_転置された数字文字の出現回数ならび). _転置された数字文字の出現回数ならび = [_第一行数字文字ならび|R], concat_atom(_第一行数字文字ならび,_第一行文字列), writef('%t\n',[_第一行文字列]), max(R,Max), '*を使って数字の下側に表示する'(1,Max,R). '*を使って数字の下側に表示する'(N,Max,_) :- N > Max,!.). '*を使って数字の下側に表示する'(N,L) :- 一行星か空白の印字(N,L), write('\n'), N2 is N + 1, '*を使って数字の下側に表示する'(N2,L). 一行星か空白の印字(N,L) :- append(_,[M|R],L), 星か空白か(M,N,_印字文字), writef('%t',[_印字文字]), R = [],!. 星か空白か(M,N,*) :- M >= N,!. 星か空白か(M,N,' ') :- M < N,!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1308749241/456 # # [1] 授業単元:C言語 # [2] 問題文(含コード&リンク):http://codepad.org/dx3nSGGc # # //盤面データ構造体 # struct aa_t { # int cell[9][9]; # }; # # ・(r,c)に数字kは入らないとする関数 # マス(r,c)に9ビットの状態数が与えられています。 # たとえば110101110のとき、kが2なら、この関数によって110101100というようにします。 # このとき、元から0であり変更がなかったなら0を、1を0に変更したら1を返すようにします。 # int aa_del(struct aa_t *s, int r, int c, int k) { # if((s->cell[r][c] & (0001 << (k-1))) == 0000){return 0;} # else {s->cell[r][c] = (s->cell[r][c] & ( ~(0001 << (k-1)) ) );return 1;} # } # # ・横一列に同じ数字は入り得ないとする関数 # (r,c)には1~9のいずれかの数字が入ります。 # たとえば(r,c)のマスに3,6,9の数字が入る可能性がある事を100100100という状態数で表しています。 # もし(r,c)の状態数が000000100となると、(r,c)に3が入ることが確定します。 # このときc列に3が入る可能性を消す関数です。(もちろん(r,c)以外の) # そしてこの関数で実際に変更を受けたマスの数を戻り値として返すようにします。 '(r,c)に数字kは入らない'(_r,_c,_k,LL1,LL2,_b) :- findall(N,( bit_n(M,N), \+(M=_k)), L), sum(L,S), nth1(_r,LL1,L1), nth1(_c,L1,_b), _b2 is _B \/ S, '行列の置換'(_r,_c,_b2,LL1,LL2),!. '横一列に同じ数字は入り得ない'(_r,_c,_k,LL1,LL2) :- 'kを否定する為の数'(_k,S), 転置して列のビット処理(LL1,_r,_c,_k,S,LL2). 'kを否定する為の数'(_k,S) :- findall(N,( bit_n(M,N), \+(M=_k)), L), sum(L,S),!. 転置して列のビット処理(LL1,_r,_c,_k,S,LL2) :- 転置(LL1,LL3), 行とカラムを得る(LL3,_c,_r,L3,_b), 行全体のビットオフ(L3,S,L2), 指定カラムだけビットオン(L2,_k,_b,_b3,L4), 要素位置指定によるならびの置換(LL3,_c,L4,LL4), 転置(LL4,LL2),!. 行とカラムを得る(LL,_r,_c,L,_b) :- nth1(_r,LL,L), nth1(_c,L,_b),!. 行全体のビットオフ(L3,S,L2) :- findall(_b2,( member(I,L3), _b2 is I /\ S), L2),!. 指定カラムだけビットオン(L2,_k,_b,_b3,L4) :- bit_n(_k,J), _b3 is _b \/ J, 要素位置指定によるならびの置換(L2,_r,_b3,L4),!. bit_n(0,0). bit_n(1,1). bit_n(2,2). bit_n(3,4). bit_n(4,8). bit_n(5,16). bit_n(6,32). bit_n(7,64). bit_n(8,128). bit_n(9,256). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1308749241/444 # # 内容: # [1] 授業単元:C言語 [2] 問題文(含コード&リンク): # # 50から1まで5個づつ降順に並んだ合計付きの表を表示しながら作成する。 # # 50 49 48 47 46 240 # 45 44 43 42 41 215 # 40 39 38 37 36 190 # 35 34 33 32 31 165 # 30 29 28 27 26 140 # 25 24 23 22 21 115 # 20 19 18 17 16 90 # 15 14 13 12 11 65 # 10 9 8 7 6 40 # 5 4 3 2 1 15 # 275 265 255 245 235 1275 '50から1まで5個づつ降順に並んだ合計付きの表を表示しながら作成する'(_表) :- length(_五要素,5), length(L50,50), length(L5,5), findall(N,for(50,N,1),_50から1までのならび), findall(_行,( append(L0,_五要素,R,_50から1までのならび), ならび割り算(L0,L5,_,[]), sum(_五要素,_横計), append(_五要素,[_横計],_行), writef('%5r%5r%5r%5r%5r%5r\n',_行)), _縦計を除いた表), 転置(_縦計を除いた表,_転置された縦計を除いた表), findall(_縦計,( append(_,[L2|_],_転置された縦計を除いた表), sum(L2,_縦計)), _縦計ならび), wriref('%5r%5r%5r%5r%5r%5r\n',_縦計ならび), append(_縦計を除いた表,[_縦計ならび],_表),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1308749241/124 # # [1] 授業単元:プログラミング演習 1 # [2] 問題文(含コード&リンク) # 結果が以下のようになるC言語プログラムを作りなさい。 # 行列A,Bの各要素はscanf関数を使って標準入力から設定すること # # Matrix A # 5.0 4.0 3.0 # 4.0 3.0 2.0 # 3.0 2.0 1.0 # # Matrix B # 1.0 2.0 3.0 # 2.0 3.0 4.0 # 3.0 4.0 5.0 # # Matrix C = A - B # 4.0 2.0 0.0 # 2.0 0.0 -2.0 # 0.0 -2.0 -4.0 # # Matrix D = A * B # 22.0 34.0 46.0 # 16.0 25.0 34.0 # 10.0 16.0 22.0 # # [3.1] OS: unix # [3.2] コンパイラ名とバージョン: gcc # [3.3] 言語: C # [4] 期限:6月29日 # よろしくお願いします。 'MatrixA'([[5.0,4.0,3.0], 4.0,3.0,2.0], 3.0,2.0,1.0]]). 'MatrixB'([[1.0,2.0,3.0], [2.0,3.0,4.0], [3.0,4.0,5.0]]). 'Matrix C = A - B' :- 'MatrixA'(_行列A), 'MatrixB'(_行列B), 行列の差(_行列A,_行列B,_行列C), 行列表示(_行列C). 行列の差([],[],[]) :- ! . 行列の差([A|R1],[B|R2],[C|R3]) :- 行列の差の一(A,B,C), 行列の差(R1,R2,R3),!. 行列の差の一([],[],[]) :- !. 行列の差の一([A|R1],[B|R2],[C|R3]) :- C is A - B, 行列の差の一(R1,R2,R3),!. 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2), 行列の転置(R2,R1),!. 行列表示(_行列) :- append(_,[L|R],_行列), append(_,[A|R1],L), writef('%8r',[A]), R1 = [], write('\n'), R = [],!. % 以下のサイトは 座標の回転してから移動(_回転角度,_移動X軸距離,_移動Y軸距離,X,Y,_x,_y) :- 座標の回転(_回転角度,X,Y,_x2,_y2), _x is _x2 + _移動X軸距離, _y is _y2 + _移動Y軸距離. 座標を移動してから回転(_回転角度,_移動X軸距離,_移動Y軸距離,X,Y,_x,_y) :- X2 is X + _移動X軸距離, Y2 is Y + _移動Y軸距離, 座標の回転(_回転角度,X2,Y2,_x,_y). 座標の回転(_回転角度,X,Y,_x,_y) :- 変換正方行列(回転,_回転角度,L), m_mult([[Y,X]],L,[[_y,_x]]). 変換正方行列(回転,V,[[A,B],[C,D]]) :- \+(var(V)), R is pi * V / 180, A is cos(R), B is (-1) * sin(R), C is sin(R), D = A. 変換正方行列(回転,90,[[0,-1],[1,0]]). 変換正方行列(回転,180,[[-1,0],[0,-1]]). 変換正方行列(回転,270,[[0,1],[-1,0]]). 変換正方行列(回転,-90,[[0,1],[-1,0]]). 変換正方行列(回転,-180,[[-1,0],[0,-1]]). 変換正方行列(回転,-270,[[0,-1],[1,0]]). 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2), 行列の転置(R2,R1),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1307166756/232 # # [1] 授業単元:配列の並び替え # [2] 問題文(含コード&リンク): # ../test/read.cgi/tech/1307166756/189のシステムを以下のように拡張する。 # 指定済みの座標を入力した場合、「先手の負け」または「後手の負け」と表示する。 # 全てのマスが埋まったら、「試合終了」と表示する。 # この段階でも、勝ち負けの判定も行わない。 '先手、後手の順番で、x=1,2,3 y=1,2,3の座標の整数値をx yの順番で与えると、その場所に先手ならA、後手ならBを表示して、3目並べを実現する' :- length(LL,3), findall(L,(append(_,[L|_],LL),length(L,3)),LL), 3目並べを実現する(後手,LL,_診断). 3目並べを実現する(_,_,_診断) :- \+(var(_診断)),!. 3目並べを実現する(_,LL,正常終了) :- 打つところがない(LL), write('試合終了),!. 3目並べを実現する(_前の手番,LL,正常終了) :- 三目ならび完成(LL), writef('%tの勝ちです\n',[_前の手番]),!. 3目並べを実現する(_前の手番,LL,_診断) :- \+(三目ならび完成(LL)), 手番(_前の手番,_手番), 座標値を与える(_手番,LL,_診断), 3目並べを実現する(_手番,LL,_診断). 打つところがない([]). 打つところがない([L|R]) :- 全て変数(L), 打つところがない(R). すべて変数([]). すべて変数([V|R]) :- var(V), すべて変数(R). 三目ならび完成([[_,_,A],[_,A,_],[A,_,_]]) :- \+(var(A)),!. 三目ならび完成([[A,_,_],[_,A,_],[_,_,A]]) :- \+(var(A)),!. 三目ならび完成([[A,A,A]|_]) :- \+(var(A)),!. 三目ならび完成([_,[A,A,A]|_]) :- \+(var(A)),!. 三目ならび完成([_,_,[A,A,A]]) :- \+(var(A)),!. 三目ならび完成(L) :- 転置(L,L1), 三目ならび完成(L1). 手番(先手,後手). 手番(後手,先手). 着手記号(先手,'O'). 着手記号(後手,'@'). 座標値を与える(_手番,LL,_診断) :- 盤面表示(LL), writef('%t の手番です : \n',[_手番]), 座標値を得る(_x,_y), 座標値診断(_手番,_x,_y,LL),!. 座標値を得る(_x,_y) :- get_line(Line), split(Line,[' ',','],[_x,_y]),!. 座標値診断(_手番,_x,_y,LL,_診断) :- nth1(_y,LL,L), nth1(_x,L,V), var(V), 着手記号(_手番,_記号), V = _記号,!. 座標値診断(_手番,_,_,_,異常終了) :- write('%tの負けです。\n',[_手番]),!. 盤面表示(LL) :- write('---------\n'), append(_,[[A,B,C]|R],LL), 変数は空白に変換([A,B,C],[A2,B2,C2]), concat_atom([A2,B2,C2],'|',S), writef('|%t|\n',[S]), R = [], write('---------\n'),!. 変数は空白に変換([],[]). 変数は空白に変換([V|R1],[' '|R2]) :- var(V), 変数は空白に変換(R1,R2). 変数は空白に変換([V|R1],[V|R2]) :- \+(var(V)), 変数は空白に変換(R1,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1307166756/189 # # [1] 授業単元:配列の並び替え # [2] 問題文(含コード&リンク): # 先手、後手の順番で、x=1,2,3 y=1,2,3の座標の整数値をx yの順番で与えると、その場所に先手ならO、後手なら@を表示して、3目並べを実現するプログラムを作成しなさい。 # 操作は、先手・後手が交互に座標の数値を1ずつ与えるものとし、入力ミスは考えない。 # すでに指定済みの座標かどうかについては判定し、指定済みの座標を入力した場合は、「異常終了」と表示し、プログラムを終了することとする。 # この段階では、勝ち負けの判定も行わない。 # '先手、後手の順番で、x=1,2,3 y=1,2,3の座標の整数値をx yの順番で与えると、その場所に先手ならA、後手ならBを表示して、3目並べを実現する' :- length(LL,3), findall(L,(append(_,[L|_],LL),length(L,3)),LL), 3目並べを実現する(後手,LL,_診断), 診断値表示(_診断). 3目並べを実現する(_,_,_診断) :- \+(var(_診断)),!. 3目並べを実現する(_前の手番,LL,正常終了) :- 三目ならび完成(LL), writef('%tの勝ちです\n',[_前の手番]),!. 3目並べを実現する(_前の手番,LL,_診断) :- \+(三目ならび完成(LL)), 手番(_前の手番,_手番), 座標値を与える(_手番,LL,_診断), 3目並べを実現する(_手番,LL,_診断). 三目ならび完成([[_,_,A],[_,A,_],[A,_,_]]) :- \+(var(A)),!. 三目ならび完成([[A,_,_],[_,A,_],[_,_,A]]) :- \+(var(A)),!. 三目ならび完成([[A,A,A]|_]) :- \+(var(A)),!. 三目ならび完成([_,[A,A,A]|_]) :- \+(var(A)),!. 三目ならび完成([_,_,[A,A,A]]) :- \+(var(A)),!. 三目ならび完成(L) :- 転置(L,L1), 三目ならび完成(L1). 手番(先手,後手). 手番(後手,先手). 着手記号(先手,'O'). 着手記号(後手,'@'). 座標値を与える(_手番,LL,_診断) :- 盤面表示(LL), writef('%t の手番です : \n',[_手番]), 座標値を得る(_x,_y), 座標値診断(_手番,_x,_y,LL),!. 座標値を得る(_x,_y) :- get_line(Line), split(Line,[' ',','],[_x,_y]),!. 座標値診断(_手番,_x,_y,LL,_診断) :- nth1(_y,LL,L), nth1(_x,L,V), var(V), 着手記号(_手番,_記号), V = _記号,!. 座標値診断(_,_,_,_,異常終了). 診断値表示(異常終了) :- write('異常終了\n'),!. 診断値表示(_). 盤面表示(LL) :- write('---------\n'), append(_,[[A,B,C]|R],LL), 変数は空白に変換([A,B,C],[A2,B2,C2]), concat_atom([A2,B2,C2],'|',S), writef('|%t|\n',[S]), R = [], write('---------\n'),!. 変数は空白に変換([],[]). 変数は空白に変換([V|R1],[' '|R2]) :- var(V), 変数は空白に変換(R1,R2). 変数は空白に変換([V|R1],[V|R2]) :- \+(var(V)), 変数は空白に変換(R1,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1305867431/289 # # [1] 授業単元: プログラム # [2] 問題文(含コード&リンク): #  M*R次元の行列(mat1)とR*N次元の行列(mat2)の乗算を行いM*N次元の行列(mat3)を #  得る関数(matMul)を作成せよ。ただし、関数のプロトタイプにおいて行列を表す引数部分には、 #  2つの行列のサイズを表す引数と、行列データそのものを表す引数(2次元配列)を含めること。 # 行列の乗算(M*R,LL1,R*N,LL2,M*N,X) :- length(LL1,R), LL1 = [L1|_], length(L1,M), length(LL2,N), LL2 = [L2|_], length(L2,R), length(X,N), findall(L,( append(_,[L|_],X), length(L,M)), X), 行列の乗算(LL1,LL2,X). 行列の乗算(LL1,LL2,X) :- 行列の転置(LL2,LL4), 行列の乗算(LL1,LL4,X). 行列の乗算_1([],_,[]) :- !. 行列の乗算_1([L|R1],LL,[S1|R3]) :- 行列の乗算_2(L,LL,S1), 行列の乗算_1(R1,LL,R3). 行列の乗算_2(_,[],[]) :- !. 行列の乗算_2(L1,[L2|R2],[L3|R3]) :- 行列の乗算_3(L1,L2,L3), 行列の乗算_2(L1,R2,R3). 行列の乗算_3([],[],0) :- !. 行列の乗算_3([N1|R1],[N2|R2],M) :- M1 is N1 * N2, 行列の乗算_3(R1,R2,M2), M is M1 + M2. 行列の転置([[]|_],[]) :- !. 行列の転置(LL,[L|R1]) :- 行列の転置(LL,L,R2), 行列の転置(R2,R1),!. 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1301553333/908 # # # # [1] 授業単元:計算機プログラミング # [2] 問題文:http://nojiriko.asia/prolog/org1648258.pdf #         リンク先の問題2 # # 2.下記のような,学生 10 名の 5 科目の成績表がある(表の仕様,値などは各自決めてよい)。 # 成績表 # StudentNo. Electromag. Elec.Cct Computer Math English # E001 70 65 85 90 70 # E002 50 45 55 65 60 # E003 78 90 95 70 85 # E004 90 98 87 85 75 # E005 45 75 62 48 50 # # 個人毎,および科目毎の平均を計算するプログラムを組みなさい。 # ただし,プログラムの設計仕様に次の 2 点を必ず含めること。 # # (1) キーボードなどから点数を入力し,結果をファイルに出力すること(kekka.txt など)。 # ファイル(data.txt など)を読込ませてもよい。ただし,値をプログラムに組み込まないこと! # (2) 平均を求める箇所を関数にすること。 '個人毎,および科目毎の平均を計算する。キーボードなどから点数を入力し(ファイル(data.txt など)を読込ませてもよい),結果をファイルに出力する'(_入力ファイル,_出力ファイル) :- 'キーボードなどから点数を入力し(ファイル(data.txt など)を読込ませてもよい)'(_入力ファイル,_見出し項,_生成表), '個人毎,および科目毎の平均を計算する'(_成績表,_個人毎平均,_個人毎平均を付加した成績表,_科目毎平均), ファイルに出力する(_見出し項,_個人毎平均,_科目毎平均). 'キーボードなどから点数を入力し(ファイル(data.txt など)を読込ませてもよい)'(_入力ファイル,_見出し項,_生成表) :- get_split_lines(_入力ファイル,[' '],LL), LL = [_見出し項|_成績表]. '個人毎,および科目毎の平均を計算する'(_成績表,_個人毎平均,_個人毎平均を付加した成績表,_科目毎平均) :- 個人毎の平均を計算する(_成績表,_個人毎平均,_個人毎平均を付加した成績表), 科目毎の平均を計算する(_成績表,_科目毎平均). 個人毎の平均を計算する(_成績表,_個人毎平均を付加した成績表) :- findall(L,( append(_,[L1|_],_成績表), L1 = [_|_個人成績ならび], avg(_個人成績ならび,_個人毎平均), append(L1,[_個人毎平均],L)), _個人毎平均を付加した成績表). 科目毎の平均を計算する(_成績表,_科目毎平均) :- 転置(_成績表,_転置された成績表), findall(Avg,( append(_,[[_|L]|_],_転置された成績表), avg(L,Avg)), _科目毎平均). ファイルに出力する(_見出し項,_個人毎平均,_科目毎平均) :- open(_出力ファイル,write,Outstream), 見出し項を出力する(Outstream,_見出し項), 個人毎の平均を出力する(Outstream,_個人毎平均), 科目毎の平均を出力する(Outstream,_科目毎平均), close(Outstream). 見出し項を出力する(Outstream,_見出し項) :- append(_見出し項,['Average'],_見出し項のニ), write_formattet(Outstream,'%16t %16t %16t %16t %16t %16t %16t %16t \n',_見出し項のニ),!. 個人毎の平均を出力する(Outstream,_個人毎平均) :- append(_,[L|R],_個人毎平均), write_formatted(Outstream,'%16t %16t %16t %16t %16t %16t %16t %16t \n',L), R = []. 科目毎の平均を出力する(Outstream,_科目毎平均) :- write_formatted(Outstream,'avarage %16t %16t %16t %16t %16t %16t %16t \n',_科目毎平均). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1294061094/892 # # 【質問テンプレ】 # [1] 授業単元:C言語初級講座 # [2] 問題文(含コード&リンク): # http://ime.nu/www.dotup.org/uploda/www.dotup.org1384986.txt # # テキストファイル名"a.txt"から以下の表を作成せよ。 # xやxxxの所は計算結果を表示させ、 # テキストファイル名"b.txt"に計算結果を追加して # 保存せよ。 # # # 【テキストファイル内容】 # 商品名,アイスクリーム # 2010,2011 # 4,5,6,7,8,9,10,11,12,1,2,3 # 仕入数,3,3,13,22,30,15,11,5,5,3,5,5,仕入総数 # 販売個数,1,2,12,20,30,15,8,4,2,3,3,2,販売総数 # 在庫数,在庫総数 # # # 【表示結果】 # 商品名 アイスクリーム # 年度 2010年 2011年 # 月 4 5 6 7 8 9 10 11 12 1 2 3 # --------------------------------------------------------- # 仕入数 3 3 13 22 30 15 11 5 5 3 5 5 仕入総数 xxx # 販売個数 1 2 12 20 30 15 8 4 2 3 3 2 販売総数 xxx # --------------------------------------------------------- # 在庫数 x x x x x x x x x x x x 在庫総数 xxx 計算後の表イメージ(1,商品名,L,L,[]). 計算後の表イメージ(2,年度,_年度ならび,_年度ならび,[]). 計算後の表イメージ(3,月ならび,_月ならび,_月ならび,[]). 計算後の表イメージ(4,仕入数ならび,L,_仕入数ならび,R) :- append([仕入数],_仕入数ならび,[仕入総数|R],L). 計算後の表イメージ(5,販売個数ならび,L,_販売個数ならび,R) :- append([販売個数],_販売個数ならび,[販売総数|R],L). 計算後の表イメージ(6,在庫個数ならび,L,_在庫個数ならび,R) :- append([在庫個数],_在庫個数ならび,[在庫総数|R],L). 'テキストファイル名"a.txt"から以下の表を作成せよ。xやxxxの所は計算結果を表示させ、テキストファイル名"b.txt"に計算結果を追加して保存せよ。' :- get_split_lines('a.txt',[','],LL), 計算結果(LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数), 計算結果を表示する(LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数), 'テキストファイル名"b.txt"に計算結果を追加して保存する'(LL). 計算結果を表示する(LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数) :- 計算結果(LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数), 表示する(LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数),!. 計算結果(LL1,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数) :- 計算対象部分の抽出(LL1,LL2), 仕入総数・販売総数の計算(LL2,_仕入総数,_販売総数), 在庫個数の計算(LL2,_在庫個数ならび), 在庫総数(_在庫個数ならび,_在庫総数). 仕入総数・販売総数の計算([_仕入数ならび,_販売個数ならび],_仕入総数,_販売総数) :- 加算(_仕入数ならび,S1), _仕入総数 is trancate(S1), 加算(_販売個数ならび,S2), _販売総数 is trancate(S2),!. 在庫個数の計算(LL,_在庫個数ならび) :- 転置(LL,LL2), findall(_在庫個数,( append(_,[[_仕入個数,_販売個数]|_],LL2), _在庫個数 is _仕入個数 - _販売個数, _在庫個数 is truncate(S1)), _在庫個数ならび). 在庫総数(_在庫個数ならび,_在庫総数) :- 加算(_在庫個数ならび,S1), _在庫総数 is truncate(S1). 計算対象部分の抽出(LL1,[_仕入数ならび,_販売個数ならび]) :- append(_,[L1|_],LL1), 計算後の表イメージ(_,仕入数ならび,L1,_仕入数ならび), 計算後の表イメージ(_,販売個数ならび,L1,_販売個数ならび),!. 表示する(LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数) :- append(L0,[L|R],LL), length([_|L0],_行), 行ごとに表示(_行,L,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数), R = [],!. 行ごとに表示(1,L,_,_,_,_) :- write_formatted('%12s%12s\n',L),!. 行ごとに表示(2,L,_,_,_,_) :- write_formatted('%12s%30s%30s\n',L),!. 行ごとに表示(3,L,_,_,_,_) :- write_formatted('%10s%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%10s%3d\n',L), write('---------------------------------------------------------\n'),!. 行ごとに表示(4,L,_仕入総数,_,_,_) :- 計算後の表イメージ(4,_,LX,L,_仕入総数), write_formatted('%10s%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%10s%3d\n',LX),!. 行ごとに表示(5,L,_,_販売総数,_,_) :- 計算後の表イメージ(5,_,LX,L,_販売総数), write_formatted('%10s%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%10s%3d\n',LX), write('---------------------------------------------------------\n'),!. 行ごとに表示(6,L,_,_,_在庫個数ならび,_在庫総数) :- 計算後の表イメージ(5,_,LX,_在庫個数ならび,_在庫総数), write_formatted('%10s%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%10s%3d\n',LX),!. 'テキストファイル名"b.txt"に計算結果を追加して保存する'(LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数) :- open('b.txt',write,Outstream), 保存する(Outstream,LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数), close(Outstream),!. 保存する(Outstream,LL,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数) :- append(L0,[L|R],LL), length([_|L0],_行), 行ごとに保存する(Outstream,_行,L,_仕入個数,_販売総数,_在庫個数ならび,_在庫総数), R = [],!. 行ごとに保存(Outstream,4,L,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数) :- 計算後の表イメージ(4,_,LX,L,_仕入総数), concat_atom(LX,',',S), write_formatted(Outstream,'%t\n',[S]),!. 行ごとに保存(Outstream,5,L,_仕入総数,_販売総数,_在庫個数ならび,_在庫総数) :- 計算後の表イメージ(5,_,LX,L,_販売総数), concat_atom(LX,',',S), write_formatted(Outstream,'%t\n',[S]),!. 行ごとに保存(Outstream,6,L,_仕入個数,_販売総数,_在庫個数ならび,_在庫総数) :- 計算後の表イメージ(5,_,LX,_在庫個数ならび,_在庫総数), concat_atom(LX,',',S), write_formatted(Outstream,'%t\n',[S]),!. 行ごとに保存(Outstream,6,L,_仕入個数,_販売総数,_在庫個数ならび,_在庫総数) :- concat_atom(L,',',S), write_formatted(Outstream,'%t\n',[S]),!. 以下の表('商品名 アイスクリーム'). 以下の表('年度 2010年 2011年'). 以下の表(' 月 4 5 6 7 8 9 10 11 12 1 2 3'). 以下の表('---------------------------------------------------------'). 以下の表('仕入数 3 3 13 22 30 15 11 5 5 3 5 5 仕入総数 xxx'). 以下の表('販売個数 1 2 12 20 30 15 8 4 2 3 3 2 販売総数 xxx'). 以下の表('---------------------------------------------------------'). 以下の表('在庫数 x x x x x x x x x x x x 在庫総数 xxx'). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1294061094/239 # # [1] 授業単元:プログラミング演習 # [2] 問題文(含コード&リンク) # 縦は無数、横が10列で数字が書き込まれているecxelファイルを読み込む(ファイル名は何でもいいです) # 読み込む時は今後の処理を考えてなるべく配列で # その後各列を縦に参照していき、正の値が出たときは別の同じ型の配列の同じ位置に代入していく # 負の値が出たときに、そのセルの列の前5個、後ろ5個を参照し以下の処理を行う # 前にも後ろにも正の値が検出された場合 → 参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する # 前あるいは後ろの片方にしか正の値が検出されなかった場合 → 一番近い値をそのまま別の配列に格納する # 前にも後ろにも正の値が無い場合 → そのままの負の値で別の配列に格納する # # 最後に値の変更を終えた別の配列をそのままresult.csvとして出力する # # # 'ファイルからcsvファイルを読み取りルールにしたがってすべてのセルを書き換え、result.csvファイルに出力する'(_ファイル,LL) :- '縦は無数、横が10列で数字が書き込まれているecxelファイルを読み込む'(_ファイル,LL1), 転置(LL1,LL2), ルールにしたがってすべてのセルを書き換える(LL2,LL3), 転置(LL3,LL), 'result.csvファイルとして出力する'(LL). '縦は無数、横が10列で数字が書き込まれているecxelファイルを読み込む'(_ファイル,LL) :- get_split_lines(_ファイル,[' '],LL). ルールにしたがってすべてのセルを書き換える(L,[]) :- !. ルールにしたがってすべてのセルを書き換える([L1|R1],[L2|R2]) :- length(L1,Len), ルールにしたがってすべての行を書き換える(1,Len,L1,[_セル2|R2]) :- ルールにしたがってすべてのセルを書き換える(R1,R2). ルールにしたがってすべての行を書き換える(M,Len,[]) :- M > Len,!. ルールにしたがってすべての行を書き換える(M1,Len,L,[_セル1|R2]) :- list_nth(M1,L,_セル1), _セル1 >= 0, M2 is M1 + 1, ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!. ルールにしたがってすべての行を書き換える(M1,Len,L,[_参照しているセルに一番近い値|R2]) :- そのセルの列の前5個、後ろ5個を参照し(L,M1,Len,_前5個ならび,_そのセル,_後ろ5個ならび), 前あるいは後ろの片方にしか正の値が検出されなかった場合(L,_前5個ならび,_そのセル,_後ろ5個ならび), '参照しているセルに一番近い値をそのまま別の配列に格納する'(_そのセルの位置,_前5個ならび,_そのセル,_後ろ5個ならび,_参照しているセルに一番近い値), M2 is M1 + 1, ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!. ルールにしたがってすべての行を書き換える(M1,Len,L,[_2つの平均値|R2]) :- そのセルの列の前5個、後ろ5個を参照し(L,M1,Len,_前5個ならび,_そのセル,_後ろ5個ならび), 前にも後ろにも正の値が検出された場合(_前5個ならび,_そのセル,_後ろ5個ならび), '参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'(_前5個ならび,_そのセル,_後ろ5個ならび,_2つの平均値), M2 is M1 + 1, ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!. ルールにしたがってすべての行を書き換える(M1,Len,L,[_そのセル|R2]) :- そのセルの列の前5個、後ろ5個を参照し(L,M1,Len,_前5個ならび,_そのセル,_後ろ5個ならび), 前にも後ろにも正の値が無い場合(_前5個ならび,_そのセル,_後ろ5個ならび), M2 is M1 + 1, ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!. 前あるいは後ろの片方にしか正の値が検出されなかった場合(_前5個ならび,_そのセル,_後ろ5個ならび) :- _そのセル < 0, append(_,[N1|_],_前5個ならび), N1 > 0, \+((append(_,[N2|_],_後ろ5個ならび),N2 > 0)),!. 前あるいは後ろの片方にしか正の値が検出されなかった場合(_前5個ならび,_そのセル,_後ろ5個ならび) :- _そのセル < 0, \+((append(_,[N1|_],_前5個ならび),N1 > 0)), append(_,[N2|_],_後ろ5個ならび), N2 > 0,!. 前にも後ろにも正の値が検出された場合(_前5個ならび,_そのセル,_後ろ5個ならび) :- _そのセル < 0, append(_,[N1|_],_前5個ならび), N1 > 0, append(_,[N2|_],_後ろ5個ならび), N2 > 0,!. 前にも後ろにも正の値が無い場合(_前5個ならび,_そのセル,_後ろ5個ならび) :- \+((append(_,[N1|_],_前5個ならび),N1 > 0)), \+((append(_,[N2|_],_後ろ5個ならび),N2 > 0)),!. そのセルの列の前5個、後ろ5個を参照し(L,_そのセルの位置,Len,_前5個ならび,_そのセル,_後ろ5個ならび) :- Len < _そのセルの位置 + 5, _そのセルの位置 >= 6, len0 is _そのセルの位置 - 6, length(L0,Len0), length(_前5個ならび,5), append(_前5個ならび,[_そのセル|_後ろ5個ならび],L1), append(L0,L1,L),!. そのセルの列の前5個、後ろ5個を参照し(L,_そのセルの位置,Len,_前5個ならび,_そのセル,_後ろ5個ならび) :- _そのセルの位置 < 6, Len >= _そのセルの位置 + 5, _前5個ならびの長さ is _そのセルの位置 - 1, length(_前5個ならび,_前5個ならびの長さ), length(_後ろ5個ならび,5), append(_前5個ならび,[_そのセル|_後ろ5個ならび],L1), append(L1,L2,L),!. そのセルの列の前5個、後ろ5個を参照し(L,_そのセルの位置,Len,_前5個ならび,_そのセル,_後ろ5個ならび) :- _そのセルの位置 >= 6, Len >= _そのセルの位置 + 5, Len0 is _そのセルの位置 - 6, length(L0,Len0), length(_前5個ならび,5), append(_前5個ならび,[_そのセル|_後ろ5個ならび],L1), append(L0,L1,_,L),!. '参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'([],_そのセル,_後ろ5個ならび,_値) :- findmin([M,N],( append(_,[N|_],_後5個ならび), M is abs(N - _そのセル)), [_差,_値]),!. '参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'(_前5個ならび,_そのセル,[],_値) :- findmin([M,N],( append(_,[N|_],_前5個ならび), M is abs(N - _そのセル)), [_差,_値]), '参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'(_前5個ならび,_そのセル,_後ろ5個ならび,_2つの平均値) :- findmin([M,N],( append(_,[N|_],_前5個ならび), M is abs(N - _そのセル)), [_差1,_値1]), findmin([M,N],( append(_,[N|_],_後5個ならび), M is abs(N - _そのセル)), [_差2,_値2]), _2つの平均値 is (_値1 + _値2) / 2. '参照しているセルに一番近い値をそのまま別の配列に格納する'(_前5個ならび,_そのセル,_後ろ5個ならび,_参照しているセルに一番近い値) :- append(_前5個ならび,_後ろ5個ならび,L), findmin([M,N],( append(_,[N|_],L), M is abs(N - _そのセル)), [_差2,_参照しているセルに一番近い値]),!. 'result.csvファイルとして出力する'(LL) :- open('result.csv',write,Outstream), 'result.csvファイルとして出力する'(Outstream,LL), close(Outstream). 'result.csvファイルとして出力する'(_,[]) :- !. 'result.csvファイルとして出力する'(Outstream,[L|R]) :- concat_atom(L,' ',S), write_formatted(Outstream,'%t\n',[S]), 'result.csvファイルとして出力する'(Outstream,R). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1294061094/3 # # 【質問テンプレ】 # [1] 授業単元:画像処理学 # [2] 問題文(含コード&リンク): #   指定されたエクセルファイル(csv1)の中にあるデータを読み込み #   各列ごとにそれぞれのデータに対し[0,1]区間に正規化し #   別のエクセルファイル(csv2)として出力せよ. #   正規化されたエクセルファイルの中にあるデータを読み込み #   そのデータをそれぞれx軸の値として #   y = x + a  の式との交点であるy軸の値をそれぞれ #   別のエクセルファイルとして出力(csv3)せよ. #   a の値は -1〜1 までの値を0.5刻みでランダムにとり #   同じ行では同じ関数を使うものとする. #   その後そのプログラムに加え #   各行に対し3つずつそれぞれランダムにaを決定した関数との接点を求め出力する. #   また6列目に使用したaの値をa1,a2,a3という形で出力(csv4)せよ. # '指定されたエクセルファイル(csv1)の中にあるデータを読み込み各列ごとにそれぞれのデータに対し[0,1]区間に正規化し別のエクセルファイル(csv2)として出力する'(_指定されたCSVファイル,_別のCSVファイル) :- get_split_lines(_指定されたCSVファイル,[' ',','],LL1), 転置(LL1,LL2), '各列ごとにそれぞれのデータに対し[0,1]区間に正規化し'(LL2,LL3), 転置(LL3,LL4), '別のエクセルファイル(csv2)として出力する'(LL4,_別のCSVファイル). '各列ごとにそれぞれのデータに対し[0,1]区間に正規化し'([],[]) :- !. '各列ごとにそれぞれのデータに対し[0,1]区間に正規化し'([L1|R1],[L2|R2]) :- 相加平均(L1,_相加平均), 標準偏差(L1,_標準偏差), '各列ごとにそれぞれのデータに対し[0,1]区間に正規化し'(L1,_相加平均,_標準偏差,L2), '各列ごとにそれぞれのデータに対し[0,1]区間に正規化し'(R1,R2). '各列ごとにそれぞれのデータに対し[0,1]区間に正規化し'([A|R1],_相加平均,_標準偏差,[B|R2]) :- B is ( A - _相加平均) / _標準偏差, '各列ごとにそれぞれのデータに対し[0,1]区間に正規化し'(R1,_相加平均,_標準偏差,R2). '別のエクセルファイル(csv2)として出力する'(_別のCSVファイル,LL) :- open(_別のCSVファイル,write,Outstream), 'CSVファイルとして出力する'(Outstream,LL), close(Outstream). 'CSVファイルとして出力する'(Outstream,[]) :- !. 'CSVファイルとして出力する'(Outstream,[L|R]) :- concat_atom(L,',',S), write_formatted(Outstream,'%t\n',[S]), 'CSVファイルとして出力する'(Outstream,R). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1291471791/956 # # 【質問テンプレ】 # [1] 授業単元:画像処理学 # [2] 問題文(含コード&リンク): #   指定されたエクセルファイルの中にあるデータを読み込み #   各列ごとにそれぞれのデータに対し[0,1]区間に正規化し #   別のエクセルファイルとして出力せよ. # '指定されたエクセルファイルの中にあるデータを読み込み各列ごとにそれぞれのデータに対し[0,1]区間に正規化し別のエクセルファイルとして出力せよ.'(_指定されたCSVファイル,_別のCSVファイル) :- get_split_lines(_指定されたCSVファイル,[' ',','],LL), 転置(LL,LL1), 行単位に正規化(LL1,LL2), 転置(LL2,LL3), csvファイルとして出力する(_別のcsvファイル,LL3). 行単位に正規化([],[]) :- !. 行単位に正規化([L1|R1],[L2|R2]) :- 相加平均(L1,_相加平均), 標準偏差(L1,_標準偏差), 正規化(L1,_相加平均,_標準偏差,L2), 行単位に正規化(R1,R2). 正規化([],_,_,[]) :- !. 正規化([A|R1],_相加平均,_標準偏差,[B|R2]) :- B is (_相加平均 - A) / _標準偏差, 正規化(R1,_相加平均,_標準偏差,R2). csvファイルとして出力する(_別のcsvファイル,LL) :- open(_別のcsvファイル,write,Outstream), append(_,[L|R],LL), concat_atom(L,',',S), write_formatted(Outstream,'%t\n',[S]), R = [], close(Outstream). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1291471791/778 # # 1] 授業単元:Cプロ実習 # [2] 問題文(含コード&リンク): # 2つの4×4行列を2次元配列に格納し、それらの積を求めるプログラムを作成せよ。 # 以下の関数を必ず利用すること。 # 関数の引数の型では1次元目が空白になっているが、 #  main関数では4×4の通常の2次元配列を用いればよい。 # '2つの4×4行列を2次元配列に格納し、それらの積を求める' :- 行列一の入力(LL1), 行列二の入力(LL2), 行列の積(LL1,LL2,LL3), 結果の表示(LL1,LL2,LL3). 行列一の入力(LL1) :- length(LL1,4), findall(L1, append(L0,[L1|_],LL1), length([_|L0],Nth), write_formatted('第二行列の%t行目をカンマ区切りで4列入力してください\n',[Nth]), カンマ区切りによる四項入力(L1)), LL1). 行列二の入力(LL2) :- length(LL2,4), findall(L2, append(L0,[L2|_],LL2), length([_|L0],Nth), write_formatted('第二行列の%t行目をカンマ区切りで4列入力してください\n',[Nth]), カンマ区切りによる四項入力(L2)), LL2). カンマ区切りによる四項入力(L) :- get_line(Line), カンマ区切りによる四項入力診断(Line,L),!. カンマ区切りによる四項入力(L) :- カンマ区切りによる四項入力(L). カンマ区切りによる四項入力診断(Line,L) :- split(Line,[','],L), length(L,4), すべて数値(L),!. カンマ区切りによる四項入力診断(Line,L) :- write('入力された%tからは四項を取り出すことができません。再入力をお願いします。\n'), fail. すべて数値([]) :- !. すべて数値([V|R]) :- number(V),すべて数値(R). 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 行列の転置(R2,R3,R4). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[L1|R2]) :- 行列の転置(L,L2,L1), 行列の転置(L2,R2). 結果の表示(LL1,LL2,LL3) :- 行列の表示(LL1), write(' ×\n'), 行列の表示(LL2), write(' =\n'), 行列の表示(LL3). 行列の表示(LL) :- write('['), 行列の表示の一(LL). 行列の表示の一([]) :- write(']\n'),!. 行列の表示の一([L]) :- write_formatted(' %t]\n',[L]),!. 行列の表示の一([L|R]) :- write_formatted(' %t\n',[L]), 行列の表示の一(R),! % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1291471791/456 # # ../test/read.cgi/tech/1291471791/400 IEだと文字化けしてたのではりなおします…(´・ω・`) # # 問題1:キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力。 # 次の表の形式にして画面に出力するようにする(平均は小数点第二位まで) # # A B C D heikin # sugaku 40 100 50 50 60.00 # eigo 60 80 100 30 67.50 # kokugo 26 25 50 60 40.25 # 'キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力。次の表の形式にして画面に出力するようにする(平均は小数点第二位まで)\\n A B C D heikin\\neigo 60 80 100 30 67.50\\nkokugo 26 25 50 60 40.25\\n' :- 'キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力'(LL1), 転置(LL1,LL2), 次の表の形式にして画面に出力する(LL2). 'キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力'(LL) :- length(LL,4), 'キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力'(['A','B','C','D'],LL). 'キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力'(_,[]). 'キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力'([_氏名|R1],[_成績|R2]) :- write_formatted_atom(S,'%t : ',[_氏名]), 催促付き整数入力(S,_成績), 'キーボードから4人の数学、英語、国語の成績(整数)をint型二次元配列に入力'(R1,R2). 次の表の形式にして画面に出力する(LL) :- write(' A B C D heikin\n'), append(_,[_行|R],LL2), concat_atom(_行,' ',S1), avg(_行,_平均), write_formatted_atom(S2,'%.2f',[_平均]), write_formatted('%t %t\n',[S1,S2]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1289913298/122 # # [1] 授業単元:プログラミング # [2] 問題文 # コンストラクタでrow,columnを指定して、動的に確保 # デストラクタを解放 # これで足し算メソット add(matrix Y)を作ってください # 行列を確保する(_row,_column,_行列) :- findall(L,( for(1,_,_row), length(L,_column)), _行列). 足し算(_行列1,_足し算された行列) :- すべての行を足し算して答えを列として追加する(_行列1,_行列2), 転置(_行列2,_行列3), すべての行を足し算して答えを列として追加する(_行列3,_行列4), 転置(_行列4,_足し算された行列). すべての行を足し算して答えを列として追加する([_行1|R1],[_行2|R2]) :- 加算(_行1,_和), append(_行1,[_和],_行2), すべての行を足し算して答えを列として追加する(R1,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1288531658/604 # # [1] 授業単元: プログラム # [2] 問題文(含コード&リンク):10人分の各教科の平均点を計算する関数を実装してください。 # % 10人分という部分に何か意味があるかどうか? 何教科あるかの方が問題ではないか。 % このプログラムだと教科数の検査ができていない。 '10人分の各教科の平均点を計算する関数を実装してください。' :- '10人分の各教科の点数を入力する'(_個人成績ならび), '10人分の各教科の平均点を計算する'(_個人成績ならび,_教科毎平均点), 教科毎の平均を表示する(_教科毎平均点). '10人分の各教科の平均点を計算する'(_個人成績ならび,_教科毎平均点) :- 転置(_個人成績ならび,[_|_個人名を除き転置された個人成績ならび]), findall(_教科の平均点,( append(_,[L|_],_個人名を除き転置された個人成績ならび), avg(L,_教科の平均点)), _教科毎の平均点). '10人分の各教科の点数を入力する'(_個人成績ならび) :- length(_個人成績ならび,10), 個人成績を一行で入力していく(_個人成績ならび). 個人成績を一行で入力していく([]) :- !. 個人成績を一行で入力していく([_個人成績|R]) :- write('個人成績を最初に個人名その後教科成績をカンマ区切りで入力してください : '), get_line(Line), split(Line,[','],_個人成績), 本来ならここに項目数検査、項目内容の精査が入る, 個人成績を一行で入力していく([_],R). 教科毎の平均を表示する(_,[]). 教科毎の平均を表示する(LC,[_平均|R]) :- length(LC,N), write_formatted('教科-%t の平均点は %t です。\n',[N,_平均]), 教科毎の平均を表示する([_|LC],R). %%%%%%%%%%%%%%%%%% 注釈的述語 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 本来ならここに項目数検査、項目内容の精査が入る. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1288531658/460 # # [1] 授業単元: コンピュータ基礎 # [2] 問題文(含コード&リンク): # 3行3列の実数行列aijとbijの積を計算するプログラムを作成せよ。 # ただし、乗算結果の行列をcijとして計算を行うものとする。 # 行列の要素への入力は、代入文あるいは初期化子を用いること。 # 行列の積(L1,L2,L3) :- 転置(L2,L22), 行列の積_1(L1,L22,L3). 行列の積_1([],[],[]) :- !. 行列の積_1([L1|R1],[L2|R2],[L3|R3]) :- 行列の積_2(L1,L2,L3), 行列の積_1(R1,R2,R3). 行列の積_2(_,[],[]) :- !. 行列の積_2(L1,[L2|R2],[U|R3]) :- 行列の積_3(L1,L2,U), 行列の積_2(L1,R2,R3). 行列の積_3([],[],0) :- !. 行列の積_3([A|R1],[B|R2],X) :- U is A * B, 行列の積_3(R1,R2,Y), X is U + Y. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1288531658/3 # # [1] 授業単元:C言語入門 # # [2] 問題文):最大24個の整数が格納できる配列を用意する。 # この配列の先頭から10個分には1を代入し, # つづく6個分には0を入れ,最後の8個分には-1を入れよ。 # # '最大24個の整数が格納できる配列を用意する。この配列の先頭から10個分には1を代入し,つづく6個分には0を入れ,最後の8個分には-1を入れよ。'(L) :- 最大24個の整数が格納できる配列を用意する(L), この配列の先頭から10個分には1を代入し(L,R1), つづく6個分には0を入れ(R1,R2), '最後の8個分には-1を入れよ'(R2). 最大24個の整数が格納できる配列を用意する(L) :- length(L,24). この配列の先頭から10個分には1を代入し(L,R) :- length(L1,10), all(L1,1), append(L1,R,L). つづく6個分には0を入れ(L,R) :- length(L1,6), all(L1,0), append(L1,R,L). '最後の8個分には-1を入れよ'(L) :- length(L,8), all(L,-1). ?- ti. no. ?- keizo104 :: pwd(X). ?- w3db(keizo104,7083,true). yes. ?- !'ls -l *.html | grep "2010-10-31"'. -rw-r--r-- 1 root root 745 2010-10-31 17:15 c141_966.html -rw-r--r-- 1 root root 1057 2010-10-31 20:54 c141_971.html -rw-r--r-- 1 root root 592 2010-10-31 22:42 c141_983.html yes. ?- cat c141_966.html. # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1286978599/966 # # [1] 授業単元:情報処理 # [2] 問題文(含コード&リンク): # http://ime.nu/img69.imageshack.us/img69/1731/65183447.jpg # (b)、(d)の回答をよろしくお願いします。 # # 1 dを入力し、(n+1)^2 - n^2 =< d なる最小のnを出力するプログラムを #  while 文を使って作りたい。nは整数、 dは実数とせよ。以下の問に答えよ。 # # (a) このプログラムに必要な変数を述べよ。 # (b) (n + 1)^2 - n^2 =< d を判定するC言語の条件式を書け。 # (c) 処理の手順を番号付き箇条書、または、フローチャートで示せ。 # (d) プログラムを書け。 yes. ?- cat c141_971.html. # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1286978599/971 # # [1] 授業単元:プログラミング演習 # [2] 問題文(含コード&リンク) # # *記号を使ってでsin曲線を描け。 # '*記号を使ってsin曲線を描け。' :- '*記号を使ってでsin曲線を描け。'(1,LL), 転置(LL,LL2), append(_,[L|R],LL2), concat_atom(L,A), write_formatted('%t\n',[A]), R = []. '*記号を使ってsin曲線'(X,[]) :- X > 629,!. '*記号を使ってsin曲線'(X,[L|R]) :- length(L0,101), Y is truncate((100 * sin((X-1) * pi / 100))+101), list_nth(Y,L0,'*'), reverse(L0,L1), 全ての変数を空白に(L0), X2 is X + 1, '*記号を使ってsin曲線'(X2,R). 全ての変数を空白に([]) :- !. 全ての変数を空白に([V|R]) :- var(V), V = ' ', 全ての変数を空白に(R),!. 全ての変数を空白に([_|R]) :- 全ての変数を空白に(R),!. ?- nojiri('c141_971.html'). yes. ?- ti. ?- !'ls -l *.html | grep "2010-10-30"'. -rw-r--r-- 1 root root 3258 2010-10-30 03:06 c141_863.html -rw-r--r-- 1 root root 2471 2010-10-30 17:27 c141_863_1.html -rw-r--r-- 1 root root 3771 2010-10-30 09:07 c141_863_2.html -rw-r--r-- 1 root root 561 2010-10-30 23:28 c141_948.html yes. # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1286978599/948 # # [1] 授業単元:プログラムとアルゴリズム # [2] 問題文(含コード&リンク):整数配列aとその長さnを渡して、配列のそれぞれの要素を10倍して戻す関数Funcを作成し、必要な追加を行って動作を確認しなさい。 # 下敷きとするソースコードは以下のURL(jpgで見にくくてすみません)でお願いします。 # http://ime.nu/pc.gban.jp/?p=24057.jpg # 'リストa、長さnを渡して、n要素だけ10倍して戻す'(_a,_n,X) :- length(L,_n), append(L,R,_a), '10倍して戻す'(L,L10), append(L10,R,X). '10倍して戻す'(L,L10) :- findall(N2,( append(_,[N|_],L), N2 is N * 10), L10). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 'リストa、長さnを渡して、n要素だけ10倍して戻す'(_a,_n) :- length(L,_n), '10倍して戻す'(L,_a,X), '10倍して戻す'([],X,X) :- !. '10倍して戻す'([_|R1],[N|R2],[N2|R3]) :- N2 is N * 10, '10倍して戻す'(R1,R2,R3). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 'リストa、要素位置m、長さnを渡して、最初からm要素目からn要素だけ10倍して戻す'(_a,_m,X) :- length(L,_n), _m_1 is _m - 1, length(L1,_m_1), append(L1,R,_a), '10倍して戻す'(L,R,L2), append(L1,L2,X). '10倍して戻す'([],X,X) :- !. '10倍して戻す'([_|R1],[N|R2],[N2|R3]) :- N2 is N * 10, '10倍して戻す'(R1,R2,R3). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1286978599/971 # # [1] 授業単元:プログラミング演習 # [2] 問題文(含コード&リンク) # # *記号を使ってでsin曲線を描け。 # '*記号を使ってsin曲線を描け。' :- '*記号を使ってでsin曲線を描け。'(1,LL), 転置(LL,LL2), append(_,[L|R],LL2), concat_atom(L,A), write_formatted('%t\n',[A]), R = []. '*記号を使ってsin曲線'(X,[]) :- X > 629,!. '*記号を使ってsin曲線'(X,[L|R]) :- length(L0,101), Y is truncate((100 * sin((X-1) * pi / 100))+101), list_nth(Y,L0,'*'), reverse(L0,L1), 全ての変数を空白に(L0), X2 is X + 1, '*記号を使ってsin曲線'(X2,R). 全ての変数を空白に([]) :- !. 全ての変数を空白に([V|R]) :- var(V), V = ' ', 全ての変数を空白に(R),!. 全ての変数を空白に([_|R]) :- 全ての変数を空白に(R),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1286978599/859 # # [1] プログラミング演習 # [2] 10個のデータ{2, 9, 4, 3, 4, 5, 7, 9, 3, 5}を与えて、その値を*を使い # 下向きのグラフで表示してください。数値一個当たり*一個で表示しなければいけません。 # 実行例 # -------------------- # 2 # * # * # '10個のデータ{2, 9, 4, 3, 4, 5, 7, 9, 3, 5}を与えて、その値を*を使い下向きのグラフで表示してください。数値一個当たり*一個で表示しなければいけません。' :- max([2, 9, 4, 3, 4, 5, 7, 9, 3, 5],Max), 横向きイメージ(Max,[2, 9, 4, 3, 4, 5, 7, 9, 3, 5],_横向きイメージ), 転置(_横向きイメージ,_下向きイメージ), write('--------------------\n'), append(_,[_横方向一行ならび|R],_下向きイメージ), concat_atom(_横方向一行ならび,' ',_表示文字列), write_formatted('%t\n',[_表示文字列]), R = []. 横向きイメージ(_,[],[]) :- !. 横向きイメージ(Max,[N|R1],[[N|_星と空白からなるならび]|R2]) :- length(_星と空白からなるならび,Max), append(_星ならび,_空白ならび,_星と空白からなるならび), length(_星ならび,N), all(_星ならび,'*'), all(_空白ならび,' '), 横向きイメージ(Max,R1,R2). % 以下のサイトは # 左横書き文書を右縦書き文書に変換してください # 左横書き文書を右縦書き文書に変換(_横書きの行ならび,_縦書きに置換された行ならび) :- 行の最大長まで空白を付加した文字ならびのならびを作る(_横書きの行ならび,_文字ならびのならび), 転置(_文字ならびのならび,_縦書き用に転置された文字ならびのならび), 右書き用に反転して文字列に戻す(_縦書き用に転置された文字ならびのならび,_縦書きに置換された行ならび),!. 行の最大長まで空白を付加した文字ならびのならびを作る(_横書きの行ならび,_文字ならびのならび) :- 行の最大長を得る(_行の最大長), findall(Chars_2,( append(_,[_行|_],_横書きの行ならび), atom_chars(_行,Chars_1), 空白を付加して文字数を揃える(_行の最大長,Chars_1,Chars_2)), _文字ならびのならび). 行の最大長を得る(_行の最大長) :- findmax(_長さ,( append(_,[_行|_],_横書きの行ならび), sub_atom(_行,0,_長さ,0,_行)), _行の最大長). 空白文字を付加して文字数を揃える(_文字の最大長,_文字ならび,_空白を付加された文字ならび) :- length(_空白を付加された文字ならび,_文字の最大長), append(_文字ならび,_付加するならび,_空白を付加された文字ならび), all(_付加するならび,' '). 右書き用に反転して文字列に戻す([],[]) :- !. 右書き用に反転して文字列に戻す([L1|R1],[S|R2]) :- reverse(L1,L2), atomic_list_concat(L2,S), 右書き用に反転して文字列に戻す(R1,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1272006124 # # <問題> # 全社員が売上を記録した日を求めよ。 これをPrologプログラムとして表現しなさい。 全社員が売上を記録した日を求めよ(_日) :- count(社員(_社員),_社員人数), findsetof(_日,売上(_社員,_日,_データ),L1), append(_,[_日|R],L1), findsetof(_社員,社員(_社員,_日,_データ),L2), length(L2,_社員人数). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% count(P,N) :- findsum(1,P,F), N is truncate(F). findsum(_選択項,_項,_合計値) :- findall(_選択項,_項,_値ならび), 加算(_値ならび,_合計値),!. findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), L = 0.0e+00,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S). 加算_1([],S,S) :- !. 加算_1([A|R],Y,S) :- ならび(A), ならび(Y), !, ならび加算(A,Y,Z), 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,I), integer(I), Z is I + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,F), real(F), Z is F + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), 加算_1(R,Y,S),!. 加算_1([A|R],Y,S) :- A1 は A, Z is A1 + Y, 加算_1(R,Z,S). 加算_2([],[]) :- !. 加算_2([L|R],[S|R2]) :- 加算(L,S), 加算_2(R,R2). ならび加算([],L,L) :- !. ならび加算(L,[],L) :- !. ならび加算([A|R],[B|R1],[C|R2]) :- C is A + B, ならび加算(R,R1,R2). 加算の変数に零をおく([]) :- !. 加算の変数に零をおく([A|R]) :- 変数(A), A = 0.0e+00, 加算の変数に零をおく(R),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1284632294/523 # # [1] 授業単元:プログラミング # [2] 問題文(含コード&リンク): # 入力された2つの行列の積算を行い、結果を示せ。 # 1.行列の行、列数の入力を求める # 2.2つの行列の積算 # 3.行列として結果を表示 # '2つの行列の積算'(_行列1,_行列2,_行列の積) :- 行列を入力する(_行列1), write('入力された行列は\n'), 行列の表示(_行列1), 行列を入力する(_行列2), write('入力された行列は\n'), 行列の表示(_行列2), 行列の積(_行列1,_行列2,_行列の積), write('積行列は\n'), 行列の表示(_行列の積). 行列を入力する(_行列) :- 行列の行、列数の入力を求める(_行数,_列数), findall(L1,( for(1,N,_行数), length(L1,_列数), write('1行分入力します\n'), 行の入力(L1)), _行列). 行の入力([]) :- !. 行の入力([_値|R]) :- write('値を入力してください : '), get_line(Line), 行の入力診断(Line,_値), 行の入力(R). 行の入力(L) :- 行の入力(L). 行の入力診断(Line,_値) :- atom_to_term(Line,_値,_), number(_値),!. 行の入力診断(Line,V) :- write_formatted('%tは行列の要素としては適切でありません。再入力が必要です。\n',[Line]), fail. 行列の行、列数の入力を求める(_行数,_列数) :- 行数の入力(_行数), 列数の入力(_列数),!. 行数の入力(_行数) :- write('行数を入力してください : '), get_line(Line), 行数入力の診断(Line,_行数),!. 行数の入力(_行数) :- 行数の入力(_行数). 列数の入力(_列数) :- write('列数を入力してください : '), get_line(Line), 列数入力の診断(Line,_列数),!. 列数の入力(_列数) :- 列数の入力(_列数). 行数入力の診断(Line,_行数) :- atom_to_term(Line,_行数,_), integer(_行数), _行数 > 0,!. 行数入力の診断(Line,_行数) :- write_formatted('%tは適切な行数ではありません。再入力が必要です。\n',[Line]), fail. 列数入力の診断(Line,_列数) :- atom_to_term(Line,_列数,_), integer(_列数), _列数 > 0,!. 列数入力の診断(Line,_列数) :- write_formatted('%tは適切な列数ではありません。再入力が必要です。\n',[Line]), fail. 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 行列の転置(R2,R3,R4). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[L1|R2]) :- 行列の転置(L,L2,L1), 行列の転置(L2,R2). 行列の表示([]) :- write(']\n'),!. 行列の表示([L]) :- write_formatted(' %t]\n',[L]),!. 行列の表示([L|R]) :- write_formatted(' %t\n',[L]),行列の表示(R),! % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1197620454/580 # # 下記のプログラムを関数を用いて実行したいのですが、どのようにすれば良いでしょうか? # 回答(できたら簡単な解説)の明記をお願いします。 # # 問題1:入力したプログラムから以下のように出力するプログラムを作成する。 # (実行結果例) # 文字列を入力: 今日は、晴れです。 # # 今日は、晴れです。 # 日 す # は で # 、 れ # 晴 晴 # れ 、 # で は # す 日 # 。すでれ晴、は日今 # 最初と最後に特別なことをするリスト処理 :- write('文字列を入力: '), get_line(Line), atom_chars(Line,Chars), reverse(Chars,Chars2), 転置([[Chars,Chars2]],_転置されたChars), 最初と最後だけ特別のことをする([Chars,Chars2],_転置されたChars,L), put_lines(L). 最初と最後だけ特別のことをする(L,L1,L) :- 最初は特別のことをする(L,L1,R1,L2), 残りの処理(L,R1,L2). 残りの処理(L,L1,X) :- 最後は特別のことをする(L,L1,X),!. 残りの処理(L,[[A,B]|R1],[S|R2]) :- write_formatted_atom(S,'%t %t',[A,B]), 残りの処理(L,R1,R2). 最初は特別のことをする([Head,_],[_|R1],R1,[S|R2]) :- concat_atom(Head,S),!. 最後は特別のことをする([_,Last],[_],[S]) :- concat_atom(Last,S),!. %%%%%%%%%%%%%%% こちらが一般形 %%%%%%%%%%%%%%%%%%%%%%%%%% 最初と最後だけ特別のことをする([A|R1],[B|R2]) :- 最初は特別のことをする(A,B), 残りの処理(R1,R2). 残りの処理(L1,X) :- 最後は特別のことをする(L1,X),!. 残りの処理([A|R1],[B|R2]) :- 通常の処理(A,B), 残りの処理(R1,R2). 最初は特別のことをする(A,B) :- 最初は特別(A,B). 最後は特別のことをする([A],[B]) :- 最後は特別(A,B). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1197620454/580 # # 下記のプログラムを関数を用いて実行したいのですが、どのようにすれば良いでしょうか? # 回答(できたら簡単な解説)の明記をお願いします。 # # 問題1:入力したプログラムから以下のように出力するプログラムを作成する。 # (実行結果例) # 文字列を入力: 今日は、晴れです。 # # 今日は、晴れです。 # 日 す # は で # 、 れ # 晴 晴 # れ 、 # で は # す 日 # 。すでれ晴、は日今 # 最初と最後に特別なことをするリスト処理 :- write('文字列を入力: '), get_line(Line), atom_chars(Line,Chars), reverse(Chars,Chars2), 転置([[Chars,Chars2]],_転置されたChars), 最初と最後だけ特別のことをする([Chars,Chars2],_転置されたChars,L), put_lines(L). 最初と最後だけ特別のことをする(L,L1,L) :- 最初は特別のことをする(L,L1,R1,L2), 残りの処理(L,R1,L2). 残りの処理(L,L1,X) :- 最後は特別のことをする(L,L1,X),!. 残りの処理(L,[[A,B]|R1],[S|R2]) :- write_formatted_atom(S,'%t %t',[A,B]), 残りの処理(L,R1,R2). 最初は特別のことをする([Head,_],[_|R1],R1,[S|R2]) :- concat_atom(Head,S),!. 最後は特別のことをする([_,Last],[_],[S]) :- concat_atom(Last,S),!. %%%%%%%%%%%%%%% こちらが一般形 %%%%%%%%%%%%%%%%%%%%%%%%%% 最初と最後だけ特別のことをする([A|R1],[B|R2]) :- 最初は特別のことをする(A,B), 残りの処理(R1,R2). 残りの処理(L1,X) :- 最後は特別のことをする(L1,X),!. 残りの処理([A|R1],[B|R2]) :- 通常の処理(A,B), 残りの処理(R1,R2). 最初は特別のことをする(A,B) :- 最初は特別(A,B). 最後は特別のことをする([A],[B]) :- 最後は特別(A,B). % 以下のサイトは # 出典:: 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/241 # # ../test/read.cgi/tech/1274827528/235です。何度もすいません。 # # ↓のように出力するにはどうすればいいでしょうか #  #   1  4  5  10  #   4  5  6  15 #   5  8  7  20 #  10 10 10  30 #  #  20 27 28  75 # # 表に合計を付加して、表示する。ただし、行和、列和の前は少し空ける(_表) :- 表に合計を付加して、(_表,_合計が付加された表), 表示する。ただし、行和、列和の前は少し空ける(_合計が付加された表). 表に合計を付加する、(_表,_合計が付加された表) :- 転置(_表,_転置表), 算術和(_転置表,_横合計ならび), ならびの連結(_転置表,[_横合計ならび],_横合計が付加された転置表), 転置(_横合計が付加された転置表,_横合計付加表), 算術和(_横合計付加表,_縦合計ならび), ならびの連結(_横合計付加表,[_縦合計ならび],_合計が付加された表),!. 表示する。ただし、行和、列和の前は少し空ける(_合計が付加された表) :- append(_,[L|R],_合計が付加された表), append(L1,[E],L), concat_atom(L1,' ',S1), write_formtted('%t %t\n',[S1,E]), R = [L2], append(L3,[E2],L2), concat_atom(L3,' ',S2), write('\n'), write_formatted('%t %t\n',[S2,E2]). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1274827528/204 # # 「4行3列の配列をキーボードから読み込み、 # 各行、各列の和、及び配列全体の総和を求め、表示する # プログラムを作成しなさい。」という問題です。 '4行3列の配列をキーボードから読み込み、各行、各列の和、及び配列全体の総和を求め、表示する' :- '4行3列の配列をキーボードから読み込み、'(_4行3列の配列), 各行、各列の和、及び配列全体の総和を求め、(_4行3列の配列,_各行の和,_各列の和,_配列全体の総和), '_4行3列の配列,_各行の和,_各列の和,_配列全体の総和を表示する'(_4行3列の配列,_各行の和,_各列の和,_配列全体の総和). '4行3列の配列をキーボードから読み込み、'(_4行3列の配列) :- write('列を3要素の整数リストとして4行入力しなさい(ただしread/1で読み込めるよう入力は.で終わること) : '), findall(_3要素の整数ならび,(for(1,N,3),read(_3要素の整数ならび)),_4行3列の配列). 各行、各列の和、及び配列全体の総和を求め、(_4行3列の配列,_各行の和,_各列の和,_配列全体の総和) :- 各行の和(_4行3列の配列,_各行の和), 各列の和(_4行3列の配列,_各列の和), 配列全体の総和(_各行の和,_配列全体の総和). 各行の和(_4行3列の配列,_各行の和) :- findall(_行の和,(append(_,[_行|_],_4行3列の配列), sum(_行,_行の和)),_各行の和). 各列の和(_4行3列の配列,_各列の和) :- 転置(_4行3列の配列,_転置された配列), 各行の和(_転置された配列,_各列の和). 配列全体の総和(_各行の和,_配列全体の総和) :- sum(_各行の和,_配列全体の総和). '_4行3列の配列,_各行の和,_各列の和,_配列全体の総和を表示する'(_4行3列の配列,_各行の和,_各列の和,_配列全体の総和) :- 行の表示(_4行3列の配列,_各行の和), 各列の和の表示(_各列の和), 配列全体の総和の表示(_配列全体の総和). 行の表示([],[]) :- !. 行の表示([_行|R1],[_和|R2]) :- append(_行,[_和],L), write_formatted('%d,%d,%d,%d\n',L), 行の表示(R1,R2). 各列の和の表示(_各列の和) :- write_formatted('%d,%d,%d,',_各列の和). 配列全体の総和の表示(_配列全体の総和) :- write_formatted('%d\n',[_配列全体の総和]). sum([],0) :- !. sum([N|R],S) :- sum(R,S1),S is N + S1. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1269438098/921 # # [1]授業単元:プログラミング # [2]問題文:(1)scanfにより3つの正の整数a,b,cの値を入力する。 #      (2)(i,j)要素がj+(a-1)*iであるa×b行列を定義する。 #       (3)(i,j)要素がj-(b-1)*iであるb×c行列を定義する。 #      (4)2つの行列の積を計算し、結果を表示する。 # [3]環境:windows,C++ # [4]期限:5月25日 # [5]なし # # よろしくおねがいします。 # '(4)2つの行列の積を計算し、結果を表示する' :- '3つの正の整数a,b,cの値を入力する'(_a,_b,_c), '(i,j)要素がj+(a-1)*iであるa×b行列を定義する'(_a,_b,_行列1), '(i,j)要素がj-(b-1)*iであるb×c行列を定義する'(_b,_c,_行列2), 行列の積(_行列1,_行列2,_行列の積), 行列の表示(_行列の積). '3つの正の整数a,b,cの値を入力する'(_a,_b,_c) :- get_split_line([' '],[_a,_b,_c]). '(i,j)要素がj+(a-1)*iであるa×b行列を定義する'(_a,_b,_行列) :- findall(L2,(for(1,_i,_a),findall(U,(for(1,_j,_b),U is _j + ( _a - 1 ) * _i),L2)),_行列). '(i,j)要素がj-(b-1)*iであるb×c行列を定義する'(_b,_c,_行列) :- findall(L2,(for(1,_i,_b),findall(U,(for(1,_j,_c),U is _j - ( _b - 1 ) * _i),L2)),_行列). 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 行列の転置(R2,R3,R4). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[L1|R2]) :- 行列の転置(L,L2,L1), 行列の転置(L2,R2). 行列の表示([]) :- write(']\n'),!. 行列の表示([L]) :- write_formatted(' %t]\n',[L]),!. 行列の表示([L|R]) :- write_formatted(' %t\n',[L]),行列の表示(R),! % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1269438098/855 # # [1] 授業単元: プログラム演習 # [2] 問題文(含コード&リンク): 2×2行列Aと二次元ベクトルxとの積Axを計算する関数linear_trans()を実装しなさい。ただし、関数linear_trans()は以下のような仕様とする。 # void linear_trans(double matA [2][2], double vecx[2], double vecy[2]) # { # /*matA × vecx = vecy を実装*/ # } # 2×2行列Aと二次元ベクトルxとの積Axを計算する(_行列A,_ベクトルx,_積Ax) :- ならびを着る(_ベクトルx,L1), 行列の積(_行列A,L1,_行列A_2), ならびを脱ぐ(_行列A_2,_積Ax). 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 行列の転置(R2,R3,R4). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[L1|R2]) :- 行列の転置(L,L2,L1), 行列の転置(L2,R2). ならびを着る([],[]) :- !. ならびを着る([_項|_残りならび],[[_項]|_残りならびの二]) :- ならびを着る(_残りならび,_残りならびの二),!. ならびを脱ぐ([],[]) :- !. ならびを脱ぐ([A|R],L) :- list(A),!, ならびを脱ぐ(A,L1), ならびを脱ぐ(R,L2), append(L1,L2,L) . ならびを脱ぐ([A|R],[A|R1]) :- ならびを脱ぐ(R,R1) . % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1269438098/801 # # [1] 授業単元:プログラミング演習 # [2] 問題文: # テストの点数を入力し合計点、平均点、受験者数、合格者数を表示するプログラムを作成しなさい。ただし、データの終わりの999(999点と表示しない)合格者は60点以上 # 実行例 # # 84         <--キーボードから点数入力 # 84点        <--入力した点数を表示 # 95 # 95点 # 48 # 48点 # 66 # 66点 # 80 # 80点 # 999     <--データの終わり(999点とは表示しない) # 合計点=373点 # 平均点=74.6点 # 受験者数=5名 # 合格者数=4名 # キーボードから点数入力 テストの点数を入力し合計点、平均点、受験者数、合格者数を表示するプログラムを作成しなさい。ただし、データの終わりの999(999点と表示しない)合格者は60点以上 :- 'テストの点数を入力し、ただし、データの終わりの999(999点と表示しない)'(_点数ならび), 合計点(_点数ならび,_合計点), 受験者数(_点数ならび,_受験者数), 合格者数(_点数ならび,_合格者数), 表示する('合計点=%t\n平均点=%t点\n受験者数=%t\n合格者数=%t\n',[_合計点,_平均点,_受験者数,合格者数]). 'テストの点数を入力し、ただし、データの終わりの999(999点と表示しない)'(_点数ならび) :- キーボードから点数入力('点数を入力してください(データの終わりの999) : ',_点数), 'テストの点数を入力し、ただし、データの終わりの999(999点と表示しない)'(_点数,_点数ならび). 'テストの点数を入力し、ただし、データの終わりの999(999点と表示しない)'(_点数,[]) :- 'ただし、データの終わりの999(999点と表示しない)'(_点数),!. 'テストの点数を入力し、ただし、データの終わりの999(999点と表示しない)'(_点数,[_点数|R]) :- 入力した点数を表示(_点数), キーボードから点数入力(_次の点数), 'テストの点数を入力し、ただし、データの終わりの999(999点と表示しない)'(_次の点数,R). キーボードから点数入力('点数を入力してください(データの終わりの999) : ',_点数) :- 催促付き整数入力('点数を入力してください(データの終わりの999) : ',_点数). キーボードから点数入力(_点数) :- get_integer(_点数). 入力した点数を表示(_点数) :- write_formatted('%t点\n',[_点数]). 'ただし、データの終わりの999(999点と表示しない)'(999). 合計点(_点数ならび,_合計点) :- 加算(_点数ならび,_合計点_浮動小数点),_合計点 is truncate(_合計点_浮動小数点数), 平均点(_点数ならび,_平均点) :- 平均(_点数ならび,_平均点). 受験者数(_点数ならび,_受験者数) :- length(_点数ならび,_受験者数). 合格者数(_点数ならび,_合格者数) :- 度数((member(_点数,_点数ならび),_点数>=60),_合格者数). 表示する(Format,_値ならび) :- write_formatted(Format,_値ならび). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), 合計は原則として浮動小数点数, L = 0.0e+00,!. 加算([],L) :- var(L), 合計は原則として整数, L = 0,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S). 全て整数([]) :- !. 全て整数([N|R]) :- integer(N),全て整数(R). 平均(L,Avg) :- list(L),findavg(A,member(A,L),Avg). 度数(A,[],0). 度数(A,[A|R],X) :- 度数(A,R,Y),X is Y + 1. 度数(A,[_|R],X) :- 度数(A,R,X). 度数(P,N) :- findsum(1,P,F),N is truncate(F). findavg(_集約項,_項,_算術平均) :- findall(_集約項,_項,_値ならび), 加算(_値ならび,_合計値), list_length(_値ならび,_ならびの長さ), _算術平均 is _合計値 / _ならびの長さ,!. 合計は原則として浮動小数点数. % 合計は原則として整数. % 以下のサイトは % *** 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), ! . 行基本変形3(_行目1,*,_乗数,_行目2,_行列,X) :- list_nth(_行目1,_行列,_行1), findall(U,(member(A,_行1),U is A * _乗数),_乗算された行), list_nth(_行目2,_行列,_行2), 加算([_乗算された行,_行2],_加算された行), replace_nth(1,_行目2,_加算された行,_行列,X),!. % *** user: '既約ガウス行列' / 1 *** '既約ガウス行列'(_行列) :- '既約ガウス行列の一'([],_行列), '行列の転置'(_行列,_転置された行列), '既約ガウス行列検査'(_転置された行列). % *** user: '既約ガウス行列' / 2 *** '既約ガウス行列'(_,[]) :- ! . '既約ガウス行列'(L,[_行|R]) :- append(L,_,_行), '要素がゼロ以外に出会うまで'(_行,P1,[1|_]), '既約ガウス行列'([0|P1],R) . 既約ガウス行列の一([_行]) :- 零以外の最初の要素が1(_行),!. 既約ガウス行列の一([_行|R]) :- 零以外の最初の要素が1(_行), 既約ガウス行列の一(R). % *** user: '既約ガウス行列の一' / 2 *** '既約ガウス行列の一'(_,[]) :- ! . '既約ガウス行列の一'(L,[_行|R]) :- append(L,_,_行), '要素がゼロ以外に出会うまで'(_行,P1,[1|_]), '既約ガウス行列の一'([0|P1],R) . 単位行列(_単位行列,N) :- findall(L,(length(L,N),append(L1,[1|R],L),all(L1,0),all(R,0)),_単位行列),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1269438098/148 # # [1] 授業単元: ゼミ演習でのプログラミング # [2] 問題文(含コード&リンク): ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10566.zip # # [1] ヒストグラム # 0〜9の範囲内の整数を20個入力し、そのヒストグラムを求めて出力するプログラムを書きなさい# # '0〜9の範囲内の整数を20個入力し、そのヒストグラムを求めて出力する' :- 0〜9の範囲内の整数を20個入力し(1,_サンプルならび), ヒストグラム(_サンプルならび). ヒストグラム(_サンプルならび) :- 最初に縦棒の限界数を決めよう(_サンプルならび,_限界数), '次に度数表示を*のならびで表現して、0-9のならびを取る'(_サンプルならび,_限界数,_度数表示ならび), 転置(_度数表示ならび,_転置した度数表示ならび), ヒストグラム表示(_転置した度数表示ならび). 最初に縦棒の限界数を決めよう(_サンプルならび,_限界数) :- findmax(U,count(member(U,_サンプルならび)),_限界数). '次に度数表示を*のならびで表現して、0-9のならびを取る'(_サンプルならび,_限界数,_度数表示ならび) :- findall(_度数表示, (for(0,N,9),count(member(N,_サンプルならび),_度数), '空白が先に来るように反転した*ならびの生成'(_度数,1,_限界数,[],_度数表示)), _度数表示ならび). '空白が先に来るように反転した*ならびの生成'(_,N,_限界数,X,X) :- N > _限界数,!. '空白が先に来るように反転した*ならびの生成'(_度数,N,_限界数,Y,X) :- N > _度数, N2 is N + 1, '空白が先に来るように反転した*ならびの生成'(_度数,N2,_限界数,[' '|Y],X). '空白が先に来るように反転した*ならびの生成'(_度数,N,_限界数,Y,X) :- N =< _度数, N2 is N + 1, '空白が先に来るように反転した*ならびの生成'(_度数,N2,_限界数,['*'|Y],X). ヒストグラム表示([]) :- !. ヒストグラム表示([L|R]) :- concat_atom(L,A),write_formatted('%t\n',[A]),ヒストグラム表示(R). 0〜9の範囲内の整数を20個入力し(M,[]) :- M > 20,!. 0〜9の範囲内の整数を20個入力し(M,[N|R]) :- write_formatted('%t個目 : ',[M]), get_integer(N), N >= 0, N =< 9, M2 is M + 1, 0〜9の範囲内の整数を20個入力し(M2,R),!. 0〜9の範囲内の整数を20個入力し(M,L) :- write('0〜9の範囲内の整数を入力してください\n'), 0〜9の範囲内の整数を20個入力し(M,L). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1260532772/32 # # [1] 授業単元: プログラミング論 # [2] 問題文(含コード&リンク): # 次のA・Bの行列をA×Bの計算をして、その結果を表示するプログラムを作成しなさい。 # # A=[5 3]   B=[7 1 5 4] #   [3 8]     [1 9 2 8] #   [1 6] #   [9 1] # # 解の表示) #        [38 32 31 44] #        [29 75 31 76] #        [13 55 17 52] #        [64 18 47 44] 'A'([[5,3],[3,8],[1,6],[9,1]]). 'B'([[7,1,5,4],[1,9,2,8]]). A・Bの行列をA×Bの計算をして、その結果を表示する :- 'A'(_行列A), 'B'(_行列B), 行列の積(_行列A,_行列B,_行列C), 行列の表示(_行列C). % *** user: 行列の積 / 3 *** 行列の積(L1,L2,X) :- 行列の転置(L2,L4), 行列の積_1(L1,L4,X) . % *** user: 行列の積_1 / 3 *** 行列の積_1([],_,[]) :- !. 行列の積_1([A|R1],L,[S1|R3]) :- 行列の積_2(A,L,S1), 行列の積_1(R1,L,R3). % *** user: 行列の積_2 / 3 *** 行列の積_2(_,[],[]) :- !. 行列の積_2(A,[B|R2],[C|R3]) :- 行列の積_3(A,B,C), 行列の積_2(A,R2,R3). % *** user: 行列の積_3 / 3 *** 行列の積_3([],[],0) :- !. 行列の積_3([A|R1],[B|R2],S) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2. % *** user: 行列の転置 / 3 *** 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3). % *** user: 行列の転置 / 2 *** 行列の転置([[]|_],[]) :- !. 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2), 行列の転置(R2,R1),!. 行列の表示(_行列) :- member(_行,_行列), concat_atom(_行,' ',S), write_formatted('[%t]\n',[S]), fail. 行列の表示(_). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1258158172/339 # # [1] 授業単元: プログラミング # [2] 問題文(含コード&リンク):5人の学生の3教科(国・数・英)の点数を # 読み込んで、2次元配列を用いて以下の条件を満たすプログラムを作成せよ。 # (1)科目別の最高点を求める。 # (2)各学年の3教科の平均を求める。 # これらを表にして表示する。 # '5人の学生の3教科(国・数・英)の点数を読み込んで、2次元配列を用いて、科目別最高点、3教科の平均を表示' :- findall(L,(for(1,N,5),get_line(Line),split(Line,[','],L)),_学生の得点ならび), 科目別最高点(_学年の得点ならび,[_国最高点,_数最高点,_英最高点]), write('科目別最高点,国,数,英\n'), write_formatted(',%t,%t,%t\n',[_国最高点,_数最高点,_英最高点]), どんな学年があるか(_学生の得点ならび,_学年ならび), write('学年別、科目別平均点\n'), member(_学年,_学年ならび), findavg([_国,_数,_英],member([_学年,_国,_数_英],_学年の得点ならび),[_国平均,_数平均,_英平均]), member([_学年,_国平均,_数平均,_英平均],_各学年の3教科の平均), write_formatted('%t,%t,%t,%t\n',[_学年,_国平均,_数平均,_英平均]), fail. '5人の学生の3教科(国・数・英)の点数を読み込んで、2次元配列を用いて、科目別最高点、3教科の平均を表示'. 科目別最高点(_学年の得点ならび,_科目別最高点) :- 行列の転置(_学年の得点ならび,[_|L1]), findall(Max,(member(L2,L1),max(L2,Max)),_科目別最高点). どんな学年があるか(_学生の得点ならび,_学年ならび) :- findall(_学年,member(_学年,_学年の得点ならび),L), sort(L,_学年ならび). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1258158172/339 # # [1] 授業単元: プログラミング # [2] 問題文(含コード&リンク):5人の学生の3教科(国・数・英)の点数を # 読み込んで、2次元配列を用いて以下の条件を満たすプログラムを作成せよ。 # (1)科目別の最高点を求める。 # (2)各学年の3教科の平均を求める。 # これらを表にして表示する。 # '5人の学生の3教科(国・数・英)の点数を読み込んで、2次元配列を用いて、科目別最高点、3教科の平均を表示' :- findall(L,(for(1,N,5),get_line(Line),split(Line,[','],L)),_学生の得点ならび), 科目別最高点(_学年の得点ならび,[_国最高点,_数最高点,_英最高点]), write('科目別最高点,国,数,英\n'), write_formatted(',%t,%t,%t\n',[_国最高点,_数最高点,_英最高点]), 各学年の3教科の合計(_学生の得点ならび,[],_各学年の3教科の合計), 各学年の3教科の平均(_各学年の3教科の合計,_各学年の3教科の平均), write('学年別、科目別平均点\n'), member([_学年,_国平均,_数平均,_英平均],_各学年の3教科の平均), write_formatted('%t,%t,%t,%t\n',[_学年,_国平均,_数平均,_英平均]), fail. '5人の学生の3教科(国・数・英)の点数を読み込んで、2次元配列を用いて、科目別最高点、3教科の平均を表示'. 科目別最高点(_学年の得点ならび,_科目別最高点) :- 行列の転置(_学年の得点ならび,[_|L1]), findall(Max,(member(L2,L1),max(L2,Max)),_科目別最高点). 各学年の3教科の合計([],X,X). 各学年の3教科の合計([[_学年,_国,_数,_英]|R1],Y,X) :- '3教科合計に加算'(_学年,_国,_数,_英,Y,Y2), 各学年の3教科の合計(R1,Y2,X). '3教科合計に加算'(_学年,_国,_数,_英,[],[[_学年,1,_国合計,_数合計,_英合計]]). '3教科合計に加算'(_学年,_国,_数,_英,[_学年,_人数,_国合計,_数合計,_英合計|R],[[_学年,_人数2,_国合計2,_数合計2,_英合計2]|R]) :- _国合計2 is _国 + _国合計, _数合計2 is _数 + _数合計, _英合計2 is _英 + _英合計, _人数2 is _人数 + 1,!. '3教科合計に加算'(_学年,_国,_数,_英,[L1|R1],[L1|R2]) :- '3教科合計に加算'(_学年,_国,_数,_英,R1,R2). 各学年の3教科の平均([],[]). 各学年の3教科の平均([[_学年,_人数,_国合計,_数合計,_英合計]|R1],[[_学年,_国平均,_数平均,_英平均]|R2]) :- _国平均 is _国合計 / _人数, _数平均 is _数合計 / _人数, _英平均 is _英合計 / _人数, 各学年の3教科の平均(R1,R2). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1255709298/833 # # [1] 授業単元: プログラミング実習 # [2] 問題文(含コード&リンク):http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10094.txt # 対称行列であるかどうかを調べるプログラムを作成せよ。 # 対称行列とは、行列Aの転置行列をA’とすると、A=A'が成り立つ行列のことである '対称行列であるかどうかを調べるプログラムを作成せよ。'(_対称行列) :- 対称行列(_対称行列). 対称行列(_対称行列) :- '対称行列とは、行列Aの転置行列をA’とすると、A=A’が成り立つ行列のことである'(_対称行列). '対称行列とは、行列Aの転置行列をA’とすると、A=A’が成り立つ行列のことである'(_対称行列) :- 行列の転置(_対称行列,_対称行列). 行列の転置([],[],[]) :- !. 行列の転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 行列の転置(R2,R3,R4). 行列の転置([[]|_],[]) :- !. 行列の転置(L,[L1|R2]) :- 行列の転置(L,L2,L1), 行列の転置(L2,R2). % 以下のサイトは :- op(700,xfx,は). % *** user: 'ABC分析パラメータ' / 3 *** 'ABC分析パラメータ'('A',0.0e+00,0.7). 'ABC分析パラメータ'('B',0.7,0.9). 'ABC分析パラメータ'('C',9.0,1.0). 'ABC分析'(X,A,B,C) :- '加算'(X,[_,S]), findall([U,L1],(append(L1,L2,X) , '加算'(L1,[_,D]) , U is D / S , U < 0.7),L), max(L,A), A = [W1,L3], append(L3,L4,X), findall([V,L5],(append(L5,L6,L4) , '加算'(L5,[_,E]) , V is E / S , V < 0.2),L7), max(L7,B), B = [W2,L8], append(L8,L9,L4), W3 is 1 - W1 - W2, C = [W3,L9], !. % *** user: 'ABC分析' / 7 *** 'ABC分析'(X,PerA,PerB,PerC,A,B,C) :- '加算'(X,[_,S]), 'ABC分析パラメータ'('A',Ap1,Ap2), 'ABC分析の二'(X,S,Ap1,Ap2,PerA,A), append(A,L2,X), 'ABC分析パラメータ'('B',Bp1,Bp2), 'ABC分析の二'(L2,S,0.0e+00,Bp2 - PerA,PerB,B), append(B,C,L2), PerC is 1 - PerA - PerB, !. % *** user: 'ABC分析の二' / 6 *** 'ABC分析の二'(L,S,Per1,Per2,PerX,X) :- findall([U,L1],(append(L1,_,L) , '加算'(L1,[_,D]) , U is D / S , U > Per1 , U =< Per2),L2), max(L2,Y), Y = [PerX,X], !. % *** user: '加算' / 2 *** '加算'(trunc(L),SL) :- '加算'(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL), !. '加算'('四捨五入'(L),SL) :- '加算'(L,SL2), findall(A,(member(B,SL2) , A 'は' '四捨五入'(B)),SL), !. '加算'('切捨て'(L),SL) :- '加算'(L,SL2), findall(A,(member(B,SL2) , A 'は' '切捨て'(B)),SL), !. '加算'('切り上げ'(L),SL) :- '加算'(L,SL2), findall(A,(member(B,SL2) , A 'は' '切り上げ'(B)),SL), !. '加算'([],L) :- var(L), L = 0.0e+00, !. '加算'([],L) :- \+(var(L)), '加算の変数に零をおく'(L), !. '加算'([L|R],SL) :- 'ならび'(L), m_trans([L|R],L1), '加算_2'(L1,SL), !. '加算'(X,S) :- '加算_1'(X,0.0e+00,S) . % *** user: ('は') / 2 *** _項 'は' (_ネットワーク :: _式) :- _ネットワーク :: _項 'は' _式, !. _評価項 'は' N : L :- M 'は' N, L1 'は' L, list_nth(M,L1,_評価項), !. _評価項 'は' prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail) . _評価値 'は' [X|{P}] :- findall(X,P,_評価値), !. _評価項 'は' ` _値 :- !, _評価項 = _値, !. _項 'は' _式 :- var(_式), _項 = _式, !. _項 'は' _式 :- error_protect('一時関数定義'(_式,_項),fail) . _項 'は' _式 :- atom(_式), member(_式,[minint,maxint,cputtime,time,csize,cused,dbsize,dbused,gsize,gused,noptrs,ptrsued,ssize,sused,tsize,tused]), !, _項 is _式, !. _項 'は' _式 :- '二項組込み関数'(_式), '二項組込み関数の評価'(_式,_項) . _項 'は' _式 :- '二項組込み関数'(_式), !, fail . _項 'は' _式 :- functor(_式,Functor,1), arg(1,_式,Arg), Y 'は' Arg, functor(_式_1,Functor,1), arg(1,_式_1,Y), member(Functor,[atom,real,integer,var,float,list]), !, error_protect(_式_1,fail), _項 = Y, !. _項 'は' _式 :- atom(_式), error_protect(get_global(_式,_項),fail), !. _項 'は' _式 :- real(_式), _項 = _式, !. _項 'は' _式 :- real(_式), !, fail . _項 'は' _式 :- list(_式), findall(X,(member(U,_式) , X 'は' U),_項) . _項 'は' _式 :- list(_式), !, fail . _項 'は' _erlang_module : _erlang関数 :- 'erlang関数評価'(_erlang_module : _erlang関数,_項), !. _項 'は' _式 :- '関数定義'(_式,_項), !. _項 'は' _式 :- functor(_式,_関数,_次数), function(_関数,_次数), findall(Arg,(for(1,N,_次数) , arg(N,_式,Arg)),L), '関数評価に於いて引数部分の関数評価'(L,L2), _式の二 =.. [_関数|L2], error_protect(_項 is _式の二,fail) . _項 'は' _評価関数 :- error_protect(_項 is _評価関数,fail), !. _評価項 'は' prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail), !. _項 'は' _評価項 :- '述語評価が可能'(_評価項,_関数,_次数,_次数足す一), _評価項 =.. _評価項の項分解ならび, findall(Arg,(for(1,N,_次数) , arg(N,_評価項,Arg)),L), '関数評価に於いて引数部分の関数評価'(L,L2), append(L2,[_],_変数を付加した引数ならび), _解付き評価項 =.. [_関数|_変数を付加した引数ならび], error_protect(_解付き評価項,fail), arg(_次数足す一,_解付き評価項,_項) . _項 'は' _評価項 :- \+('述語評価が可能'(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), error_protect(_評価項,fail), arg(Arg,_評価項,_項) . _項 'は' _評価項 :- \+('述語評価が可能'(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), \+(error_protect(_評価項,fail)), _評価項 = _項, !. _項 'は' _式 :- atomic(_式), \+('述語評価が可能'(_式,_関数,_次数,_次数足す一)), _項 = _式, !. % 以下のサイトは # 出典:: http://sum2cha.blogpico.com/archives/2017 レス番号606 # [1] 授業単元: プログラミング [2] 問題文(含コード&リンク): # 3.以下のプログラムを作成 # 3x3マスのマルバツゲームのボードを作成 # ○側と×側が交互に2次元座標上の位置を入力 # 入力後、毎回ボードを表示する # たて、よこ、斜めのいずれかに○か×が3つ並んだ # 時点でプログラムを終了 マルバツゲーム(L) :- length(L1,3), length(L2,3), length(L3,3), L = [L1,L2,L3], マルバツゲーム(まる,L). マルバツゲーム(_,L) :- 変数がない(L),!. マルバツゲーム(_,L) :- 三つならびがある(L),!. マルバツゲーム(まる,L) :- ランダムに着手する(まる,L), マルバツゲーム(ばつ,L). マルバツゲーム(ばつ,L) :- ランダムに着手する(ばつ,L), マルバツゲーム(まる,L). ランダムに着手する(_種類,L) :- A is random // 9, _行 is // 3, _列 is mod 3, 着手(_種類,_行,_列,L). ランダムに着手する(_種類,_行,_列) :- ランダムに着手する(_種類,_行,_列). 着手(_種類,_行,_列,L) :- list_nth(_行,L,L1), list_nth(_列,L1,X), var(X), _種類=X,!. 変数がない(L) :- flat(L,L1),member(A,L1),\+(var(A)),!,fail. 変数がない(_). 全てがまる([]) :- !. 全てがまる([A|R]) :- A==まる,全てがまる(R). 全てがばつ([]) :- !. 全てがばつ([A|R]) :- A==まる,全てがまる(R). 三つ並びがある(L) :- for(1,N,3),list_nth(N,L,L1),list_nth(N,L1,X),X==まる,!. 三つ並びがある(L) :- for(1,N,3),list_nth(N,L,L1),list_nth(N,L1,X),X==ばつ,!. 三つ並びがある(L) :- member([M,N],[[1,3],[2,2],[3,1]]),list_nth(M,L,L1),list_nth(N,L1,X),X==まる,!. 三つ並びがある(L) :- member([M,N],[[1,3],[2,2],[3,1]]),list_nth(M,L,L1),list_nth(N,L1,X),X==ばつ,!. 三つ並びがある(L) :- for(1,N,3),list_nth(N,L,L1),全てがまる(L1),!. 三つ並びがある(L) :- for(1,N,3),list_nth(N,L,L1),全てがばつ(L1),,!. 三つ並びがある(L) :- ならびの転置(L,L1),三つ並びがあるの二(L1). 三つ並びがあるの二(L) :- for(1,N,3),list_nth(N,L,L1),全てがまる(L1),!. 三つ並びがあるの二(L) :- for(1,N,3),list_nth(N,L,L1),全てがばつ(L1),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1255709298/55 # # [1] 授業単元:プログラム言語論 # [2] 問題文(含コード&リンク): # # 設問1.C言語、またはC++言語で、割り算を計算するdev(int x,int y)関数(*)を作成しなさい。 # ただし、不変表明(assert)を使って、0で除算を実行した場合にエラーを出力するようにすること。 # (*)関数devは、int型の返値を持ち、x/yを計算するものとする。 :- op(700,xfx,は). 関数定義(div(X,Y),Z) :- div(X,Y,Z). div(X,Y,Z) :- length(L1,X), length(L2,Y), div(L1,L2,DIV,MOD), length(DIV,Z). div(_,[],_,_) :- write('0除算エラー\n'),!. div(L1,L2,[_|D],MOD) :- append(L2,L3,L1), div(L3,L2,D,MOD). div(L1,L2,[],L1) :- \+(append(L2,L3,L1)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% findavg(_集約項,_項,_算術平均) :- findall(_集約項,_項,_値ならび), '加算'(_値ならび,_合計値), length(_値ならび,_ならびの長さ), _算術平均 is _合計値 / _ならびの長さ,!. 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), L = 0.0e+00,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 行列の転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S) . 加算_1([],S,S) :- !. 加算_1([A|R],Y,S) :- ならび(A), ならび(Y), !, ならび加算(A,Y,Z), 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,I), integer(I), Z is I + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,F), real(F), Z is F + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), 加算_1(R,Y,S),!. 加算_1([A|R],Y,S) :- A1 は A, Z is A1 + Y, 加算_1(R,Z,S). 加算_1(A,Y,S) :- とからりすと(A,L), !, 加算_1(L,Y,S) . 加算_2([],[]) :- !. 加算_2([L|R],[S|R2]) :- 加算(L,S), 加算_2(R,R2). 加算の変数に零をおく([]) :- !. 加算の変数に零をおく([A|R]) :- 変数(A), A = 0.0e+00, 加算の変数に零をおく(R),!. とからりすと(A,[A]) :- atomic(A),!. とからりすと(A と B,C) :- とからりすと(A,A1), とからりすと(B,B1), append(A1,B1,C). 変数(_変数) :- var(_変数). ならび([_|_]). _項 は (_ネットワーク :: _式) :- _ネットワーク :: _項 は _式, ! . _評価項 は N : L :- M は N, L1 は L, list_nth(M,L1,_評価項), ! . _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail) . _評価値 は [X|{P}] :- findall(X,P,_評価値), ! . _評価項 は ` _値 :- !, _評価項 = _値, ! . _項 は _式 :- var(_式), _項 = _式, ! . _項 は _式 :- error_protect(一時関数定義(_式,_項),fail) . _項 は _式 :- atom(_式), member(_式,[minint,maxint,cputtime,time,csize,cused,dbsize,dbused,gsize,gused,noptrs,ptrsued,ssize,sused,tsize,tused]), !, _項 is _式, ! . _項 は _式 :- 二項組込み関数(_式), 二項組込み関数の評価(_式,_項) . _項 は _式 :- 二項組込み関数(_式), !, fail . _項 は _式 :- functor(_式,Functor,1), arg(1,_式,Arg), Y は Arg, functor(_式_1,Functor,1), arg(1,_式_1,Y), member(Functor,[atom,real,integer,var,float,list]), !, error_protect(_式_1,fail), _項 = Y, ! . _項 は _式 :- atom(_式), error_protect(get_global(_式,_項),fail), ! . _項 は _式 :- real(_式), _項 = _式, ! . _項 は _式 :- real(_式), !, fail . _項 は _式 :- list(_式), findall(X,(member(U,_式) , X は U),_項) . _項 は _式 :- list(_式), !, fail. _項 は _erlang_module : _erlang関数 :- erlang関数評価(_erlang_module : _erlang関数,_項),!. _項 は _式 :- 関数定義(_式,_項),!. _項 は _式 :- functor(_式,_関数,_次数), function(_関数,_次数), findall(Arg,(for(1,N,_次数) , arg(N,_式,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), _式の二 =.. [_関数|L2], error_protect(_項 is _式の二,fail) . _項 は _評価関数 :- error_protect(_項 is _評価関数,fail),!. _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail),!. _項 は _評価項 :- 述語評価が可能(_評価項,_関数,_次数,_次数足す一), _評価項 =.. _評価項の項分解ならび, findall(Arg,(for(1,N,_次数) , arg(N,_評価項,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), append(L2,[_],_変数を付加した引数ならび), _解付き評価項 =.. [_関数|_変数を付加した引数ならび], error_protect(_解付き評価項,fail), arg(_次数足す一,_解付き評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), error_protect(_評価項,fail), arg(Arg,_評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), \+(error_protect(_評価項,fail)), _評価項 = _項,!. _項 は _式 :- atomic(_式), \+(述語評価が可能(_式,_関数,_次数,_次数足す一)), _項 = _式,!. 述語評価が可能(_評価項,_関数,_次数,_次数足す一) :- functor(_評価項,_関数,_次数), _次数足す一 is _次数 + 1, \+(predicate_type(_関数,_次数足す一,undefined)),!. 関数評価に於いて引数部分の関数評価([],[]). 関数評価に於いて引数部分の関数評価([L|R1],[L2|R2]) :- list(L), !, 関数評価に於いて引数部分の関数評価(L,L2), 関数評価に於いて引数部分の関数評価(R1,R2), ! . 関数評価に於いて引数部分の関数評価([F|R1],[F|R2]) :- \+(error_protect(F2 は F,fail)), !, 関数評価に於いて引数部分の関数評価(R1,R2) . 関数評価に於いて引数部分の関数評価([F|R1],[F2|R2]) :- error_protect(F2 は F,fail), 関数評価に於いて引数部分の関数評価(R1,R2) . erlang関数評価(os : cmd(Command),_項) :- erlang :: (os : cmd(Command) -> _項_1), _項 は string2atom(_項_1),!. erlang関数評価(_erlang_module : _erlang関数,_項) :- erlang :: (_erlang_module : _erlang関数 -> _項),!. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, number(_値の一), _値の二 は _項の二, number(_値の二), _値 is _値の一 + _値の二, !. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 + _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, list(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),LY), concat_list(LY,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atom(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),L), concat_atom(L,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 * _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(` _値,_値) :- !. 関数定義(@ _式,_値) :- _値 は _式,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _値の二 >= 0.0e+00, _四捨五入後の値 is floor(_値の二 + 0.5) * 1.0,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 is ceil(_値の二 - 0.5),!. 関数定義(切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二) * 1.0,!. 関数定義(切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二),!. 関数定義(十円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 10 + 0.5) * 10,!. 関数定義(十円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は trunc(_値の二 / 10) * 10,!. 関数定義(十円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 10) * 10,!. 関数定義(百円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 100 + 0.5) * 100,!. 関数定義(百円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 100) * 100,!. 関数定義(百円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二 / 100) * 100,!. 関数定義(整数化(_値),_整数化された値) :- _値の二 は _値, _整数化された値 is trunc(_値の二),!. 関数定義(char_code(_項),_値) :- ( atom(_項), atomic_length(_項,1), char_code(_項,_値) ; integer(_項), char_code(_値,_項) ; 複合項(_項), _項の一 は _項, _値 は char_code(_項の一) ), !. 関数定義($ _大域変数名,_値) :- atom(_大域変数名), get_global(_大域変数名,_値の一), _値 は _値の一,!. 関数定義(S,E) :- functor(S,select,1), to(S,E),!. 関数定義(setq(A,B),E) :- atom(A), B1 は B, set_global(A,B1), E = B1,!. 関数定義(++ A,X) :- A1 は A, list(A1), 加算(A1,X),!. 関数定義(A ++ B,X) :- C is B / A, X = A + C + B,!. 関数定義(car(A),E) :- A1 は A, A1 = [E|_],!. 関数定義(cdr(A),E) :- A1 は A, A1 = [_|E],!. 関数定義(cons(A,B),E) :- A1 は A, B1 は B, E = [A1|B1],!. 関数定義(length(A),E) :- A1 は A, list(A1), length(A1,E),!. 関数定義(decode(A,B,C,D),E) :- A1 は A, B1 は B, A1 = B1, E は C,!. 関数定義(decode(A,B,C,D),E) :- E は D,!. 関数定義(decompcons(A),E) :- A1 は A, decompcons(A1,E),!. 関数定義(substr(A,B,C),E) :- 関数定義(subatomic(A,B,C),E),!. 関数定義(subatomic(A,B,C),E) :- A1 は A, B1 は B, C1 は C, subatomic(A1,B1,C1,E),!. 関数定義(concat(A),E) :- A1 は A, concat(A1,E),!. 関数定義(concat(A,B),E) :- A1 は A, B1 は B, concat(A1,B1,E),!. 関数定義(append(A,B),E) :- A1 は A, B1 は B, append(A1,B1,E),!. 関数定義(reverse(A),E) :- A1 は A, reverse(A1,E),!. 関数定義(string2atom(A),E) :- A2 は A, flat(A2,B), atom_codes(E,B),!. 関数定義(P,E) :- functor(P,greatest,Arg), P =.. [greatest|L], findall(B,(member(A,L) , B は A),L2), max(L2,E),!. 関数定義(P,E) :- functor(P,least,Arg), P =.. [least|L], findall(B,(member(A,L) , B は A),L2), min(L2,E),!. 関数定義(cel(_列数,_行数,_行列),_解) :- _関数評価された行数 は _行数, _関数評価された列数 は _列数, list_nth(_関数評価された行数,_行列,_行), list_nth(_関数評価された列数,_行,_解),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1248012902/330 # # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 期限 】10月17日 # 【 Ver  】1.6.0_11 # # A= # {-7.29565,6.54738,4.07991} # {-5.58592,7.51773,-1.78163} # {9.22599,-3.26847,-3.03223} # {6.25081,-8.75345,-4.31528} # # 行列norm ||A||1、||A||∞を求めるプログラムを作成せよ # # # 参考になるかはわかりませんが、複素数ベクトル版の2-norm、∞-normを # 求めるプログラムはこれです # http://rg550.hp.infoseek.co.jp/cgi-bin/joyful/img/803.java norm(_行列,1,X) :- 行列の転置(_行列,_行列1), findmax(S,(member(L,_行列1),abs_sum(L,S)),X). norm(_行列,inf,X) :- findmax(S,(member(L,_行列),abs_sum(L,S)),X). norm(_行列,N,X) :- integer(N), findsum(S1,(member(L,_行列) , 'N乗_sum'(L,N,S1)),Y), X is Y ^ (1 / N). abs_sum([],0) :- !. abs_sum([A|R1],S) :- abs_sum(R1,S1), S is abs(A) + S1. 'N乗_sum'([],N,0) :- !. 'N乗_sum'([A|R1],N,S) :- 'N乗_sum'(R1,N,S1), S is A^N + S1. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1250204272/436 # # [1] 授業単元: C言語 # [2] 問題文(含コード&リンク): http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9949.txt # 1. double x[3],y[3](成分はscanf)の内積を求めるプログラム # 2. 数列an={1,2,4,8,16,・・・}(n=1,2,・・・,20)を求めて表示するプログラム # 3. 「正数を入力してください」と表示し、入力した数字nが素数かどうかを # 判断するプログラム 内積([],[],0). 内積([A|R1],[B|R2],X) :- 内積(R1,R2,Y), C is A * B, X is Y + C. '数列an={1,2,4,8,16,・・・}(n=1,2,・・・,20)を求めて表示する'(Max,X) :- findsum(Y,( between(1,Max,N), Y is 2 ^ N)), X). 素数かどうか判断する :- write('正数を入力してください : '), repeat, get_line(Line), atom_to_term(Line,N,_), integer(N), N > 0, 素数である(N),!. 素数である(N) :- N2 is N // 2, for(2,M,N2), 0 is N mod M, !, fail. 素数である(_). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % *** user: findsum / 3 *** findsum(_選択項,_項,_合計値) :- findall(_選択項,_項,_値ならび), '加算'(_値ならび,_合計値),!. % *** user: 加算 / 2 *** 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), L = 0.0e+00,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 行列の転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S). % *** user: 加算の変数に零をおく / 1 *** 加算の変数に零をおく([]) :- !. 加算の変数に零をおく([A|R]) :- 変数(A), A = 0.0e+00, 加算の変数に零をおく(R),!. % *** user: 加算_1 / 3 *** 加算_1([],S,S) :- !. 加算_1([A|R],Y,S) :- ならび(A), ならび(Y), !, ならび加算(A,Y,Z), 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,I), integer(I), Z is I + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,F), real(F), Z is F + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), 加算_1(R,Y,S),!. 加算_1([A|R],Y,S) :- A1 は A, Z is A1 + Y, 加算_1(R,Z,S). 加算_1(A,Y,S) :- とからりすと(A,L), !, 加算_1(L,Y,S). % *** user: 加算_2 / 2 *** 加算_2([],[]) :- !. 加算_2([L|R],[S|R2]) :- 加算(L,S), 加算_2(R,R2). % *** user: 行列の転置 / 3 *** 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3). % *** user: 行列の転置 / 2 *** 行列の転置([[]|_],[]) :- !. 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2), 行列の転置(R2,R1),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/291 # # [1] 授業単元:コンピュータリテラシー # [2] 問題文(含コード&リンク):問題文と参考は以下です #   http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9806.txt # ・試験の過程を記録 # 1,番号、得点を入力したあと平均点を計算 # 2,番号順と得点順に並べ替え(ifを使いどちらか選択できるようにする) # 3,番号、得点、平均との差を出力 # 以上のプログラムを作成 成績を記録する :- write('番号と得点をスペースで区切って一行で入力してください\n'), get_line(_行), 成績を記録する(_行). 成績を記録する(end_of_file) :- !. 成績を記録する(_行) :- split(_行,[' '],[_番号,_得点]), assertz(成績(_番号,_得点)), get_line(_次の行), 成績を記録する(_次の行). 平均点(_平均点) :- findavg(_得点,成績(_,_得点),_平均点). 番号順に並べ直し(_番号順成績ならび) :- findall([_番号,_得点],成績(_番号,_得点),_成績ならび), quicksort(_成績ならび,_番号順成績ならび). 得点順に並べ直し(_得点順成績ならび) :- findall([_得点,番号],成績(_番号,_得点),_得点・番号成績ならび), quicksort(_得点・番号成績ならび,_整列した得点・番号ならび), 項目位置を元に戻す(_整列した得点・番号ならび,_得点順成績ならび). 項目位置を元に戻す([],[]). 項目位置を元に戻す([[A,B]|R1],[[B,A]|R2]) :- 項目位置を元に戻す(R1,R2). 番号、得点、平均との差の出力 :- 平均点(_平均点), write('番号 得点 平均との差\n'), 成績(_番号,_得点), _平均との差 is _得点 - _平均点, write_formatted('%t %t %t\n',[_番号,_得点,_平均との差]), fail. 番号、得点、平均との差の出力. quicksort([],[]) :- !. quicksort([X|Xs],Ys) :- partition(Xs,X,Littles,Gigs), quicksort(Littles,Ls), quicksort(Bigs,Bs), append(Ls,[X|Bs],Ys). partition([],Y,[],[]) :- !. partition([X|Xs],Y,[X|Ls],Bs) :- X @=< Y,partition(Xs,Y,Ls,Bs). partition([X|Xs],Y,Ls,[X|Bs]) :- X @> Y,partition(Xs,Y,Ls,Bs). %%%%%%%% findavg/3 加算/2 他 %%%%%%%%%%%%%%%%%%%% :- op(A,B,は). findavg(_集約項,_項,_算術平均) :- findall(_集約項,_項,_値ならび), '加算'(_値ならび,_合計値), length(_値ならび,_ならびの長さ), _算術平均 is _合計値 / _ならびの長さ,!. 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), L = 0.0e+00,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 行列の転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S) . 加算_1([],S,S) :- !. 加算_1([A|R],Y,S) :- ならび(A), ならび(Y), !, ならび加算(A,Y,Z), 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,I), integer(I), Z is I + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,F), real(F), Z is F + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), 加算_1(R,Y,S),!. 加算_1([A|R],Y,S) :- A1 は A, Z is A1 + Y, 加算_1(R,Z,S). 加算_1(A,Y,S) :- とからりすと(A,L), !, 加算_1(L,Y,S) . 加算_2([],[]) :- !. 加算_2([L|R],[S|R2]) :- 加算(L,S), 加算_2(R,R2). 加算の変数に零をおく([]) :- !. 加算の変数に零をおく([A|R]) :- 変数(A), A = 0.0e+00, 加算の変数に零をおく(R),!. とからりすと(A,[A]) :- atomic(A),!. とからりすと(A と B,C) :- とからりすと(A,A1), とからりすと(B,B1), append(A1,B1,C). 変数(_変数) :- var(_変数). ならび([_|_]). _項 は (_ネットワーク :: _式) :- _ネットワーク :: _項 は _式, ! . _評価項 は N : L :- M は N, L1 は L, list_nth(M,L1,_評価項), ! . _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail) . _評価値 は [X|{P}] :- findall(X,P,_評価値), ! . _評価項 は ` _値 :- !, _評価項 = _値, ! . _項 は _式 :- var(_式), _項 = _式, ! . _項 は _式 :- error_protect(一時関数定義(_式,_項),fail) . _項 は _式 :- atom(_式), member(_式,[minint,maxint,cputtime,time,csize,cused,dbsize,dbused,gsize,gused,noptrs,ptrsued,ssize,sused,tsize,tused]), !, _項 is _式, ! . _項 は _式 :- 二項組込み関数(_式), 二項組込み関数の評価(_式,_項) . _項 は _式 :- 二項組込み関数(_式), !, fail . _項 は _式 :- functor(_式,Functor,1), arg(1,_式,Arg), Y は Arg, functor(_式_1,Functor,1), arg(1,_式_1,Y), member(Functor,[atom,real,integer,var,float,list]), !, error_protect(_式_1,fail), _項 = Y, ! . _項 は _式 :- atom(_式), error_protect(get_global(_式,_項),fail), ! . _項 は _式 :- real(_式), _項 = _式, ! . _項 は _式 :- real(_式), !, fail . _項 は _式 :- list(_式), findall(X,(member(U,_式) , X は U),_項) . _項 は _式 :- list(_式), !, fail. _項 は _erlang_module : _erlang関数 :- erlang関数評価(_erlang_module : _erlang関数,_項),!. _項 は _式 :- 関数定義(_式,_項),!. _項 は _式 :- functor(_式,_関数,_次数), function(_関数,_次数), findall(Arg,(for(1,N,_次数) , arg(N,_式,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), _式の二 =.. [_関数|L2], error_protect(_項 is _式の二,fail) . _項 は _評価関数 :- error_protect(_項 is _評価関数,fail),!. _評価項 は prolog(_評価項) :- functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), !, error_protect(_評価項,fail),!. _項 は _評価項 :- 述語評価が可能(_評価項,_関数,_次数,_次数足す一), _評価項 =.. _評価項の項分解ならび, findall(Arg,(for(1,N,_次数) , arg(N,_評価項,Arg)),L), 関数評価に於いて引数部分の関数評価(L,L2), append(L2,[_],_変数を付加した引数ならび), _解付き評価項 =.. [_関数|_変数を付加した引数ならび], error_protect(_解付き評価項,fail), arg(_次数足す一,_解付き評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), error_protect(_評価項,fail), arg(Arg,_評価項,_項) . _項 は _評価項 :- \+(述語評価が可能(_評価項,_関数,_次数,_次数足す一)), functor(_評価項,F,Arg), \+(predicate_type(F,Arg,undefined)), \+(error_protect(_評価項,fail)), _評価項 = _項,!. _項 は _式 :- atomic(_式), \+(述語評価が可能(_式,_関数,_次数,_次数足す一)), _項 = _式,!. 述語評価が可能(_評価項,_関数,_次数,_次数足す一) :- functor(_評価項,_関数,_次数), _次数足す一 is _次数 + 1, \+(predicate_type(_関数,_次数足す一,undefined)),!. 関数評価に於いて引数部分の関数評価([],[]). 関数評価に於いて引数部分の関数評価([L|R1],[L2|R2]) :- list(L), !, 関数評価に於いて引数部分の関数評価(L,L2), 関数評価に於いて引数部分の関数評価(R1,R2), ! . 関数評価に於いて引数部分の関数評価([F|R1],[F|R2]) :- \+(error_protect(F2 は F,fail)), !, 関数評価に於いて引数部分の関数評価(R1,R2) . 関数評価に於いて引数部分の関数評価([F|R1],[F2|R2]) :- error_protect(F2 は F,fail), 関数評価に於いて引数部分の関数評価(R1,R2) . erlang関数評価(os : cmd(Command),_項) :- erlang :: (os : cmd(Command) -> _項_1), _項 は string2atom(_項_1),!. erlang関数評価(_erlang_module : _erlang関数,_項) :- erlang :: (_erlang_module : _erlang関数 -> _項),!. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, number(_値の一), _値の二 は _項の二, number(_値の二), _値 is _値の一 + _値の二, !. 関数定義(_項の一 + _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 + _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, list(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),LY), concat_list(LY,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atom(_値の一), _値の二 は _項の二, integer(_値の二), findall(_値の一,for(1,_,_値の二),L), concat_atom(L,_値), !. 関数定義(_項の一 * _項の二,_値) :- _値の一 は _項の一, atomic(_値の一), _値の二 は _項の二, atomic(_値の二), concat_atom([_値の一,_値の二],_値), !. 関数定義(_ならびの一 * _ならびの二,_値) :- ( 変数(_ならびの一) ; _ならびの一 == [] ; list(_ならびの一) ; 変数(_ならびの二) ; _ならびの二 == [] ; list(_ならびの二) ), !, append(_ならびの一,_ならびの二,_値) . 関数定義(` _値,_値) :- !. 関数定義(@ _式,_値) :- _値 は _式,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _値の二 >= 0.0e+00, _四捨五入後の値 is floor(_値の二 + 0.5) * 1.0,!. 関数定義(四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 is ceil(_値の二 - 0.5),!. 関数定義(切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二) * 1.0,!. 関数定義(切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二),!. 関数定義(十円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 10 + 0.5) * 10,!. 関数定義(十円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は trunc(_値の二 / 10) * 10,!. 関数定義(十円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 10) * 10,!. 関数定義(百円未満四捨五入(_値),_四捨五入後の値) :- _値の二 は _値, _四捨五入後の値 は floor(_値の二 / 100 + 0.5) * 100,!. 関数定義(百円未満切り上げ(_値),_切り上げ後の値) :- _値の二 は _値, _切り上げ後の値 は ceil(_値の二 / 100) * 100,!. 関数定義(百円未満切り捨て(_値),_切り捨て後の値) :- _値の二 は _値, _切り捨て後の値 は floor(_値の二 / 100) * 100,!. 関数定義(整数化(_値),_整数化された値) :- _値の二 は _値, _整数化された値 is trunc(_値の二),!. 関数定義(char_code(_項),_値) :- ( atom(_項), atomic_length(_項,1), char_code(_項,_値) ; integer(_項), char_code(_値,_項) ; 複合項(_項), _項の一 は _項, _値 は char_code(_項の一) ), !. 関数定義($ _大域変数名,_値) :- atom(_大域変数名), get_global(_大域変数名,_値の一), _値 は _値の一,!. 関数定義(S,E) :- functor(S,select,1), to(S,E),!. 関数定義(setq(A,B),E) :- atom(A), B1 は B, set_global(A,B1), E = B1,!. 関数定義(++ A,X) :- A1 は A, list(A1), 加算(A1,X),!. 関数定義(A ++ B,X) :- C is B / A, X = A + C + B,!. 関数定義(car(A),E) :- A1 は A, A1 = [E|_],!. 関数定義(cdr(A),E) :- A1 は A, A1 = [_|E],!. 関数定義(cons(A,B),E) :- A1 は A, B1 は B, E = [A1|B1],!. 関数定義(length(A),E) :- A1 は A, list(A1), length(A1,E),!. 関数定義(decode(A,B,C,D),E) :- A1 は A, B1 は B, A1 = B1, E は C,!. 関数定義(decode(A,B,C,D),E) :- E は D,!. 関数定義(decompcons(A),E) :- A1 は A, decompcons(A1,E),!. 関数定義(substr(A,B,C),E) :- 関数定義(subatomic(A,B,C),E),!. 関数定義(subatomic(A,B,C),E) :- A1 は A, B1 は B, C1 は C, subatomic(A1,B1,C1,E),!. 関数定義(concat(A),E) :- A1 は A, concat(A1,E),!. 関数定義(concat(A,B),E) :- A1 は A, B1 は B, concat(A1,B1,E),!. 関数定義(append(A,B),E) :- A1 は A, B1 は B, append(A1,B1,E),!. 関数定義(reverse(A),E) :- A1 は A, reverse(A1,E),!. 関数定義(string2atom(A),E) :- A2 は A, flat(A2,B), atom_codes(E,B),!. 関数定義(P,E) :- functor(P,greatest,Arg), P =.. [greatest|L], findall(B,(member(A,L) , B は A),L2), max(L2,E),!. 関数定義(P,E) :- functor(P,least,Arg), P =.. [least|L], findall(B,(member(A,L) , B は A),L2), min(L2,E),!. 関数定義(cel(_列数,_行数,_行列),_解) :- _関数評価された行数 は _行数, _関数評価された列数 は _列数, list_nth(_関数評価された行数,_行列,_行), list_nth(_関数評価された列数,_行,_解),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1247438792/157 # # [1] 授業単元: C++ # [2] 問題文(含コード&リンク): # http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9762.txt # # 正数による正方行列のうち、全ての行、列、斜め列の合計が同じであり、 # かつ2回以上使用される数字が存在しないものを魔方陣という。 # 下図に示すa,bに数値を設定したときに、1〜9の整数によって構成される魔方陣を # 出力するプログラムを作成せよ。 # 但し、魔方陣が作成不可能な(a,b)の組み合わせが設定された場合は、「Impossible」 # と出力するとする。 # # la_lb_l__l # l__l__l__l # l__l__l__l # 魔方陣(N枡,A,B,_行列) :- 魔方陣のための行列の生成(N枡,_行列), _行列 = [[A,B|_],_,_], 行の合計が全て一致する(_行列,S), 列の合計が全て一致する(_行列,S), 正方行列の斜め要素の合計が一致する(_行列,S). 魔方陣のための行列の生成(N枡,_行列) :- N2 is N枡 ^ 2, findall(M,for(1,M,N2),NL),!, 順列(NL,N2,_順列数字ならび), findall(_N個組,n個組(N枡,_順列数字ならび,_N個組),_行列). 行の合計が全て一致する([],S) :- !. 行の合計が全て一致する([_行|R],S) :- 魔方陣の加算(_行,0,S), 行の合計が全て一致する(R,S). 列の合計が全て一致する(_行列,S) :- 行列の転置(_行列,_転置行列), 列の合計が全て一致する(_転置行列,S),!. 正方行列の斜め要素の合計が一致する(_正方行列,S) :- length(_行列,Len), 左上から右下方向の合計(1,Len,_正方行列,0,S), 右上から左下方向の合計(1,Len,_正方行列,0,S),!. 左上から右下方向の合計(M,N,_,S,S) :- M > N,!. 左上から右下方向の合計(M,N,_行列,S1,S) :- list_nth(M,_行列,_行), list_nth(M,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 左上から右下方向の合計(M2,N,_行列,S2,S),!. 右上から左下方向の合計(M,N,_,S,S) :- M > N,!. 右上から左下方向の合計(M,N,_行列,S1,S) :- M1 is N - M + 1, list_nth(M1,_行列,_行), list_nth(M1,_行,_要素), S2 is _要素 + S1, M2 is M + 1, 右上から左下方向の合計(M2,N,_行列,S2,S),!. n個組(N,L,X) :- length(X,N), append(X,L2,L3), append(L1,L3,L), length(L1,Len), 0 is Len mod N. 魔方陣の加算([],X,X) :- !. 魔方陣の加算([A|R],Y,X) :- Z is A + Y, 魔方陣の加算(R,Z,X). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1232627790/958 # # 【 課題 】テキストファイルから文字列5行を読み込み、別のテキストへ縦書きで書き出す # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 期限 】7/14 am6:00 # 【 Ver  】Eclipse Version: 3.4.2 # 【 補足 】 # あいう # かきく # さしす # 上記のようなテキストファイルを読み込み、 # あかさ # いきし # うくす # のように別のテキストファイルに書き出す感じです。 'テキストファイルから文字列5行を読み込み、別のテキストへ縦書きで書き出す'(_テキストファイル,_別のテキストファイル) :- 'テキストファイルから文字列5行を読み込み、'(_テキストファイル,LL), '別のテキストへ縦書きで書き出す'(_別のテキストファイル,LL), 'テキストファイルから文字列5行を読み込み、'(_テキストファイル,_行文字ならびのならび) :- open(_テキストファイル,read,Instream), 文字列を5行読み込み(Instream,_行文字ならびのならび), close(Instream). 文字列を5行読み込み(Instream,_行文字ならびのならび) :- findall(_行文字ならび,( between(1,5,N), get_line(Instream,_行文字列), atom_chars(_行文字列,_行文字ならび)), _行文字ならびのならび). 別のテキストファイルへ縦書きで書き出す(_別のテキストファイル,_行文字ならびのならび) :- 別のテキストファイルへ(_別のテキストファイル,Outstream), 縦書きで(_行文字ならびのならび,_縦書き), 書き出す(Outstream,_縦書き). 別のテキストファイルへ(Outfile,Outstream) :- open(_別のテキストファイル,write,Outstream). 縦書きで(_行文字ならびのならび,_縦書き) :- 最長の行文字数(_行文字ならびのならび,_最長の行文字数), 空白文字を付加して行の文字数一致させる(_最長の行文字数,_行文字ならびのならび,_空白を付加し長さを揃えた行文字ならびのならび), 行列の転置(_空白を付加し長さを揃えた行文字ならびのならび,_縦書き). 最長の行文字数(_行文字ならびのならび,_最長の行文字数) :- findmax(_行の文字数,( member(_行文字ならび,_行文字ならびのならび), length(_行文字ならび,_行の文字数)), _最長の行文字数). 空白文字を付加して文字数を一致させる(_最長の行文字数,_行文字ならびのならび,_空白を付加し長さを揃えた行文字ならびのならび) :- findall(_空白を付加し長さを揃えた文字ならび,( member(_行文字ならび,_行文字ならびのならび), length(_空白を付加し長さを揃えた行文字ならび,_最長の行文字数), append(_行文字ならび,_空白を付加し長さを揃えた行文字ならび,_空白を付加し長さを揃えた行文字ならび), all(L2,' ')), _空白を付加し長さを揃えた行文字ならびのならび). 書き出す(Outstream,[]) :- close(Outstream). 書き出す(Outstream,[_行文字ならび|R]) :- atomic_list_concat(_行文字ならび,_行文字列), format(Outstream,'~w\n',[_行文字列]), 書き出す(Outstream,R). all([],_). all([V|R],V) :- all(R,V). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1232627790/958 # # 【 課題 】テキストファイルから文字列5行を読み込み、別のテキストへ右縦書きで書き出す # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 期限 】7/14 am6:00 # 【 Ver  】Eclipse Version: 3.4.2 # 【 補足 】 # あいう # かきく # さしす # 上記のようなテキストファイルを読み込み、 # さかあ # しきい # すくう # のように別のテキストファイルに書き出す感じです。 テキストファイルから文字列5行を読み込み、別のテキストへ右縦書きで書き出す(InFile,OutFile) :- open(InFile,read,Input), open(OutFile,write,Output), findall(Chars,(for(1,N,5),get_line(InFile,_行),atom_chars(_行,Chars)),LL), findmax(Len,length(Chars,Len),Max), 空白文字を付加して文字数一致させる(Max,LL,LL2), 行列の転置(LL2,LL3), 右書き用に反転して出力ファイルに書き出す(Output,LL3). 右書き用に反転して出力ファイルに書き出す(Output,[]) :- close(Output),!. 右書き用に反転して出力ファイルに書き出す(Output,[L|R]) :- reverse(L,L1), concat_atom(L1,S), write_formatted(Output,'%t\n',[S]), 右書き用に反転して出力ファイルに書き出す(Output,R). 空白文字を付加して文字数を一致させる(Max,LL1,LL2) :- findall(L,(member(L1,LL1),length(L,Max),append(L1,L2,L),all(L2,' ')),LL2). all([],_). all([V|R],V) :- all(R,V). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1232627790/958 # # 【 課題 】テキストファイルから文字列5行を読み込み、別のテキストへ縦書きで書き出す # 【 形態 】1. Javaアプリケーション(main()で開始) # 【 期限 】7/14 am6:00 # 【 Ver  】Eclipse Version: 3.4.2 # 【 補足 】 # あいう # かきく # さしす # 上記のようなテキストファイルを読み込み、 # あかさ # いきし # うくす # のように別のテキストファイルに書き出す感じです。 テキストファイルから文字列5行を読み込み、別のテキストへ縦書きで書き出す(InFile,OutFile) :- open(InFile,read,Input), open(OutFile,write,Output), findall(Chars,(for(1,N,5),get_line(InFile,_行),atom_chars(_行,Chars)),LL), max(Chars,Max), 空白文字を付加して文字数一致させる(Max,LL,LL2), 行列の転置(LL2,LL3), 出力ファイルに書き出す(Output,LL3). 出力ファイルに書き出す(Output,[]) :- close(Output),!. 出力ファイルに書き出す(Output,[L|R]) :- concat_atom(L,S), write_formatted(Output,'%t\n',[S]), 出力ファイルに書き出す(Output,R). 空白文字を付加して文字数を一致させる(Max,LL1,LL2) :- findall(L,(member(L1,LL1),length(L,Max),append(L1,L2,L),all(L2,' ')),LL2). all([],_). all([V|R],V) :- all(R,V). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1245853701/901 # # [1] 授業単元: C言語プログラミング演習 # [2] 問題文(含コード&リンク): プログラムを実行すると # 行列1: # 1,2,3 # 4,5,6 # 7,8,9 # 行列2: # 3,4,5 # 6,7,8 # 9,10,11 # と表示する。最後に行列1と行列2の積を計算し、以下のように表示 # するプログラム。 # [行列1と行列2の積は # ?,?,? # ?,?,? # ?,?,?] t432 :- _行列1 = [[1,2,3],[4,5,6],[7,8,9]], _行列2 = [[3,4,5],[6,7,8],[9,10,11]], write('行列1:\n'),行列表示(_行列1), write('行列2:\n'),行列表示(_行列2), 行列の積(_行列1,_行列2,_行列3), write('行列1と行列2の積は\n'),行列表示(_行列3). 行列表示([]). 行列表示([_行|R]) :- concat_atom(_行,',',[_表示文字列]),write_formatted('%t\n',[_表示文字列]),行列表示(R). 行列の積(L1,L2,X) :- 行列の転置(L2,L3),行列の積の一(L1,L3,X). 行列の積の一([],_,[]) :- !. 行列の積の一([A|R1],L,[S1|R3]) :- 行列の積の二(A,L,S1),行列の積の一(R1,L,R3). 行列の積の二(_,[],[]) :- !. 行列の積の二(A,[B|R2],[C|R3]) :- 行列の積の三(A,B,C),行列の積の二(A,R2,R3). 行列の積の三([],[],0) :- !. 行列の積の三([A|R1],[B|R2],S) :- S1 is A * B,行列の積の三(R1,R2,S2),S is S1 + S2 . 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3) . 行列の転置([[]|_],[]) :- !. 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2),行列の転置(R2,R1),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1245853701/822 # # 何人かの学生の3教科(数学、国語、英語)の得点を2次元配列を用いて # 処理するプログラムを作る。 # # (1)科目別の最高点、最低点を表示する。 # (2)各学生の3教科の平均点を表示する。 # (3)各教科の平均点を表示する。 # # ただし Ctrl+zが押されるまで次々と整数値を読み込んでいくものとする。 % テーマ findallを使った集約処理 '何人かの学生の3教科(数学、国語、英語)の得点を2次元配列を用いて 処理するプログラムを作る。 (1 )科目別の最高点、最低点を表示する。 (2)各学生の3教科の平均点を表示する。 (3)各教科の平均点を表示する。 ただし Ctrl+zが押されるまで次々と整数値を読み込んでいくものとする。' :- 'Ctrl+zが押されるまで次々と整数値を読み込んでいく'(_整数行列), '(1 )科目別の最高点、最低点を表示する。 '(_整数行列), '(2)各学生の3教科の平均点を表示する。 '(_整数行列), '(3)各教科の平均点を表示する。 '(_整数行列). 'Ctrl+zが押されるまで次々と整数値を読み込んでいく'(_整数行列) :- findall(_行,( get_split_line([','],_行)), _整数行列). '(1 )科目別の最高点、最低点を表示する。 '(_整数行列) :- 転置(_整数行列,[_学年ならび|LL]), forall(( nth1(_nth1,LL,L), 最高点と最低点を得る(L,_最高点,_最低点)), 表示する('科目番号:%t 最高点:%t 最低点:%t\n',[_nth1,_最高点,_最低点])). 最高点と最低点を得る([A|R],_最高点,_最低点) :- 最高点を得る(R,A,_最高点), 最低点を得る(R,A,_最低点). 最高点を得る([],_最高点,_最高点). 最高点を得る([N|R],_最高点_1,_最高点) :- N > _最高点_1, 最高点を得る(R,N,_最高点). 最高点を得る([N|R],_最高点_1,_最高点) :- N =< _最高点_1, 最高点を得る(R,_最高点_1,_最高点). 最低点を得る([],_最低点,_最低点). 最低点を得る([N|R],_最低点_1,_最低点) :- N < _最低点_1, 最低点を得る(R,N,_最低点). 最低点を得る([N|R],_最低点_1,_最低点) :- N >= _最低点_1, 最低点を得る(R,_最低点_1,_最低点). '(2)各学生の3教科の平均点を表示する。 '(_整数行列) :- forall(( nth1(_nth1,_整数行列,[_|R]), 相加平均(R,_相加平均)), writef('学生:%t 3教科の平均点:%t\n',[_nth1,_相加平均])). '(3)各教科の平均点を表示する。 '(_整数行列) :- 転置(_整数行列,[_学年ならび|LL]), forall(( nth1(_nth1,LL,L), 相加平均(L,_相加平均)), 表示する('科目番号:%t 平均点:%t\n',[_nth1,_相加平均])). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 相加平均(L,M) :- length(L,N), 相加平均(L,N,0,M). 相加平均([],N,S,M) :- M is S / N,!. 相加平均([A|R],N,S,M) :- S1 is S + A, 相加平均(R,N,S1,M). get_split_line(File,Splitter,List) :- get_split_lines(File,Splitter,Lines), member(List,Lines) . get_split_line(Splitters,List) :- get_line(Line), split(Line,Splitters,List). get_line(X) :- get_char(C), get_line_1(C,Chars), atom_chars(X,Chars). get_line_1('\n',[]) :- !. get_line_1('\z',[]) :- !. get_line_1(end_of_file,[]) :- !. get_line_1(C,[C|R]) :- get_char(C2), get_line_1(C2,R). split(_文字列,_区切り符号ならび,X) :- sPlit(_文字列,_区切り符号ならび,Y), findall(U,( member(U,Y), \+(U = '')), L), L = X,!. sPlit(_文字列,_区切り符号ならび,X) :- atom_chars(_文字列,L), split_00(L,_区切り符号ならび,Y), findall(U,( member(U,Y), \+(member(U,_区切り符号ならび))), Z), Z = X,!. split_00(_文字ならび,_区切り符号ならび,X) :- findall([B,A],( member(A,_区切り符号ならび), atom_chars(A,B)), _区切り符号ならびの二), split_0(_文字ならび,_区切り符号ならびの二,X). split_0(_文字ならび,_区切り符号ならび,['',_区切り符号,'']) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), _文字ならび = _区切り文字ならび,!. split_0(_文字ならび,_区切り符号ならび,['',_区切り符号|R2]) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), append(_区切り文字ならび,R,_文字ならび), split_1(R,_区切り符号ならび,R2),!. split_0(L,_区切り符号ならび,X) :- split_1(L,_区切り符号ならび,X). split_1([],_,[]) :- !. split_1(_文字ならび,_区切り符号ならび,['',_区切り符号,'']) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), _文字ならび = _区切り文字ならび,!. split_1(_文字ならび,_区切り符号ならび,['',_区切り符号_1,C,_区切り符号_2|X]) :- member([_区切り文字ならび,_区切り符号_1],_区切り符号ならび), append(_区切り文字ならび,R,_文字ならび), split_2(R,R2,_区切り符号_2,_区切り符号ならび,B), split_5(B,C), split_0(R2,_区切り符号ならび,X),!. split_1(_文字ならび,_区切り符号ならび,[C|X]) :- split_2(_文字ならび,R2,_区切り符号,_区切り符号ならび,B), _区切り符号 = '', split_5(B,C), split_0(R2,_区切り符号ならび,X),!. split_1(_文字ならび,_区切り符号ならび,[C,_区切り符号|X]) :- split_2(_文字ならび,R2,_区切り符号,_区切り符号ならび,B), \+(_区切り符号 = ''), split_5(B,C), split_0(R2,_区切り符号ならび,X),!. split_2([],[],'',_,[]) :- !. split_2(_文字ならび,R,_区切り符号,_区切り符号ならび,[]) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), append(_区切り文字ならび,R,_文字ならび),!. split_2([''''|R],R2,_区切り符号,_区切り符号ならび,X) :- split_3([''''|R],R2,_区切り符号,_区切り符号ならび,X),!. split_2(['"'|R],R2,_区切り符号,_区切り符号ならび,X) :- split_32(['"'|R],R2,_区切り符号,_区切り符号ならび,X),!. split_2([_文字|R],R2,_区切り符号,_区切り符号ならび,[_文字|X]) :- split_2(R,R2,_区切り符号,_区切り符号ならび,X),!. split_3(['''',''''|R],R2,_区切り符号,_区切り符号ならび,[''''|X]) :- split_4(R,R2,_区切り符号,_区切り符号ならび,X),!. split_3([_|R],R2,_区切り符号,_区切り符号ならび,X) :- split_4(R,R2,_区切り符号,_区切り符号ならび,X),!. split_4(['''',''''|R],R2,_区切り符号,_区切り符号ならび,[''''|X]) :- split_4(R,R2,_区切り符号,_区切り符号ならび,X),!. split_4([''''|R],R2,_区切り符号,_区切り符号ならび,X) :- split_2(R,R2,_区切り符号,_区切り符号ならび,X),!. split_4([],[],'',_,[]) :- !. split_4([_文字|R],R2,_区切り符号ならび,[_文字|X]) :- split_4(R,R2,_区切り符号,_区切り符号ならび,X),!. split_5([],'') :- !. split_5(B,C) :- numeric_list(B,Nl), number(C,Nl),!. split_5(B,C) :- atomic_list_concat(B,C),!. split_32(['"','"'|R],R2,_区切り符号,_区切り符号ならび,[''''|X]) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. split_32([_|R],R2,_区切り符号,_区切り符号ならび,X) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. split_42(['"','"'|R],R2,_区切り符号,_区切り符号ならび,['"'|X]) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. split_42(['"'|R],R2,_区切り符号,_区切り符号ならび,X) :- split_2(R,R2,_区切り符号,_区切り符号ならび,X),!. split_42([],[],'',_,[]) :- !. split_42([_文字|R],R2,_区切り符号ならび,[_文字|X]) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. numeric_list([],[]) :- !. numeric_list([A|R],[B|R1]) :- digit(A), char_code(A,B), numeric_list(R,R1),!. numeric_list(['.'|R],[46|R1]) :- numeric_list(R,R1),!. numeric_list([-|R],[45|R1]) :- numeric_list(R,R1),!. % 以下のサイトは # [1] 授業単元:情報処理 # [2] 問題文(含コード&リンク): # 例えば下図に示すように,通行可能なマス目に'0'が, # 障害物があって通行不能なマス目に'+'が記されている盤がある. # 盤の左上をスタート地点,右下をゴール地点として,経路を表示する # プログラムを作りなさい. # 盤の例 # 0 0 + 0 + # + 0 0 0 + # 0 + + 0 0 # 0 0 + 0 0 # + 0 0 0 0 # # 例えばこのようなアルゴリズムが考えられる. # # 1) 現在位置を表示の後、進行方向に対して,右に進めるなら右に, # そうでなければ直進,それもだめなら左に,さらにそれもダメなら後退する. # 2) 1を繰り返してゴールに達したらその旨を表示する. # ただし,マス目の数分だけ移動してもゴールに達しない場合はその時点で終了する. # # 入力形式は、 # # %> ./a.out 00+0+ +000+ 0++00 00+00 +0000 # # とする. t340(X) :- abolish(経路/2), write('盤面を一行で入力しなさい '), get_line(S), t340_1(S,_終点), 経路探索((1,1),_終点,[(1,1)],X). 経路探索(_終点,_終点,Log,Log) :- !. 経路探索(A,_終点,Log,X) :- 経路(A,B), not(member(B,Log)), 経路探索(B,_終点,[B|Log],X),!. 経路探索(A,_終点,Log,X) :- 経路(B,A), not(member(B,Log)), 経路探索(B,_終点,[B|Log],X),!. t340_1(S,(N,M)) :- split(S,[' '],L), findall(L1,(member(A,L),atom_chars(A,L1)),Ls), length(Ls,N), t340_2(1,Ls), 行列の転置(Ls,Ls2), length(Ls2,M), t340_3(1,Ls2),!. t340_2(_,[]) :- !. t340_2(N,[L|R]) :- t340_2_1(N,1,L), N2 is N + 1, t340_2(N2,R). t340_2_1(_,_,[_]) :- !. t340_2_1(N,M,['+'|R]) :- M2 is M + 1, t340_2_1(N,M2,R),!. t340_2_1(N,M,[A,B|R]) :- not(A='+'), not(B='+'), M2 is M + 1, assertz(経路((N,M),(N,M2))), t340_2_1(N,M2,[B|R]),!. t340_2_1(N,M,[A,B|R]) :- not(A='+'), B='+', M2 is M + 1, t340_2_1(N,M2,[B|R]),!. t340_3_1(_,_,[_]) :- !. t340_3_1(N,M,['+'|R]) :- M2 is M + 1, t340_3_1(N,M2,R),!. t340_3_1(N,M,[A,B|R]) :- not(A='+'), not(B='+'), M2 is M + 1, assertz(経路((M,N),(M2,N))), t340_3_1(N,M2,[B|R]),!. t340_3_1(N,M,[A,B|R]) :- not(A='+'), B='+', M2 is M + 1, t340_3_1(N,M2,[B|R]),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1245853701/ # # [1] 授業単元:C言語実習 # [2] 問題文(含コード&リンク):http://kansai2channeler.hp.infoseek.co.jp/cgi-bin /joyful/img/9658.txt # {5,21,4,14,12}, # {25,20,15,3,7}, # {24,11,6,1,13}, # {16,2,17,19,8}, # {23,18,22,9,10} # # の横の各行を小さい順に並び替えた後、縦の各列を小さい順に並び替え(上が小さくな るように) # 結果を出力 # # 結果は # # 5 21 4 14 12 # 25 20 15 3 7 # 24 11 6 1 13 # 16 2 17 19 8 # 23 18 22 9 10 # # のような形で出力 '横の各行を小さい順に並び替えた後、縦の各列を小さい順に並び替えて出力する'(_ファイル) :- 行列に入力する(_ファイル,_行列1), '横の各行を小さい順に並び替えた後、縦の各列を小さい順に並び替えてW得点データをバブルソートを用いて国語の得点の大きい順に並び替えよ出力する'(_行列1,_行列2), 出力する(_行列2),!. '横の各行を小さい順に並び替えた後、縦の各列を小さい順に並び替えて出力する'(_行列1,_行列2) :- 各行を整列する(_行列1,_行列3), 縦の各列を整列する(_行列3,_行列2). 行列に入力する(_ファイル,_行列) :- get_split_lines(_ファイル,['{',',','}'],_行列). 各行を整列する([],[]) :- !. 各行を整列する([_行|R1],[_整列された行|R2]) :- quicksort(_行,_整列された行), 各行を整列する(R1,R2). 縦の各列を整列する(_行列1,_行列2) :- 転置(_行列2,_行列3), 各行を整列する(_行列3,_行列4), 転置(_行列4,_行列2). 出力する(_行列2) :- append(L0,[L|R],_行列2), concat_atom(L,' ',S), writef('%t\n',[S]), R = []. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% get_split_lines(File,Sep,Lines) :- get_lines(File,Lines1), findall(Line,(member(A,Lines1) , split(A,Sep,Line)),Lines) . get_lines(File,Lines) :- get_chars(File,L), chars_lines(L,Lines),!. get_lines(Lines) :- findall(Line,( repeat , get_line(Line) , (Line = end_of_file , (!) , fail ; true)), Lines). get_chars(File,L) :- \+(is_stream(_,File,_)), exists(File,read), open(File,read,Input), get_char(Input,X), get_chars(Input,X,L), close(Input),!. get_chars(Input,L) :- is_stream(_,Input,_), get_char(Input,X), get_chars(Input,X,L),!. get_line(Instream,X) :- get_char(Instream,C), get_line_3(Instream,C,Chars), atom_chars(X,Chars),!. get_line(X) :- get_char(C), get_line_1(C,Chars), atom_chars(X,Chars). get_line_1('\n',[]) :- !. get_line_1(end_of_file,[]) :- !. get_line_1(C,[C|R]) :- get_char(C2), get_line_1(C2,R). get_line_3(_,'連続','\n',[]) :- !. get_line_3(Instream,_診断,'\r',X) :- get_char(Instream,C2), get_line_3_2(Instream,_診断,C2,X),!. get_line_3(Instream,'終了',end_of_file,[]) :- !. get_line_3(Instream,_診断,C,[C|R]) :- get_char(Instream,C2), get_line_3(Instream,_診断,C2,R). get_line_3(_,'\n',[]) :- !. get_line_3(Instream,end_of_file,[]) :- !. get_line_3(Instream,C,[C|R]) :- get_char(Instream,C2), get_line_3(Instream,C2,R). get_chars(L) :- findall(U,( repeat , get_char(U) , (U = end_of_file , (!) , fail ; true)), L). get_line(Instream,_診断,X) :- get_char(Instream,C), get_line_3(Instream,_診断,C,Chars), atom_chars(X,Chars),!. get_line(Instream,X) :- get_char(Instream,C), get_line_3(Instream,C,Chars), atom_chars(X,Chars),!. get_line(X) :- get_char(C), get_line_1(C,Chars), atom_chars(X,Chars). get_line_1('\n',[]) :- !. get_line_1(end_of_file,[]) :- !. get_line_1(C,[C|R]) :- get_char(C2), get_line_1(C2,R). get_line_3(_,'連続','\n',[]) :- !. get_line_3(Instream,_診断,'\r',X) :- get_char(Instream,C2), get_line_3_2(Instream,_診断,C2,X),!. get_line_3(Instream,'終了',end_of_file,[]) :- !. get_line_3(Instream,_診断,C,[C|R]) :- get_char(Instream,C2), get_line_3(Instream,_診断,C2,R). get_line_3(_,'\n',[]) :- !. get_line_3(Instream,end_of_file,[]) :- !. get_line_3(Instream,C,[C|R]) :- get_char(Instream,C2), get_line_3(Instream,C2,R). get_line_3_2(Instream,'連続','\n',[]) :- !. get_line_3_2(Instream,'連続',C,['\r'|R]) :- \+(C == '\n'), get_line_3(Instream,_診断,C,R),!. split(_文字列,_区切り符号ならび,X) :- sPlit(_文字列,_区切り符号ならび,Y), findall(U,(member(U,Y) , not U = ''),L), L = X,!. sPlit(_文字列,_区切り符号ならび,X) :- atom_chars(_文字列,L), split_00(L,_区切り符号ならび,Y), findall(U,(member(U,Y) , \+(member(U,_区切り符号ならび))),Z), Z = X,!. split_00(_文字ならび,_区切り符号ならび,X) :- findall([B,A],( member(A,_区切り符号ならび) , atom_chars(A,B)), _区切り符号ならびの二), split_0(_文字ならび,_区切り符号ならびの二,X). split_0(_文字ならび,_区切り符号ならび,['',_区切り符号,'']) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), _文字ならび = _区切り文字ならび,!. split_0(_文字ならび,_区切り符号ならび,['',_区切り符号|R2]) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), append(_区切り文字ならび,R,_文字ならび), split_1(R,_区切り符号ならび,R2),!. split_0(L,_区切り符号ならび,X) :- split_1(L,_区切り符号ならび,X). split_1([],_,[]) :- !. split_1(_文字ならび,_区切り符号ならび,['',_区切り符号,'']) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), _文字ならび = _区切り文字ならび,!. split_1(_文字ならび,_区切り符号ならび,['',_区切り符号_1,C,_区切り符号_2|X]) :- member([_区切り文字ならび,_区切り符号_1],_区切り符号ならび), append(_区切り文字ならび,R,_文字ならび), split_2(R,R2,_区切り符号_2,_区切り符号ならび,B), split_5(B,C), split_0(R2,_区切り符号ならび,X),!. split_1(_文字ならび,_区切り符号ならび,[C|X]) :- split_2(_文字ならび,R2,_区切り符号,_区切り符号ならび,B), _区切り符号 = '', split_5(B,C), split_0(R2,_区切り符号ならび,X),!. split_1(_文字ならび,_区切り符号ならび,[C,_区切り符号|X]) :- split_2(_文字ならび,R2,_区切り符号,_区切り符号ならび,B), \+(_区切り符号 = ''), split_5(B,C), split_0(R2,_区切り符号ならび,X),!. split_2([],[],'',_,[]) :-!. split_2(_文字ならび,R,_区切り符号,_区切り符号ならび,[]) :- member([_区切り文字ならび,_区切り符号],_区切り符号ならび), append(_区切り文字ならび,R,_文字ならび),!. split_2([''''|R],R2,_区切り符号,_区切り符号ならび,X) :- split_3([''''|R],R2,_区切り符号,_区切り符号ならび,X),!. split_2(['"'|R],R2,_区切り符号,_区切り符号ならび,X) :- split_32(['"'|R],R2,_区切り符号,_区切り符号ならび,X),!. split_2([_文字|R],R2,_区切り符号,_区切り符号ならび,[_文字|X]) :- split_2(R,R2,_区切り符号,_区切り符号ならび,X),!. split_5([],'') :- !. split_5(B,C) :- numeric_list(B,Nl), number(C,Nl),!. split_5(B,C) :- concat_atom(B,C),!. split_32(['"','"'|R],R2,_区切り符号,_区切り符号ならび,[''''|X]) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. split_32([_|R],R2,_区切り符号,_区切り符号ならび,X) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. split_42(['"','"'|R],R2,_区切り符号,_区切り符号ならび,['"'|X]) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. split_42(['"'|R],R2,_区切り符号,_区切り符号ならび,X) :- split_2(R,R2,_区切り符号,_区切り符号ならび,X),!. split_42([],[],'',_,[]) :- !. split_42([_文字|R],R2,_区切り符号ならび,[_文字|X]) :- split_42(R,R2,_区切り符号,_区切り符号ならび,X),!. number(A,B) :- number_codes(A,B). numeric_list([],[]) :-!. numeric_list([A|R],[B|R1]) :- digit(A), char_code(A,B), numeric_list(R,R1),!. numeric_list(['.'|R],[46|R1]) :- numeric_list(R,R1),!. numeric_list([-|R],[45|R1]) :- numeric_list(R,R1),!. 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). % *** user: quicksort / 2 *** quicksort([X|Xs],Ys) :- partition(Xs,X,Littles,Bigs), quicksort(Littles,Ls), quicksort(Bigs,Bs), append(Ls,[X|Bs],Ys). quicksort([],[]). partition([X|Xs],Y,[X|Ls],Bs) :- X @=< Y, partition(Xs,Y,Ls,Bs). partition([X|Xs],Y,Ls,[X|Bs]) :- X @> Y, partition(Xs,Y,Ls,Bs). partition([],Y,[],[]). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1244449887/674 # # [1] 授業単元:プログラム # [2] 4*3行列Aと 3*5行列B の各要素をキーボードから入力し、 # C = A*B を計算し、表示するプログラムを作成せよ。 行列の積(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) :- S1 is A * B, 行列の積_3(R1,R2,S2), S is S1 + S2 . 行列の転置([],[],[]) :- ! . 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3) . 行列の転置([[]|_],[]) :- ! . 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2), 行列の転置(R2,R1), ! . % 以下のサイトは % 項を副目標として、選択項を収集しその相加平均を取る。 findavg(_集約項,_項,_相加平均ならび) :- list(_集約項), findall(_集約項,_項,_値ならび), 加算(_値ならび,_合計値ならび), length(_値ならび,_ならびの長さ), findall(_相加平均,( member(_合計値,_合計値ならび), _相加平均 is _合計値 / _ならびの長さ), _相加平均ならび),!. findavg(_集約項,_項,_相加平均) :- findall(_集約項,_項,_値ならび), 加算(_値ならび,_合計値), length(_値ならび,_ならびの長さ), _相加平均 is _合計値 / _ならびの長さ,!. 加算([L1|R1],L2) :- list(L1), 転置([L1|R1],L3), 転置されたならびの加算(L3,L2),!. 加算(L1,X) :- sum(L1,X). sum([],0). sum([V|R],Sum) :- sum(R,Sum2), Sum is V + Sum2. 転置されたならびの加算([],[]). 転置されたならびの加算([L1|R1],[S|R2]) :- sum(L1,S), 転置されたならびの加算(R1,R2). % 以下のサイトは % 項を副目標として、選択項を収集しその合計を取る。 findsum(_選択項,_項,_合計値) :- findall(_選択項,_項,_値ならび), 加算(_値ならび,_合計値),!. 加算([L1|R1],L2) :- list(L1), 転置([L1|R1],L3), 転置されたならびの加算(L3,L2),!. 加算(L1,X) :- sum_list(L1,X). 転置されたならびの加算([],[]). 転置されたならびの加算([L1|R1],[S|R2]) :- sum_list(L1,S), 転置されたならびの加算(R1,R2). 転置([],[],[]) :- !. 転置([[A|R1]|R2],[R1|R3],[A|R4]) :- 転置(R2,R3,R4). 転置([[]|_],[]) :- !. 転置(L,[L1|R2]) :- 転置(L,L2,L1), 転置(L2,R2). '文字列を入力し、その文字列に含まれる英字、数字、その他の文字の数を出力せよ。' :- get_line(_文字列), findsum([A,B,C],( sub_atom(_文字列,_,1,_,_文字), 文字種判定(_文字,A,B,C)),[_英字の数,_数字の数,_その他の文字の数]), writef('英字の数は %t,数字の数は %t,その他の文字の数は %t\n',[_英字の数,_数字の数,_その他の文字の数]). 文字種判定(_文字,1,0,0) :- 英字(_文字),!. 文字種判定(_文字,0,1,0) :- 数字(_文字),!. 文字種判定(_文字,0,0,1). 英字(A) :- A @>='A',A @=< 'Z'; A @>='a',A @=< 'z'. 数字(A) :- A @>= '0', A @=< '9'. % 転置/2