Project Euler Problem 39 Solution

Project Euler Problem 39 Solution

Integer Right Triangles

by {BetaProjects} | Project Euler & HackerRank
Difficulty: Easy

Project Euler Problem 39 Statement

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 \le 1000$, is the number of solutions maximised?

Solution

HackerRank Project Euler Problem 39 overview:

Given an upper limit \( L \) on the perimeter of right‐angled triangles with integer sides, determine the perimeter \( p \leq L \) that maximizes the number of distinct right‐angled triangles that can be formed.

Solution Summary

The solution precomputes the number of right‐angled triangles for each perimeter up to \(N = 5\,000\,000\) by generating primitive Pythagorean triples using a modified version of Euclid’s formula and updating all their multiples, then builds a prefix maximum array that records the best perimeter (with the most solutions) up to each value, enabling each query for a given \(L\) to be answered in constant time.

Solution Details
1. Initial Settings

The program begins by importing the required modules and setting up an array c of length \( N \):

import itertools, math
N = 5_000_000
c = [0] * N

Here:

2. Generating Pythagorean Triples

Next, the code generates Pythagorean triples using a variation of Euclid’s formula. Recall that the primitive Pythagorean triple can be generated by:

\( a = m^2 - n^2,\quad b = 2mn,\quad c = m^2 + n^2, \) with \( m > n \), \( m \) and \( n \) coprime and of opposite parity.

Their perimeter is:

\( p = a + b + c = 2m(m+n). \)

The program uses a modified parameterization:

for t, s in itertools.combinations_with_replacement(range(1, math.isqrt(N), 2), 2):
    if math.gcd(s, t) == 1:
        x = s * (s + t)
        c[x::x] = [v+1 for v in c[x::x]]

Let's break down this loop:

3. Building the “Best-So-Far” Array

After the counts are in place, the program constructs an array \( r \) such that for each perimeter \( i \), r[i] holds the perimeter \(\leq i\) which has the maximum number of solutions. The code is:

m, a, r = 0, 0, []
for i, v in enumerate(c):
    if v > m:
        m, a = v, i
    r.append(a)

Here:

4. Answering the Queries

The final part of the code quickly answers the input queries using the precomputed array \( r \):

for _ in range(int(input())):
    print(r[int(input())])

For each test case, the program reads an integer \( L \) (the maximum allowed perimeter) and immediately outputs r[L], which is the perimeter \( \leq L \) having the most right-angled triangle solutions.

HackerRank version

HackerRank Project Euler 39 includes either 1—9 or 1—8 pandigital numbers and has you find the multipliers 100 ≤ N ≤ 105 in ascending order.

Python Source Code

import itertools, math
N = 5_000_000
c = [0]*N

for t,s in itertools.combinations_with_replacement(range(1,math.isqrt(N),2),2):
    if math.gcd(s,t)==1:
        x = s*(s+t)
        c[x::x] = [v+1 for v in c[x::x]]
 
m, a, r = 0, 0, []
for i,v in enumerate(c):
    if v>m: m,a = v,i
    r.append(a)

for _ in range(int(input())):
    print(r[int(input())])