project-euler/139_pythagorean_tiles.py

37 lines
755 B
Python

#!/usr/bin/env python3
from math import gcd
def sols():
"""yields solutions to a**2 - 2b**2 = -1"""
a, b = 3, 2
while True:
yield 2*b - a, a - b
a, b = 3*a + 4*b, 2*a + 3*b
def mn_from_ab(a, b, sgn):
M, N = a + b, b - sgn
div = gcd(M, N)
m, n = M // div, N // div
return m, n
def gen_mn(N):
for a, b in sols():
if b > N//2:
break
yield mn_from_ab(a, b, 1)
yield mn_from_ab(a, b, -1)
def is_primitive(m, n):
return (m + n) % 2 == 1 and n != 0
def count_triangles(m, n, circ):
sides = (m**2 - n**2, 2*m*n, m**2 + n**2)
return (circ-1) // sum(sides)
N = 100 * 10**6
R = sum(count_triangles(m, n, N) for m, n in gen_mn(N) if is_primitive(m, n))
print(R)