Project Euler 45(2)

Pm = Hn を式変形すると、

m(3m - 1) = 2n(2n - 1)
(36m2 - 12m) / 12 = (16n2 - 8n) / 4
( (6m - 1)2 - 1) / 12 = ( (4n - 1)2 - 1) / 4
(6m - 1)2 - 3(4n - 1)2 = -2

結局、次の方程式に帰着されました。

x2 - 3y2 = -2

これはペル方程式に似ています。
(x, y) = (1, 1) が最小解であることはすぐにわかります。

pn - √3qn = (2 - √3)n

としたとき、

xn - √3yn = (pn - √3qn)(1 - √3)

とすると、(xn, yn) が元の方程式の解であることが分かります。

xn2 - 3yn2
= (xn - √3yn)(xn + √3yn)
= (pn - √3qn)(1 - √3)(pn + √3qn)(1 + √3)
= -2(2 - √3)n(2 + √3)n
= -2

ただし、一般的にはほかに解があるかもしれません。今回の問題については無いようです。ですから、xnが6で割って余り5、ynが4で割って余り3になる解を選べばよいわけです。


from itertools import count, islice

def is_square(n):
m = int(sqrt(n))
return m * m == n

def gen_Pell_solution():
n, m = 1, 1
while True:
yield n, m
n, m = 2 * n + 3 * m, n + 2 * m

def gen_both():
for x, y in gen_Pell_solution():
if x % 6 == 5 and y % 4 == 3:
m = (x + 1) / 6
n = (y + 1) / 4
yield m * (3 * m - 1) / 2

print sum(islice(gen_both(), 2, 3))