http://projecteuler.net/index.php?section=problems&id=135
初項をa、公差をdとすると、
n = (a + 2d)2 - (a + d)2 - a2 = (3d - a)(d + a)
となります。
dを固定してaを変えましょう。dが小さいとき、1 ≤ a ≤ 3d - 1となりますが、dが大きいときにa = dをピークとしてnが100万以上になるので、そうでない領域が分断されます。こういうときのためにiterableをつなぐchainという関数がPythonには用意されています。これで一つのiterableになるので、dが小さいときと同じ扱いができます。
from itertools import * def f(d, a): return (3 * d - a) * (d + a) N = 10 ** 6 L = 10 b = [ 0 ] * N for d in xrange(1, (N + 1) / 4 + 1): if 4 * d * d < N: g = (f(d, a) for a in xrange(1, 3 * d)) else: g1 = takewhile(lambda n: n < N, (f(d, a) for a in count(1))) g2 = takewhile(lambda n: n < N, (f(d, a) for a in xrange(3 * d - 1, 0, -1))) g = chain(g1, g2) for n in g: b[n] += 1 print sum(1 for n in xrange(N) if b[n] == L)