※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

「prolog勉強プロジェクトオイラー21~30」の編集履歴(バックアップ)一覧に戻る

prolog勉強プロジェクトオイラー21~30 - (2013/07/17 (水) 20:44:23) の編集履歴(バックアップ)


プロジェクトオイラーの問題をPrologで解くページ。
創価学会の皆さまから小学校の算数までしかできないと言われている堀江伸一さんがこのページのコードを書いているようです。


独り言
今日見つけたもの。
今日はリンク先質問には答えたけどこういう子どもには何と答えればよいのだろう、こういう子どもをきちんと教育するのは大人なら誰にでも責任があるものだとは思うけど?
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12110042462



問い21

http://projecteuler.net/problem=21
10000以下の友愛数の和を求めよという問題。
そのまま定義通り計算するだけです。
複数の関数で一つの関数を表現するPrologて独特。

yakusuu_sum(1,_,1,Sum,Sum):-!.
yakusuu_sum(N,M,1,Sum,Sum1):-N<M*M,!,Sum1 is Sum*(N+1).
yakusuu_sum(N,M,Multi,Sum,Result):-
0=:=N mod M,!,
N1 is N//M,
Multi1 is Multi*M+1,
yakusuu_sum(N1,M,Multi1,Sum,Result).
yakusuu_sum(N,M,Multi,Sum,Result):-
Sum1 is Sum*Multi,
M1 is M+1,
yakusuu_sum(N,M1,1,Sum1,Result).
yakusuu_sum_w(N,Result):- 
yakusuu_sum(N,2,1,1,Result).

check(N):-yakusuu_sum_w(N,N1),N2 is N1-N,N\==N2,yakusuu_sum_w(N2,N3),
        N4 is N3-N2,N=:=N4.
calc(N):-
	between(2,10000,N),check(N).
sum([],Sum,Sum):-!.
sum([X|Rest],Sum,Result):-Sum1 is Sum+X,sum(Rest,Sum1,Result).

main21:-findall(N,calc(N),List),sum(List,0,Ans),write(Ans).




プロジェクトオイラー問い22 Names scores

Prologの徹底ぶりを思い知った問題。
まさかファイル読み込み関数までバックトラックの対象だとは思わず、他の言語と同じノリで一回読んだらそれで終わり的な発想でコードを書いてすこしだけはまった。
気がついて慌てて修正。
このコードは正しいのだろうか?
一応末尾再帰で再帰の深さを回避はしてるつもり。
findallを使う方が正しくないだろうか?


last(-1).
spliter(34).

read_name(Names,Name):-
get0(C),
(spliter(C)->
       reverse(Name,Name1),karayomi_read([Name1|Names]);
C1 is C-"A"+1,
read_name(Names,[C1|Name])).

karayomi_read(Names):-get0(C),karayomi(Names,C).
karayomi(Names,C):-last(C),!,calc(Names).
karayomi(Names,C):-spliter(C),!,read_name(Names,[]).
karayomi(Names,_):-karayomi_read(Names).


sum_score([],Sum,Sum).
sum_score([X|Rest],Sum,Result):-Sum1 is Sum+X,sum_score(Rest,Sum1,Result).

score_calc([],_,Score,Score).
score_calc([Name|Rest],N,Score,Result):-sum_score(Name,0,S),Score1 is Score+N*S,
N1 is N+1,
score_calc(Rest,N1,Score1,Result).


calc(Names):-seen,sort(Names,Names1),
score_calc(Names1,1,0,Ans),write(Ans).

main22:-seen,see('e22.txt'),karayomi_read([]).