10を0000010のように解釈すれば。
全ての数を7ケタで考えることができます。
桁の2乗和は並べ替えても結果が同じなので、0012738や0102378などは0012378で代表して計算がすみます。
後は代表だけを全探索するだけです。
これで計算時間0.2秒です。
C++なら配列によるメモ化が使えるのでもっと早くなります。
seed([_,_,_,_,_,_,_]).
perm([],N):-N>0,!.
perm([],_):-!,fail.
perm([X|Xs],N):-
between(N,9,X),
perm(Xs,X).
keta2Wa([],Sum,Sum):-!.
keta2Wa([X|Xs],Sum,Result):-
Sum1 is Sum+X^2,
keta2Wa(Xs,Sum1,Result).
keta2WaA(0,Sum,Sum):-!.
keta2WaA(N,Sum,Result):-
N1 is N//10,
Sum1 is Sum+(N mod 10)^2,
keta2WaA(N1,Sum1,Result).
fact(N,D):-nth0(N,[1,1,2,6,24,120,720,5040,40320],D).
divs([],C,Div,Result):-
!,
fact(C,Div1),
Result is Div*Div1.
divs([X,X|Xs],C,Div,Result):-
!,
C1 is C+1,
divs([X|Xs],C1,Div,Result).
divs([_|Xs],C,Div,Result):-
!,
fact(C,Div1),
Div2 is Div*Div1,
divs(Xs,1,Div2,Result).
calc(1):-!,fail.
calc(89):-!.
calc(N):-
keta2WaA(N,0,N1),
calc(N1).
sum([],Sum,Sum):-!.
sum([X|Xs],Sum,Result):-
Sum1 is Sum+X,
sum(Xs,Sum1,Result).
search(E):-
seed(X),
perm(X,0),
divs(X,1,1,D),
E is 5040//D,
keta2Wa(X,0,Num),
calc(Num).
main:-
findall(E,search(E),Es),
sum(Es,0,Ans),
write(Ans).
最終更新:2014年12月19日 10:10