http://projecteuler.net/index.php?section=problems&id=141
rがdとqの間のとき、公差をaとして、
n = r + r/a * ra = r + r2
これは平方数になり得ないので、rが一番小さいということになります。そうすると、
n = r + ra * ra2 = r + r2a3
aをs/t(sとtは互いに素)として、
n = r + r2s3 / t3
r2 / t3が整数だから、r = kt2と表せて、
n = kt2 + k2s3t
これを素直にコーディングしても40秒以内に答えが出ました。
しかし、例えばt = 1とすると、
n = m2 = k + k2s3
4s6k + 4s3k = 4s3m2
(2s3k + 1) - 4s(s m)2 = 1
と、ペル方程式になります。
しかし、初期解を求めるのに時間がかかり、かえって遅くなってしまいました。この件は保留にしておきます。
from itertools import * from fractions import gcd from math import sqrt def is_square(n): m = int(sqrt(n)) return m * m == n def gen_progressive_perfect_squares(N): for s in takewhile(lambda s: 1 + s * s * s < N, count(2)): s3 = s * s * s for t in ifilter(lambda t: gcd(s, t) == 1, takewhile(lambda t: t * (t + s3) < N, xrange(1, s))): for n in ifilter(is_square, takewhile(lambda n: n < N, (k * t * (t + s3 * k) for k in count(1)))): yield n N = 10 ** 6 print sum(gen_progressive_perfect_squares(N))