TheAlgorithms-Python
174 строки · 5.6 Кб
1"""
2Project Euler Problem 234: https://projecteuler.net/problem=234
3
4For any integer n, consider the three functions
5
6f1,n(x,y,z) = x^(n+1) + y^(n+1) - z^(n+1)
7f2,n(x,y,z) = (xy + yz + zx)*(x^(n-1) + y^(n-1) - z^(n-1))
8f3,n(x,y,z) = xyz*(xn-2 + yn-2 - zn-2)
9
10and their combination
11
12fn(x,y,z) = f1,n(x,y,z) + f2,n(x,y,z) - f3,n(x,y,z)
13
14We call (x,y,z) a golden triple of order k if x, y, and z are all rational numbers
15of the form a / b with 0 < a < b ≤ k and there is (at least) one integer n,
16so that fn(x,y,z) = 0.
17
18Let s(x,y,z) = x + y + z.
19Let t = u / v be the sum of all distinct s(x,y,z) for all golden triples
20(x,y,z) of order 35.
21All the s(x,y,z) and t must be in reduced form.
22
23Find u + v.
24
25
26Solution:
27
28By expanding the brackets it is easy to show that
29fn(x, y, z) = (x + y + z) * (x^n + y^n - z^n).
30
31Since x,y,z are positive, the requirement fn(x, y, z) = 0 is fulfilled if and
32only if x^n + y^n = z^n.
33
34By Fermat's Last Theorem, this means that the absolute value of n can not
35exceed 2, i.e. n is in {-2, -1, 0, 1, 2}. We can eliminate n = 0 since then the
36equation would reduce to 1 + 1 = 1, for which there are no solutions.
37
38So all we have to do is iterate through the possible numerators and denominators
39of x and y, calculate the corresponding z, and check if the corresponding numerator and
40denominator are integer and satisfy 0 < z_num < z_den <= 0. We use a set "uniquq_s"
41to make sure there are no duplicates, and the fractions.Fraction class to make sure
42we get the right numerator and denominator.
43
44Reference:
45https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem
46"""
47
48from __future__ import annotations49
50from fractions import Fraction51from math import gcd, sqrt52
53
54def is_sq(number: int) -> bool:55"""56Check if number is a perfect square.
57
58>>> is_sq(1)
59True
60>>> is_sq(1000001)
61False
62>>> is_sq(1000000)
63True
64"""
65sq: int = int(number**0.5)66return number == sq * sq67
68
69def add_three(70x_num: int, x_den: int, y_num: int, y_den: int, z_num: int, z_den: int71) -> tuple[int, int]:72"""73Given the numerators and denominators of three fractions, return the
74numerator and denominator of their sum in lowest form.
75>>> add_three(1, 3, 1, 3, 1, 3)
76(1, 1)
77>>> add_three(2, 5, 4, 11, 12, 3)
78(262, 55)
79"""
80top: int = x_num * y_den * z_den + y_num * x_den * z_den + z_num * x_den * y_den81bottom: int = x_den * y_den * z_den82hcf: int = gcd(top, bottom)83top //= hcf84bottom //= hcf85return top, bottom86
87
88def solution(order: int = 35) -> int:89"""90Find the sum of the numerator and denominator of the sum of all s(x,y,z) for
91golden triples (x,y,z) of the given order.
92
93>>> solution(5)
94296
95>>> solution(10)
9612519
97>>> solution(20)
9819408891927
99"""
100unique_s: set = set()101hcf: int102total: Fraction = Fraction(0)103fraction_sum: tuple[int, int]104
105for x_num in range(1, order + 1):106for x_den in range(x_num + 1, order + 1):107for y_num in range(1, order + 1):108for y_den in range(y_num + 1, order + 1):109# n=1110z_num = x_num * y_den + x_den * y_num111z_den = x_den * y_den112hcf = gcd(z_num, z_den)113z_num //= hcf114z_den //= hcf115if 0 < z_num < z_den <= order:116fraction_sum = add_three(117x_num, x_den, y_num, y_den, z_num, z_den118)119unique_s.add(fraction_sum)120
121# n=2122z_num = (123x_num * x_num * y_den * y_den + x_den * x_den * y_num * y_num124)125z_den = x_den * x_den * y_den * y_den126if is_sq(z_num) and is_sq(z_den):127z_num = int(sqrt(z_num))128z_den = int(sqrt(z_den))129hcf = gcd(z_num, z_den)130z_num //= hcf131z_den //= hcf132if 0 < z_num < z_den <= order:133fraction_sum = add_three(134x_num, x_den, y_num, y_den, z_num, z_den135)136unique_s.add(fraction_sum)137
138# n=-1139z_num = x_num * y_num140z_den = x_den * y_num + x_num * y_den141hcf = gcd(z_num, z_den)142z_num //= hcf143z_den //= hcf144if 0 < z_num < z_den <= order:145fraction_sum = add_three(146x_num, x_den, y_num, y_den, z_num, z_den147)148unique_s.add(fraction_sum)149
150# n=2151z_num = x_num * x_num * y_num * y_num152z_den = (153x_den * x_den * y_num * y_num + x_num * x_num * y_den * y_den154)155if is_sq(z_num) and is_sq(z_den):156z_num = int(sqrt(z_num))157z_den = int(sqrt(z_den))158hcf = gcd(z_num, z_den)159z_num //= hcf160z_den //= hcf161if 0 < z_num < z_den <= order:162fraction_sum = add_three(163x_num, x_den, y_num, y_den, z_num, z_den164)165unique_s.add(fraction_sum)166
167for num, den in unique_s:168total += Fraction(num, den)169
170return total.denominator + total.numerator171
172
173if __name__ == "__main__":174print(f"{solution() = }")175