Kawazoe(@riverplus)さんのCodeIQの問題です。
こちらに問題と解答例があります。
->https://sw-logic.com/Portfolio/Programing/CodeIQ/2628.php
こちらにも情報があります。
->https://posfie.com/@riverplus/p/N1aRlyj
問題
要約すると、自然数x,y,a,bにおいて、あるa,bに対して、
x^2+a^2 = y^2+b^2
解となるx,yすべてに対する x+y の総和 F(a,b) を求める問題です。
式を変形すると (x+y)*(x-y)=b^2-a^2 なので
n=|b^2-a^2| を素因数分解し(2026.9.5訂正->素因数分解して組合せ)、
大きいほうが x+y 小さいほうが |x-y|
しかし n を i = x-y (i=1,2..、x > y) で割ったほうが簡単そうです。
あるiに対して(x,y)は高々一組
x+y > x-y より i < √n
x,yが自然数なので (x+y)+(x-y) = 2*x は偶数(偶数ならx,yがある)
偶々ですが前回投稿した「マルチプル・テーブル 」を簡単にした感じです。
#julia ver 1.0,1.41,1.53,1.85,1.12.1
function solve(a,b,v)
n = abs(a^2-b^2)
sum = 0
for i in 1 : Int(floor(sqrt(n)-1))
(d,m) = divrem(n,i)
if m == 0 && iseven(d + i)
sum += d
end
end
s = sum == v ? "ok " : "no "
println(s,sum)
end
solve(3,10,104)
solve(10,26,716)
solve(20 100,15022)
solve(19126,98765,16043311668)
Picatでも書きました。
Picatはvscode(下記ページ参照)
https://qiita.com/smallbigcats/items/9167bfcb01deb3da6f85
または Attempt This Online(https://ato.pxeger.com)
というところからrunをクリックしてPicatを選べば実行できます。
% Picat v 3.9#7
solve(A,B,R) =>
N = abs(A*A-B*B),
Sum = 0,
foreach(I in 1 .. floor(sqrt(N) -1),N rem I =:= 0 )
D := N div I,
if (D+I) rem 2 =:= 0 then
Sum := Sum + D,
end,
end,
R = Sum.
main =>
Data = [(3,10,104),(10,26,716),(20,100,15022),(19126,98765,16043311668)],
foreach((A,B,N) in Data)
if solve(A,B,R) then
Str = cond(R == N, " ok ", " no "),
printf(" %s %w,%w -> %w%n", Str, A,B, R)
else
printf(" fail %w,%w%n", A,B)
end,
end.
2026.9.5日訂正追記
投稿後 https://posfie.com/@riverplus/p/N1aRly を見に行って
間違いに気づきました。すべてのテストケースを把握していませんで、
ininsanusさんのhttps://yuppe19.bitbucket.io/sqquartet.html
の中のa=10,b=50の問題の答えが合いません。
私の過去のコードが
for i in 1 : Int(floor(sqrt(n)))
(d,m) = divrem(n,i)
if m == 0 && iseven(d + i) && i != d
sum += d
end
だったのを簡略化して投稿のコードにしたのですが、そのままにするか
for i in 1 : Int(floor(sqrt(n-1)))
にすべきでした。二つのコードを訂正するのは紙面の無駄でしょうから、
ininsanusさんのデータをコピーさせていただく容易さにより、
Picatの訂正をします
solve(A,B,R) =>
N = abs(A*A-B*B),
Sum = 0,
foreach(I in 1 .. floor(sqrt(N)),N rem I =:= 0 )
D := N div I,
if ((D+I) rem 2 =:= 0, I != D) then
Sum := Sum + D,
end,
end,
R = Sum.
main =>
Data = [(3, 10104),
(10, 50, 3500),
(20, 100, 15022),
(4, 5, 9),
(10, 26, 716),
(11, 389, 291886),
(123, 456, 294166),
(35672, 61243, 5082405064),
(71200, 82321, 2490724704),
(19126, 98765, 16043311668)],
foreach((A,B,N) in Data)
if solve(A,B,R) then
Str = cond(R == N, " ok ", " no "),
printf(" %s %w,%w -> %w%n", Str, A,B, R)
else
printf(" fail %w,%w%n", A,B)