I made a lot of wrong assumptions while working on this one. These all meant that I wasn’t actually producing all the Pythagorean triples as I should have been. I used the wikipedia article on Pythagorean triples as my guide, and had I just read it clearly the first time and followed their instructions, I wouldn’t have had any of these problems.
My errors were first that m and n cannot both be odd. They also cannot both be even because then their gcd would not be 1. Secondly, for some reason I assumed that a needed to be smaller than b, so I broke out of the n loop early. This was incorrect.
def gcd(a, b):
while b:
a, b = b, a % b
return a
def triples(perimeter):
for m in range(1, int(perimeter**0.5) + 1):
for n in range(m % 2 + 1, m, 2):
if gcd(m, n) != 1:
continue
_a = m**2 - n**2
_b = 2*m*n
_c = m**2 + n**2
if _a + _b + _c > perimeter:
break
for k in range(1, perimeter):
a = k * _a
b = k * _b
c = k * _c
if a + b + c >= perimeter:
break
yield a, b, c
def solve(perimeter):
count = 0
for a, b, c in triples(perimeter):
if c % (b - a) == 0:
count += 1
return count
if __name__ == '__main__':
import sys
n = eval(sys.argv[1])
print(solve(n))
import pytest
from problem import solve
_test_solve = (
(13, 1),
(31, 2),
(10**2, 9),
(10**3, 99),
(10**4, 1003),
)
@pytest.mark.parametrize('n,expect', _test_solve)
def test_solve(n, expect):
assert expect == solve(n)