「プロジェクトオイラー問1」の編集履歴(バックアップ)一覧に戻る

プロジェクトオイラー問1 - (2014/02/12 (水) 08:04:14) のソース

*Problem 1 「3と5の倍数」 †

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%201


10未満の自然数のうち, 3 もしくは 5 の倍数になっているものは 3, 5, 6, 9 の4つがあり, これらの合計は 23 になる.
同じようにして, 1000 未満の 3 か 5 の倍数になっている数字の合計を求めよ.



*解法
条件を満たす数のリストを得てそれを集計する方法。
 okNum(N):-N mod 3=:=0,!.
 okNum(N):-N mod 5=:=0,!.
 numListCreate(N):-
 	between(1,999,N),
 	okNum(N).
 
 sum([],0):-!.
 sum([X|Xs],Result):-sum(Xs,Re),Result is Re+X.
 
 main1A:-findall(N,numListCreate(N),NumList),
 	sum(NumList,Ans),
 	write(Ans).


再帰を使った解法
 okNum(N,N):-N mod 3=:=0,!.
 okNum(N,N):-N mod 5=:=0,!.
 okNum(_,0):-!.
 
 saiki(1000,Sum,Sum):-!.
 saiki(N,Sum,Result):-
  	okNum(N,Add),
 	Sum1 is Sum+Add,
 	N1 is N+1,
 	saiki(N1,Sum1,Result).
 main1B:-saiki(1,0,Result),write(Result).

重要なのはokNumという判断述語である。
3か5で割れたらその数を、割れなかったら0を返す。
こういう術語はこんな簡単な問題では意味がないが。
条件判断が複雑になると、述語一つで判断できるときにありがたみが出てくる。