From 9643d3060dd73ac4afa70283622cb5108fc95dab Mon Sep 17 00:00:00 2001 From: fpringle Date: Fri, 16 Oct 2020 12:30:45 +0200 Subject: [PATCH] Add solution for Project Euler problem 75. (#3129) * Added solution for Project Euler problem 75. * Added doctest for solution() in project_euler/problem_75/sol1.py * Update docstring and 0-padding of directory name. Reference: #3256 * More descriptive variable names * Moved solution explanation to module-level docstring --- project_euler/problem_075/__init__.py | 0 project_euler/problem_075/sol1.py | 60 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 project_euler/problem_075/__init__.py create mode 100644 project_euler/problem_075/sol1.py diff --git a/project_euler/problem_075/__init__.py b/project_euler/problem_075/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/project_euler/problem_075/sol1.py b/project_euler/problem_075/sol1.py new file mode 100644 index 000000000..b57604d76 --- /dev/null +++ b/project_euler/problem_075/sol1.py @@ -0,0 +1,60 @@ +""" +Project Euler Problem 75: https://projecteuler.net/problem=75 + +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. + +12 cm: (3,4,5) +24 cm: (6,8,10) +30 cm: (5,12,13) +36 cm: (9,12,15) +40 cm: (8,15,17) +48 cm: (12,16,20) + +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. + +120 cm: (30,40,50), (20,48,52), (24,45,51) + +Given that L is the length of the wire, for how many values of L ≤ 1,500,000 can +exactly one integer sided right angle triangle be formed? + +Solution: we generate all pythagorean triples using Euclid's formula and +keep track of the frequencies of the perimeters. + +Reference: https://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple +""" + +from collections import defaultdict +from math import gcd +from typing import DefaultDict + + +def solution(limit: int = 1500000) -> int: + """ + Return the number of values of L <= limit such that a wire of length L can be + formmed into an integer sided right angle triangle in exactly one way. + >>> solution(50) + 6 + >>> solution(1000) + 112 + >>> solution(50000) + 5502 + """ + frequencies: DefaultDict = defaultdict(int) + euclid_m = 2 + while 2 * euclid_m * (euclid_m + 1) <= limit: + for euclid_n in range((euclid_m % 2) + 1, euclid_m, 2): + if gcd(euclid_m, euclid_n) > 1: + continue + primitive_perimeter = 2 * euclid_m * (euclid_m + euclid_n) + for perimeter in range(primitive_perimeter, limit + 1, primitive_perimeter): + frequencies[perimeter] += 1 + euclid_m += 1 + return sum(1 for frequency in frequencies.values() if frequency == 1) + + +if __name__ == "__main__": + print(f"{solution() = }")