2014年3月21日金曜日

プロジェクトオイラー Problem 62 「立方数置換」 †

Problem 62 「立方数置換」 

立方数 41063625 (3453) は, 桁の順番を入れ替えると2つの立方数になる: 56623104 (3843) と 66430125 (4053) である. 41063625は, 立方数になるような桁の置換をちょうど3つもつ最小の立方数である.
立方数になるような桁の置換をちょうど5つもつ最小の立方数を求めよ.

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

解法
数字を文字列の文字コードに直して、文字コードをソートこれをCodes。
Codesと数をセットにしてリストに保管。
桁数が変わったらそこまでのリストをソートしたものは同じ桁数となるので。
この中で比べて同じ文字コードが5つあるもののうちで最小の数字が答え。
可能性としては6つ以上が先に見つかる可能性があるのでそこに注意。
答えが見つからなければリストをリセットして新しい桁の数字を一つセットして再度計算再開。



プログラムはProlog言語。
Prologとは数学の導出木と同じ構造を持った言語で、コードの実行順序はすべて木構造に展開されます。
コードは calc(1,0,[]).
で実行開始。


search5([],[_,Min,5],Min):-!.
search5([[Codes,_]|Rest],[Codes,Min,Count],Result):-
      !,
      Count1 is Count+1,
      search5(Rest,[Codes,Min,Count1],Result).
search5(_,[_,Min,5],Min).
search5([[Codes,Min]|Rest],_,Result):-
      search5(Rest,[Codes,Min,1],Result).

search5_w(List,Ans):-
      msort(List,[[Codes,Min]|List1]),
      findall(E,search5(List1,[Codes,Min,1],E),AnsList),
      msort(AnsList,[Ans|_]).

calc(N,OldLen,List):-
      N3 is N^3,
      number_codes(N3,Codes),
      length(Codes,Len),
      msort(Codes,Codes1),
      OldLen<Len,
      !,
      (search5_w(List,Ans)->
      !,write(Ans);
      N1 is N+1,
      calc(N1,Len,[[Codes1,N3]])).

calc(N,OldLen,List):-
      N3 is N^3,
      N1 is N+1,
      number_codes(N3,Codes),
      msort(Codes,Codes1),
      calc(N1,OldLen,[[Codes1,N3]|List]).

0 件のコメント:

コメントを投稿