Kawazoe(@riverplus)さんのCodeIQの問題です。
問題はこちらのお世話になりました。解答の出るフォームがあります。
->http://paranoiactoadstool.blog.fc2.com/blog-entry-424.html
9桁の自然数で、二乗したとき下位9桁が元の数と同じになる数が二つあります。
それを求めてくださいという問題です。
aを求めるn桁の数としますと、a^2=k10^n+a -> a(a-1)=k10^n
10がn個あるのでaとa-1の二数併せて2,5が最低n個ずつあります。
奇数と偶数の積なので片方に2^nが含まれます(奇数には2が含まれない)。
2と5が偶数側だけにあるとa=h10^(n-1)またはa=h10^(n-1)+1
となり題意を満たしませんので奇数のほうは5の奇数倍です。
5が両方にありますと二数の差が1になりませんので二数はh12^nとh25^nです。
二数の差が1なのでh2*5^nを2^nで割った剰余は ±1 です。
Juliaで解きました。
#julia ver 1.41,1.53,1.85,1.12.1
function solve(n,a)
ar=[]
x = 2^n
y = 5^n
d = div(10^(n-1),y)
f = isodd(d) ? y*(d+2) : y*(d+1) #(n桁を担保)
y1 = 2*y
for i in f : y1 : 10^n #(n桁の5の奇数倍数)
v = mod(i ,x)
if v == 1 #(剰余が1)
push!(ar,i)
end
if v == x-1 #(剰余が-1)
push!(ar,i+1)
end
end
s= ar == a ? "ok " : "no "
print(s,ar)
end
solve(9,[212890625,787109376])
Prologの解法は、n桁の5の倍数 とそれに±1を足した数の積を、
10^n で割った剰余が0になることを利用しているところだけ違います。
%SWI-Prolog ver 7.42,7.64,9.29
%:-initialization(start). %ideone,Online Prolog Compiler
%start.
loop(F,_,E,R,R):-E<F.
loop(F,Y,E,R1,R):-
(F*(F-1) mod E =:= 0->R2=[F|R1];R2=R1), %F は a
(F*(F+1) mod E =:= 0->(F1 is F+1,R3=[F1|R2]);R3=R2), %F は a-1
F2 is F+Y,loop(F2,Y,E,R3,R).
solve(N,R):-
Y is 5^N,D is 10^(N-1) div Y,(D mod 2 =:= 0->F is Y*(D+1);F is Y*(D+2)), %n桁を担保
Y1 is Y*2,E is 10^N,loop(F,Y1,E,[],R1),reverse(R1,R).
start:-f(N,A),(solve(N,R)->(R==A->Str=" ok ";Str=" no ");
write(fail)),write(" "),write(Str),writeln(N->R).
f(9,[212890625,787109376]).
9桁の数以外でも計算してみると興味深いことに、
n桁目の数は、n-1桁目の数の二乗の一部(n-1桁の数+α)となっています。
x=g10^n+y,xx=h10^(n+1)+xとしますと
x(x-1)=(g10^n)^2+g10^n*(y+y-1)+y*(y-1)=h10^(n+1)
となりますので、y(y-1)=k*10^nが必要ということかとも思いますが、
αの部分の仕組みがわかりません。