Integer right triangles

If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120.

{20,48,52}, {24,45,51}, {30,40,50}

For which value of p ≤ 1000, is the number of solutions maximised?


Idea

Conditions: $ a+b+c=p $, $a^2+b^2=c^2 $. If we want any solution for a certain p, it means the line $ a+b+c=p $ and the circle $a^2+b^2=c^2 $ have intersection, which means $ c \lt p-c \lt \sqrt{2}c $, => $ \frac{p}{1+\sqrt{2}} \lt c \lt \frac{p}{2}$.

$ \begin{cases} a+b+c=p \\ a^2+b^2=c^2 \end{cases} $ => $ 2ab = p^2 - 2pc $, which means p is even.
Also, it is safe to assume $ a \lt b \lt c $, and $ 0 \lt \frac{p(p-2c)}{2} (=ab) \lt \frac{\sqrt{2}-1}{\sqrt{2}+1} p^2 $, so $ a \lt \sqrt{\frac{\sqrt{2}-1}{\sqrt{2}+1}} p $

What leaves is just to search through all possible (a, b, c).


In [1]:
def get_c_bound(p):
    return int(p / (1 + pow(2, 0.5)))+1, p // 2 + 1
In [2]:
def get_a_upper_bound(p):
    return int(pow((3 - 2 * pow(2, 0.5)) / 2, 0.5) * p)+1
In [3]:
def solve():
    max_solution = (-1, 0, None)
    # minimun perimeter of a right angle triangle is 12
    for p in range(12, 1001, 2):
        solutions = []
        for c in range(*get_c_bound(p)):
            for a in range(1, get_a_upper_bound(p)):
                b = (pow(p, 2) - 2 * p * c) / (2 * a)
                if a < b < c and b == int(b) and sum((a, b, c)) == p:
                    assert pow(a, 2) + pow(b, 2) == pow(c, 2)
                    solutions.append((a, int(b), c))
        max_solution = max(max_solution, (len(solutions), p, solutions))
    return max_solution
In [4]:
solve()
Out[4]:
(8,
 840,
 [(240, 252, 348),
  (210, 280, 350),
  (168, 315, 357),
  (140, 336, 364),
  (120, 350, 370),
  (105, 360, 375),
  (56, 390, 394),
  (40, 399, 401)])