mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
Add Project Euler Problem 180 (#4017)
* Added solution for Project Euler problem 180 * Fixed minor details in Project Euler problem 180 * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
parent
e7ab06f5de
commit
b1801398ec
|
@ -245,6 +245,7 @@
|
|||
* [Max Sum Contiguous Subsequence](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/max_sum_contiguous_subsequence.py)
|
||||
* [Minimum Cost Path](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/minimum_cost_path.py)
|
||||
* [Minimum Partition](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/minimum_partition.py)
|
||||
* [Minimum Steps To One](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/minimum_steps_to_one.py)
|
||||
* [Optimal Binary Search Tree](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/optimal_binary_search_tree.py)
|
||||
* [Rod Cutting](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/rod_cutting.py)
|
||||
* [Subset Generation](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/subset_generation.py)
|
||||
|
@ -754,6 +755,8 @@
|
|||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_173/sol1.py)
|
||||
* Problem 174
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_174/sol1.py)
|
||||
* Problem 180
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_180/sol1.py)
|
||||
* Problem 188
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_188/sol1.py)
|
||||
* Problem 191
|
||||
|
|
0
project_euler/problem_180/__init__.py
Normal file
0
project_euler/problem_180/__init__.py
Normal file
174
project_euler/problem_180/sol1.py
Normal file
174
project_euler/problem_180/sol1.py
Normal file
|
@ -0,0 +1,174 @@
|
|||
"""
|
||||
Project Euler Problem 234: https://projecteuler.net/problem=234
|
||||
|
||||
For any integer n, consider the three functions
|
||||
|
||||
f1,n(x,y,z) = x^(n+1) + y^(n+1) - z^(n+1)
|
||||
f2,n(x,y,z) = (xy + yz + zx)*(x^(n-1) + y^(n-1) - z^(n-1))
|
||||
f3,n(x,y,z) = xyz*(xn-2 + yn-2 - zn-2)
|
||||
|
||||
and their combination
|
||||
|
||||
fn(x,y,z) = f1,n(x,y,z) + f2,n(x,y,z) - f3,n(x,y,z)
|
||||
|
||||
We call (x,y,z) a golden triple of order k if x, y, and z are all rational numbers
|
||||
of the form a / b with 0 < a < b ≤ k and there is (at least) one integer n,
|
||||
so that fn(x,y,z) = 0.
|
||||
|
||||
Let s(x,y,z) = x + y + z.
|
||||
Let t = u / v be the sum of all distinct s(x,y,z) for all golden triples
|
||||
(x,y,z) of order 35.
|
||||
All the s(x,y,z) and t must be in reduced form.
|
||||
|
||||
Find u + v.
|
||||
|
||||
|
||||
Solution:
|
||||
|
||||
By expanding the brackets it is easy to show that
|
||||
fn(x, y, z) = (x + y + z) * (x^n + y^n - z^n).
|
||||
|
||||
Since x,y,z are positive, the requirement fn(x, y, z) = 0 is fulfilled if and
|
||||
only if x^n + y^n = z^n.
|
||||
|
||||
By Fermat's Last Theorem, this means that the absolute value of n can not
|
||||
exceed 2, i.e. n is in {-2, -1, 0, 1, 2}. We can eliminate n = 0 since then the
|
||||
equation would reduce to 1 + 1 = 1, for which there are no solutions.
|
||||
|
||||
So all we have to do is iterate through the possible numerators and denominators
|
||||
of x and y, calculate the corresponding z, and check if the corresponding numerator and
|
||||
denominator are integer and satisfy 0 < z_num < z_den <= 0. We use a set "uniquq_s"
|
||||
to make sure there are no duplicates, and the fractions.Fraction class to make sure
|
||||
we get the right numerator and denominator.
|
||||
|
||||
Reference:
|
||||
https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem
|
||||
"""
|
||||
|
||||
|
||||
from fractions import Fraction
|
||||
from math import gcd, sqrt
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def is_sq(number: int) -> bool:
|
||||
"""
|
||||
Check if number is a perfect square.
|
||||
|
||||
>>> is_sq(1)
|
||||
True
|
||||
>>> is_sq(1000001)
|
||||
False
|
||||
>>> is_sq(1000000)
|
||||
True
|
||||
"""
|
||||
sq: int = int(number ** 0.5)
|
||||
return number == sq * sq
|
||||
|
||||
|
||||
def add_three(
|
||||
x_num: int, x_den: int, y_num: int, y_den: int, z_num: int, z_den: int
|
||||
) -> Tuple[int, int]:
|
||||
"""
|
||||
Given the numerators and denominators of three fractions, return the
|
||||
numerator and denominator of their sum in lowest form.
|
||||
>>> add_three(1, 3, 1, 3, 1, 3)
|
||||
(1, 1)
|
||||
>>> add_three(2, 5, 4, 11, 12, 3)
|
||||
(262, 55)
|
||||
"""
|
||||
top: int = x_num * y_den * z_den + y_num * x_den * z_den + z_num * x_den * y_den
|
||||
bottom: int = x_den * y_den * z_den
|
||||
hcf: int = gcd(top, bottom)
|
||||
top //= hcf
|
||||
bottom //= hcf
|
||||
return top, bottom
|
||||
|
||||
|
||||
def solution(order: int = 35) -> int:
|
||||
"""
|
||||
Find the sum of the numerator and denominator of the sum of all s(x,y,z) for
|
||||
golden triples (x,y,z) of the given order.
|
||||
|
||||
>>> solution(5)
|
||||
296
|
||||
>>> solution(10)
|
||||
12519
|
||||
>>> solution(20)
|
||||
19408891927
|
||||
"""
|
||||
unique_s: set = set()
|
||||
hcf: int
|
||||
total: Fraction = Fraction(0)
|
||||
fraction_sum: Tuple[int, int]
|
||||
|
||||
for x_num in range(1, order + 1):
|
||||
for x_den in range(x_num + 1, order + 1):
|
||||
for y_num in range(1, order + 1):
|
||||
for y_den in range(y_num + 1, order + 1):
|
||||
# n=1
|
||||
z_num = x_num * y_den + x_den * y_num
|
||||
z_den = x_den * y_den
|
||||
hcf = gcd(z_num, z_den)
|
||||
z_num //= hcf
|
||||
z_den //= hcf
|
||||
if 0 < z_num < z_den <= order:
|
||||
fraction_sum = add_three(
|
||||
x_num, x_den, y_num, y_den, z_num, z_den
|
||||
)
|
||||
unique_s.add(fraction_sum)
|
||||
|
||||
# n=2
|
||||
z_num = (
|
||||
x_num * x_num * y_den * y_den + x_den * x_den * y_num * y_num
|
||||
)
|
||||
z_den = x_den * x_den * y_den * y_den
|
||||
if is_sq(z_num) and is_sq(z_den):
|
||||
z_num = int(sqrt(z_num))
|
||||
z_den = int(sqrt(z_den))
|
||||
hcf = gcd(z_num, z_den)
|
||||
z_num //= hcf
|
||||
z_den //= hcf
|
||||
if 0 < z_num < z_den <= order:
|
||||
fraction_sum = add_three(
|
||||
x_num, x_den, y_num, y_den, z_num, z_den
|
||||
)
|
||||
unique_s.add(fraction_sum)
|
||||
|
||||
# n=-1
|
||||
z_num = x_num * y_num
|
||||
z_den = x_den * y_num + x_num * y_den
|
||||
hcf = gcd(z_num, z_den)
|
||||
z_num //= hcf
|
||||
z_den //= hcf
|
||||
if 0 < z_num < z_den <= order:
|
||||
fraction_sum = add_three(
|
||||
x_num, x_den, y_num, y_den, z_num, z_den
|
||||
)
|
||||
unique_s.add(fraction_sum)
|
||||
|
||||
# n=2
|
||||
z_num = x_num * x_num * y_num * y_num
|
||||
z_den = (
|
||||
x_den * x_den * y_num * y_num + x_num * x_num * y_den * y_den
|
||||
)
|
||||
if is_sq(z_num) and is_sq(z_den):
|
||||
z_num = int(sqrt(z_num))
|
||||
z_den = int(sqrt(z_den))
|
||||
hcf = gcd(z_num, z_den)
|
||||
z_num //= hcf
|
||||
z_den //= hcf
|
||||
if 0 < z_num < z_den <= order:
|
||||
fraction_sum = add_three(
|
||||
x_num, x_den, y_num, y_den, z_num, z_den
|
||||
)
|
||||
unique_s.add(fraction_sum)
|
||||
|
||||
for num, den in unique_s:
|
||||
total += Fraction(num, den)
|
||||
|
||||
return total.denominator + total.numerator
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f"{solution() = }")
|
Loading…
Reference in New Issue
Block a user