From fa750c9c4491e0df36f29f121d0e8334085545ff Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Thu, 8 Oct 2020 00:15:04 -0700 Subject: [PATCH 1/8] Add solution for Project Euler 65, Fixes: #2695 --- DIRECTORY.md | 2 + project_euler/problem_65/__init__.py | 0 project_euler/problem_65/sol1.py | 90 ++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 project_euler/problem_65/__init__.py create mode 100644 project_euler/problem_65/sol1.py diff --git a/DIRECTORY.md b/DIRECTORY.md index 6a3d31709ed6..f11bfde582e6 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -652,6 +652,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_56/sol1.py) * Problem 63 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_63/sol1.py) + * Problem 65 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_65/sol1.py) * Problem 67 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_67/sol1.py) * Problem 76 diff --git a/project_euler/problem_65/__init__.py b/project_euler/problem_65/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_65/sol1.py b/project_euler/problem_65/sol1.py new file mode 100644 index 000000000000..1086f19a6d3e --- /dev/null +++ b/project_euler/problem_65/sol1.py @@ -0,0 +1,90 @@ +""" +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. +""" + + +def solution(max: int) -> int: + """ + 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. + + For example: + n_9 = 6 * 193 + 106 = 1264 + 1 + 2 + 6 + 4 = 13 + + n_10 = 1 * 193 + 1264 = 1457 + 1 + 4 + 5 + 7 = 17 + + >>> solution(9) + 13 + >>> solution(10) + 17 + """ + n0 = 1 + n1 = 2 + + for i in range(2, max + 1): + temp = n0 + m = 2 * i // 3 if i % 3 == 0 else 1 + n0 = n1 + n1 = m * n0 + temp + + return sum_digits(n1) + + +def sum_digits(num: int) -> int: + """ + Adds all the single digits of an int together. + + >>> 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 + + +if __name__ == "__main__": + print(solution(100)) From ad934bf176707ba77c00ffc4cb996b8d8d87c391 Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Thu, 8 Oct 2020 02:00:50 -0700 Subject: [PATCH 2/8] Add URL to problem 65 and don't pass in parameter to solution() --- project_euler/problem_65/sol1.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/project_euler/problem_65/sol1.py b/project_euler/problem_65/sol1.py index 1086f19a6d3e..528476b75cfb 100644 --- a/project_euler/problem_65/sol1.py +++ b/project_euler/problem_65/sol1.py @@ -1,4 +1,7 @@ """ +Project Euler 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 + ...)))) @@ -33,7 +36,7 @@ """ -def solution(max: int) -> int: +def solution() -> int: """ The solution mostly comes down to finding an equation that will generate the numerator of the continued fraction. For the i-th numerator, the @@ -58,6 +61,7 @@ def solution(max: int) -> int: """ n0 = 1 n1 = 2 + max = 100 for i in range(2, max + 1): temp = n0 @@ -87,4 +91,4 @@ def sum_digits(num: int) -> int: if __name__ == "__main__": - print(solution(100)) + print(solution()) From 6fbc59603d2e9c1ce5b60b88a80ea614632dc26f Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Thu, 8 Oct 2020 02:10:48 -0700 Subject: [PATCH 3/8] Remove solution() tests --- project_euler/problem_65/sol1.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/project_euler/problem_65/sol1.py b/project_euler/problem_65/sol1.py index 528476b75cfb..0da28d3a6f68 100644 --- a/project_euler/problem_65/sol1.py +++ b/project_euler/problem_65/sol1.py @@ -53,11 +53,6 @@ def solution() -> int: n_10 = 1 * 193 + 1264 = 1457 1 + 4 + 5 + 7 = 17 - - >>> solution(9) - 13 - >>> solution(10) - 17 """ n0 = 1 n1 = 2 From 542ca5a8448e2b829e66faf7128891488614757f Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Wed, 14 Oct 2020 20:52:51 -0700 Subject: [PATCH 4/8] Add tests for solution(), add fstring and positional arg for solution --- project_euler/problem_65/sol1.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/project_euler/problem_65/sol1.py b/project_euler/problem_65/sol1.py index 0da28d3a6f68..4c143cba3483 100644 --- a/project_euler/problem_65/sol1.py +++ b/project_euler/problem_65/sol1.py @@ -36,7 +36,7 @@ """ -def solution() -> int: +def solution(max: int = 100) -> int: """ The solution mostly comes down to finding an equation that will generate the numerator of the continued fraction. For the i-th numerator, the @@ -45,7 +45,7 @@ def solution() -> int: 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. + n_0 = 1, and n_1 = 2 as the first 2 numbers of the representation. For example: n_9 = 6 * 193 + 106 = 1264 @@ -53,10 +53,16 @@ def solution() -> int: n_10 = 1 * 193 + 1264 = 1457 1 + 4 + 5 + 7 = 17 + + >>> solution(9) + 13 + >>> solution(10) + 17 + >>> solution(50) + 91 """ n0 = 1 n1 = 2 - max = 100 for i in range(2, max + 1): temp = n0 @@ -86,4 +92,4 @@ def sum_digits(num: int) -> int: if __name__ == "__main__": - print(solution()) + print(f"{solution() = }") From 5918f97551bcf4f0edad32ee76047783b9c71af7 Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Thu, 15 Oct 2020 20:16:27 -0700 Subject: [PATCH 5/8] Rename directory and problem number to 065 --- DIRECTORY.md | 4 ++-- project_euler/{problem_65 => problem_065}/__init__.py | 0 project_euler/{problem_65 => problem_065}/sol1.py | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename project_euler/{problem_65 => problem_065}/__init__.py (100%) rename project_euler/{problem_65 => problem_065}/sol1.py (100%) diff --git a/DIRECTORY.md b/DIRECTORY.md index cc2f2b72826b..3a13b43acf87 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -659,8 +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 65 - * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_65/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 diff --git a/project_euler/problem_65/__init__.py b/project_euler/problem_065/__init__.py similarity index 100% rename from project_euler/problem_65/__init__.py rename to project_euler/problem_065/__init__.py diff --git a/project_euler/problem_65/sol1.py b/project_euler/problem_065/sol1.py similarity index 100% rename from project_euler/problem_65/sol1.py rename to project_euler/problem_065/sol1.py From 8cac24dfc4eb9ce9f62b0bbeca4e67aa5b3c6b52 Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Thu, 15 Oct 2020 20:20:56 -0700 Subject: [PATCH 6/8] Remove directory --- Python | 1 - 1 file changed, 1 deletion(-) delete mode 160000 Python diff --git a/Python b/Python deleted file mode 160000 index f7e7ad2ef6ab..000000000000 --- a/Python +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f7e7ad2ef6ab39a5a298b24945496e8d9674f1dd From d81a171fcb58997e8e6e47085390a3b5bbd1d50b Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Thu, 15 Oct 2020 20:41:05 -0700 Subject: [PATCH 7/8] Move up explanation to module code block --- project_euler/problem_065/sol1.py | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/project_euler/problem_065/sol1.py b/project_euler/problem_065/sol1.py index 4c143cba3483..c0a91ecb7314 100644 --- a/project_euler/problem_065/sol1.py +++ b/project_euler/problem_065/sol1.py @@ -33,26 +33,31 @@ Find the sum of the digits in the numerator of the 100th convergent of the continued fraction for e. -""" +----- -def solution(max: int = 100) -> int: - """ - 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: +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) - 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 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 +""" - 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 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 @@ -75,7 +80,7 @@ def solution(max: int = 100) -> int: def sum_digits(num: int) -> int: """ - Adds all the single digits of an int together. + Returns the sum of every digit in num. >>> sum_digits(1) 1 From 27d0614fd9f5e3332dc3ea25c5ebb5c610a7f7c9 Mon Sep 17 00:00:00 2001 From: "peteryao7@gmail.com" Date: Fri, 16 Oct 2020 10:43:51 -0700 Subject: [PATCH 8/8] Move solution() below helper function, rename variables --- project_euler/problem_065/sol1.py | 51 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/project_euler/problem_065/sol1.py b/project_euler/problem_065/sol1.py index c0a91ecb7314..229769a77d07 100644 --- a/project_euler/problem_065/sol1.py +++ b/project_euler/problem_065/sol1.py @@ -1,6 +1,5 @@ """ -Project Euler 65 -https://projecteuler.net/problem=65 +Project Euler Problem 65: https://projecteuler.net/problem=65 The square root of 2 can be written as an infinite continued fraction. @@ -54,30 +53,6 @@ """ -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 - """ - n0 = 1 - n1 = 2 - - for i in range(2, max + 1): - temp = n0 - m = 2 * i // 3 if i % 3 == 0 else 1 - n0 = n1 - n1 = m * n0 + temp - - return sum_digits(n1) - - def sum_digits(num: int) -> int: """ Returns the sum of every digit in num. @@ -96,5 +71,29 @@ def sum_digits(num: int) -> int: 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() = }")