Skip to content

Project Euler 65 Solution #3035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 24, 2020
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,8 @@
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_062/sol1.py)
* Problem 063
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_063/sol1.py)
* Problem 065
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_065/sol1.py)
* Problem 067
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_067/sol1.py)
* Problem 069
Expand Down
Empty file.
99 changes: 99 additions & 0 deletions project_euler/problem_065/sol1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""
Project Euler Problem 65: https://projecteuler.net/problem=65
The square root of 2 can be written as an infinite continued fraction.
sqrt(2) = 1 + 1 / (2 + 1 / (2 + 1 / (2 + 1 / (2 + ...))))
The infinite continued fraction can be written, sqrt(2) = [1;(2)], (2)
indicates that 2 repeats ad infinitum. In a similar way, sqrt(23) =
[4;(1,3,1,8)].
It turns out that the sequence of partial values of continued
fractions for square roots provide the best rational approximations.
Let us consider the convergents for sqrt(2).
1 + 1 / 2 = 3/2
1 + 1 / (2 + 1 / 2) = 7/5
1 + 1 / (2 + 1 / (2 + 1 / 2)) = 17/12
1 + 1 / (2 + 1 / (2 + 1 / (2 + 1 / 2))) = 41/29
Hence the sequence of the first ten convergents for sqrt(2) are:
1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, ...
What is most surprising is that the important mathematical constant,
e = [2;1,2,1,1,4,1,1,6,1,...,1,2k,1,...].
The first ten terms in the sequence of convergents for e are:
2, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, ...
The sum of digits in the numerator of the 10th convergent is
1 + 4 + 5 + 7 = 17.
Find the sum of the digits in the numerator of the 100th convergent
of the continued fraction for e.
-----
The solution mostly comes down to finding an equation that will generate
the numerator of the continued fraction. For the i-th numerator, the
pattern is:
n_i = m_i * n_(i-1) + n_(i-2)
for m_i = the i-th index of the continued fraction representation of e,
n_0 = 1, and n_1 = 2 as the first 2 numbers of the representation.
For example:
n_9 = 6 * 193 + 106 = 1264
1 + 2 + 6 + 4 = 13
n_10 = 1 * 193 + 1264 = 1457
1 + 4 + 5 + 7 = 17
"""


def sum_digits(num: int) -> int:
"""
Returns the sum of every digit in num.
>>> sum_digits(1)
1
>>> sum_digits(12345)
15
>>> sum_digits(999001)
28
"""
digit_sum = 0
while num > 0:
digit_sum += num % 10
num //= 10
return digit_sum


def solution(max: int = 100) -> int:
"""
Returns the sum of the digits in the numerator of the max-th convergent of
the continued fraction for e.
>>> solution(9)
13
>>> solution(10)
17
>>> solution(50)
91
"""
pre_numerator = 1
cur_numerator = 2

for i in range(2, max + 1):
temp = pre_numerator
e_cont = 2 * i // 3 if i % 3 == 0 else 1
pre_numerator = cur_numerator
cur_numerator = e_cont * pre_numerator + temp

return sum_digits(cur_numerator)


if __name__ == "__main__":
print(f"{solution() = }")