Project Euler Problem 75 Solution

Project Euler Problem 75 Solution

Singular Integer Right Triangles

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

Project Euler Problem 75 Statement

It turns out that 12 cm is the smallest length of wire that can be bent to form an integer sided right angle triangle in exactly one way, but there are many more examples.

In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer sided right angle triangle, and other lengths allow more than one solution to be found; for example, using 120 cm it is possible to form exactly three different integer sided right angle triangles.

Given that $L$ is the length of the wire, for how many values of $L \le 1\,500\,000$ can exactly one integer sided right angle triangle be formed?

Solution

HackerRank Project Euler Problem 75 overview:

For a given upper bound $N$, how many integer perimeters (where a perimeter $L\le N$) can form exactly one right-angled triangle with integer side lengths $(a, b, c)$ (with $a^2 + b^2 = c^2$) that sums to that particular perimeter $L = a + b + c$.

Solution Summary

This script precomputes, for every perimeter up to 5,000,000, whether that perimeter can be formed by exactly one right-angled triangle with integer sides. (In other words, it "flags" those perimeters that yield a singular solution.) It then uses a prefix sum array so that each query (given a number $N$) can be answered in $O(1)$ time.

Solution Details
1. Setting Up the Limit and the Count Array
import math, bisect, itertools
L = 5 * 10**6
f = [0]*L

2. Generating Primitive Pythagorean Triples Using a Change of Variables

The standard Euclid's formula to generate a primitive Pythagorean triple is $$a = m^2 - n^2,\quad b = 2mn,\quad c = m^2 + n^2,$$ and the perimeter $$P = a+b+c = 2m(m+n),$$ where \(m\) and \(n\) are positive integers with:

This script uses a transformation that lets it iterate over pairs of odd numbers instead. Here's how:

for i,j in itertools.combinations(range(1, math.isqrt(L), 2), 2):
    if j>i and math.gcd(j, i)==1:
        s = j*(j + i)
        for i in range(s, L, s):f[i]+=1

What is happening here?


3. Filtering Singular Perimeters

After the double loop finishes, we want to know which perimeters can form exactly one right triangle. That is, we are interested in perimeters \(p\) such that f[p] == 1.

f = [i for i in range(L) if f[i]==1]

This list comprehension builds a new sorted list, storing only those perimeter values i (from 0 up to L-1) for which there is exactly one right triangle. These are the singular integer right triangles perimeters.


4. Answering the Queries Fast with Binary Search

Finally, the script processes multiple queries. For each query, it needs to count how many singular perimeters are less than or equal to a given integer.

for _ in range(int(input())):
    print(bisect.bisect_right(f, int(input())))

Input Handling:
The first input is the number of queries. For each query, the script reads an integer value (say, \(N\)).

Using bisect_right:
The list f is already sorted (since it was constructed in increasing order). The function bisect.bisect_right(f, N) returns the insertion index of \(N\) in f – which is exactly the number of elements in f[] that are \(\leq N\). In other words, it counts how many singular perimeters do not exceed \(N\).

Printing the Result:
The result is printed for each query.


HackerRank version

HackerRank Project Euler 75: Given that $L$ is the length of the wire, for how many values of $L≤ N$ where (12 ≤ N ≤ 10^6) can exactly one integer sided right angle triangle be formed?

Python Source Code

import math, bisect, itertools
L = 5 * 10**6
f = [0]*L

for i,j in itertools.combinations(range(1, math.isqrt(L), 2), 2):
    if j>i and math.gcd(j, i)==1:
        s = j*(j + i)
        for i in range(s, L, s):f[i]+=1

f = [i for i in range(L) if f[i]==1]

for _ in range(int(input())):
    print(bisect.bisect_right(f, int(input())))