問題はこちら
http://riverplus.net/codeiq/CutAndSquare.pdf
かいつまんで言うと、
[偶数 n に対して、先頭にゼロを持たない n 桁の整数で上 n/2 桁と下 n/2 桁とに分け、それぞれを 2 乗して和をとると、元の数に戻るような数で、n=6, n=10の場合を求めよ。]という感じ。
色々と回答があるようで、参考になったな~。
で、Rubyで書いた提出コードが下記。
sqrtの結果を整数に丸めるあたりが怪しい気がするが、まぁ、当たりでないときは外れるはずだからOKのはず。
ideone.comにも置きました。便利だね。
http://ideone.com/eMPnrv
【方針】
求めるN桁の数をnとし、 n = a * 10**(N/2) + b とする。
n = a**2 + b**2 (b>0, a>10**(N/2 – 1)) の条件を満たす整数a,bを見つける方針でとく。
1. n = a**2 + b**2 の1桁目に注目すると、aの1桁目の数字は0,2,8のみとなる。
(Excelで100通りをすべてチェックしましたが、a,bの下1桁の値の組み合わせは8通りしかありません。)
2. 条件の式からbについて解くことができるので、各aについて、bが条件を満たす整数かどうかをチェックする。
(bについてはループしなくて済む。)
N=10 Base2=10**(N/2) result = [] ((Base2/10)...Base2).select{|a| # aの下1桁を0, 2, 8に絞る。 tmp = a%10 tmp == 0 or tmp == 2 or tmp ==8 }.each{|a| # aについてのループ。 # bは、aについて解いておく。(b>0なので、一意にさだまる。) b=(1 + Math.sqrt(1+4*Base2*a -4*a*a)).round/2 n = a*Base2 + b result << n if a*a + b*b == n # 条件を満たすかどうかをチェック。 } p result p result.reduce(&:+)