Kawazoe(@riverplus)さんのCodeIQの問題です。
元の問題と解説のページ(PDF)がリンク切れしてしまいましたが、
こちらから問題を見ることができます。解答もあります。
->https://oraclesqlpuzzle.ninja-web.net/kyoupro-old/kyoupro-04-001.html
Kawazoeさんの別解の解説が見つかりました。
->https://riverplus.hatenablog.com/entry/2015/08/07/224228
こちらにも情報があります
->https://posfie.com/@riverplus/p/LLnPaa8
n桁(nは偶数)の数字を、上位半分の桁と下位半分の桁に分けて
(最上位が0になるときは0を除く)新しい数字を作り、
それぞれを二乗して足し合わせると元の数字に戻る場合がある。
n=6の時はただ一つあてはまる数字を求める
n=10の時は、あてはまる数字の総和を求める
という問題です。
求める数字が b*10^k+a (k=n/2) で表される場合
b^2+a^2=b*10^k+a->a*(a-1)=b*(10^k-b) ですので
10^(k-1)<=b<10^k の範囲で b*(10^k-b) の平方根をとり
(素因数分解が正攻法かとも思いますが)
その切り捨てと切り上げの積が b*(10^k-b) となれば切り上げの数字が a で
b^2+a^2 が求める数字です。
#julia ver 1.41,1.53,1.11.6
function solve(n,a)
n1 = div(n,2)
sum = 0
for i in 10^(n1-1) : 10^n1-1
x = i*(10^n1-i)
x1 = Int(ceil(sqrt(x)))
if x1*(x1-1) == x
sum += i^2 + x1^2
end
end
s = a == sum ? "ok " : "no "
println(s,sum)
end
solve(6,990100)
solve(10,29901173703)
Prologも同じ方針で書きました。
%SWI-Prolog ver 7.42,7.64,9.29
%:-initialization(start). %ideone,Online Prolog Compiler
%start.
fn(T,T,R,R).
fn(T,I,R1,R):-
X is I*(T-I),X1 is ceil(sqrt(X)),
(X=:=X1*(X1-1)->R2 is R1+I^2+X1^2;R2=R1),I1 is I+1,fn(T,I1,R2,R).
solve(N,R):-N1 is N div 2,T is 10^N1,F is 10^(N1-1),fn(T,F,0,R),!.
start:-f(N,A),(solve(N,R)->(R==A->Str=" ok ";Str=" no ");
write(fail)),write(" "),write(Str),writeln(N->R),fail.
start.
f(6,990100).
f(10,29901173703).