Project Euler 141

http://projecteuler.net/index.php?section=problems&id=141


rdqの間のとき、公差をaとして、

n = r + r/a * ra = r + r2

これは平方数になり得ないので、rが一番小さいということになります。そうすると、

n = r + ra * ra2 = r + r2a3

as/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))