2014年3月14日金曜日

プロジェクトオイラー問34

Problem 34 「桁の階乗」 

145は面白い数である. 1! + 4! + 5! = 1 + 24 + 120 = 145となる.
各桁の数の階乗の和が自分自身と一致するような数の和を求めよ.
注: 1! = 1 と 2! = 2 は総和に含めてはならない.
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2034


解法
145
154
415
451
514
541
辞書順で並べ替えて階乗の和を計算しても全部145になります。
ということは昇順になっている7ケタまでの数を生成してそれの階乗の和をとり
階乗の和を文字列に直して文字列内部をソートしなおしたものが昇順数列と同じなら
それを答えとすれば計算量が下がります。
後は全部0でないのと2桁以上であることも判定条件とするだけです。

fact(0,1):-!.
fact(N,Result):-
      !,
      N1 is N-1,
      fact(N1,Re),
      Result is Re*N.

to_num([],Num,Num):-!.
to_num([E|List],Num,Result):-
      !,
      E1 is E-48,
      fact(E1,Add),
      Num1 is Num+Add,
      to_num(List,Num1,Result).

create_perm(_,_,8,_):-
      !,
      fail.

create_perm([],_,0,Result):-
      !,
      between(48,57,N),
      create_perm([N],N,1,Result).
create_perm(List,Down,Keta,Num):-
      Down>48,
      Keta>1,
      reverse(List,List1),
      to_num(List,0,Num),
      number_codes(Num,NumCodes),
      msort(NumCodes,List1).
create_perm(List,Down,Keta,Result):-
      !,
      between(Down,57,N),
      Keta1 is Keta+1,
      create_perm([N|List],N,Keta1,Result).

sum([],0):-!.
sum([X|Xs],Result):-
      !,
      sum(Xs,Re),
      Result is Re+X.
main34:-
      findall(E,create_perm([],0,0,E),List),
      sum(List,Ans),
      write(Ans).

0 件のコメント:

コメントを投稿