TheAlgorithms-Python
99 строк · 2.5 Кб
1"""
2Project Euler Problem 65: https://projecteuler.net/problem=65
3
4The square root of 2 can be written as an infinite continued fraction.
5
6sqrt(2) = 1 + 1 / (2 + 1 / (2 + 1 / (2 + 1 / (2 + ...))))
7
8The infinite continued fraction can be written, sqrt(2) = [1;(2)], (2)
9indicates that 2 repeats ad infinitum. In a similar way, sqrt(23) =
10[4;(1,3,1,8)].
11
12It turns out that the sequence of partial values of continued
13fractions for square roots provide the best rational approximations.
14Let us consider the convergents for sqrt(2).
15
161 + 1 / 2 = 3/2
171 + 1 / (2 + 1 / 2) = 7/5
181 + 1 / (2 + 1 / (2 + 1 / 2)) = 17/12
191 + 1 / (2 + 1 / (2 + 1 / (2 + 1 / 2))) = 41/29
20
21Hence the sequence of the first ten convergents for sqrt(2) are:
221, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, ...
23
24What is most surprising is that the important mathematical constant,
25e = [2;1,2,1,1,4,1,1,6,1,...,1,2k,1,...].
26
27The first ten terms in the sequence of convergents for e are:
282, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, ...
29
30The sum of digits in the numerator of the 10th convergent is
311 + 4 + 5 + 7 = 17.
32
33Find the sum of the digits in the numerator of the 100th convergent
34of the continued fraction for e.
35
36-----
37
38The solution mostly comes down to finding an equation that will generate
39the numerator of the continued fraction. For the i-th numerator, the
40pattern is:
41
42n_i = m_i * n_(i-1) + n_(i-2)
43
44for m_i = the i-th index of the continued fraction representation of e,
45n_0 = 1, and n_1 = 2 as the first 2 numbers of the representation.
46
47For example:
48n_9 = 6 * 193 + 106 = 1264
491 + 2 + 6 + 4 = 13
50
51n_10 = 1 * 193 + 1264 = 1457
521 + 4 + 5 + 7 = 17
53"""
54
55
56def sum_digits(num: int) -> int:57"""58Returns the sum of every digit in num.
59
60>>> sum_digits(1)
611
62>>> sum_digits(12345)
6315
64>>> sum_digits(999001)
6528
66"""
67digit_sum = 068while num > 0:69digit_sum += num % 1070num //= 1071return digit_sum72
73
74def solution(max_n: int = 100) -> int:75"""76Returns the sum of the digits in the numerator of the max-th convergent of
77the continued fraction for e.
78
79>>> solution(9)
8013
81>>> solution(10)
8217
83>>> solution(50)
8491
85"""
86pre_numerator = 187cur_numerator = 288
89for i in range(2, max_n + 1):90temp = pre_numerator91e_cont = 2 * i // 3 if i % 3 == 0 else 192pre_numerator = cur_numerator93cur_numerator = e_cont * pre_numerator + temp94
95return sum_digits(cur_numerator)96
97
98if __name__ == "__main__":99print(f"{solution() = }")100