From f86430be4c035807055821245772c313e5710127 Mon Sep 17 00:00:00 2001 From: mindaugl Date: Sat, 5 Apr 2025 15:55:46 +0800 Subject: [PATCH 1/9] Add initial version for euler project problem 122. --- project_euler/problem_122/__init__.py | 0 project_euler/problem_122/sol1.py | 35 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 project_euler/problem_122/__init__.py create mode 100644 project_euler/problem_122/sol1.py diff --git a/project_euler/problem_122/__init__.py b/project_euler/problem_122/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py new file mode 100644 index 000000000000..f88e81edbc85 --- /dev/null +++ b/project_euler/problem_122/sol1.py @@ -0,0 +1,35 @@ +""" +Project Euler Problem 122: https://projecteuler.net/problem=122 + +Efficient Exponentiation +""" + + +def solve(nums: list[int], goal: int, depth: int) -> bool: + if len(nums) > depth: + return False + for el in nums: + if el + nums[-1] == goal: + return True + nums.append(el + nums[-1]) + if solve(nums, goal, depth): + return True + del nums[-1] + return False + + +def solution(n: int = 200) -> int: + m = [0] + for i in range(2, n + 1): + max_length = 0 + while True: + nums = [1] + max_length += 1 + if solve(nums, i, max_length): + break + m.append(len(nums)) + return sum(m) + + +if __name__ == "__main__": + print(f"{solution() = }") From 9a380384099317437e5d0c1109beb2e46a6cfaf3 Mon Sep 17 00:00:00 2001 From: mindaugl Date: Sat, 5 Apr 2025 16:19:11 +0800 Subject: [PATCH 2/9] Add doctests and documentation for the project euler problem 122. --- project_euler/problem_122/sol1.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index f88e81edbc85..06bc35fcc557 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -2,10 +2,29 @@ Project Euler Problem 122: https://projecteuler.net/problem=122 Efficient Exponentiation + +It uses the fact that for rather small n, applicable for this problem, the solution +for each number +can be formed by increasing the largest element. + +References: +- https://en.wikipedia.org/wiki/Addition_chain + +>>> solution(14) +45 """ def solve(nums: list[int], goal: int, depth: int) -> bool: + """ + Checks if nums can can have a sum equal to goal, given that length of nums does + not exceed depth. + + >>> solve([1], 2, 2) + True + >>> solve([1], 2, 0) + False + """ if len(nums) > depth: return False for el in nums: @@ -19,6 +38,17 @@ def solve(nums: list[int], goal: int, depth: int) -> bool: def solution(n: int = 200) -> int: + """ + Calculates sum of smallest number of multiplactions for each number up to + and including n. + + >>> solution(1) + 0 + >>> solution(2) + 1 + >>> solution(15) + 50 + """ m = [0] for i in range(2, n + 1): max_length = 0 From 53297f7a846c5adfa2ef1cb39eaf33af7cd71e42 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 14 Apr 2025 21:11:49 +0300 Subject: [PATCH 3/9] Update sol1.py --- project_euler/problem_122/sol1.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index 06bc35fcc557..c2d523bb5e6d 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -3,6 +3,30 @@ Efficient Exponentiation +The most naive way of computing n^15 requires fourteen multiplications: + + n x n x ... x n = n^15. + +But using a "binary" method you can compute it in six multiplications: + n x n = n^2 + n^2 x n^2 = n^4 + n^4 x n^4 = n^8 + n^8 x n^4 = n^12 + n^12 x n^2 = n^14 + n^14 x n = n^15 + + Date: Mon, 14 Apr 2025 21:13:37 +0300 Subject: [PATCH 4/9] Update sol1.py --- project_euler/problem_122/sol1.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index c2d523bb5e6d..8276c21dade7 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -8,6 +8,7 @@ n x n x ... x n = n^15. But using a "binary" method you can compute it in six multiplications: + n x n = n^2 n^2 x n^2 = n^4 n^4 x n^4 = n^8 @@ -15,13 +16,13 @@ n^12 x n^2 = n^14 n^14 x n = n^15 - Date: Mon, 14 Apr 2025 21:17:15 +0300 Subject: [PATCH 5/9] Update sol1.py --- project_euler/problem_122/sol1.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index 8276c21dade7..3fe1e3bae3d4 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -29,14 +29,10 @@ Find sum_{k = 1}^200 m(k). It uses the fact that for rather small n, applicable for this problem, the solution -for each number -can be formed by increasing the largest element. +for each number can be formed by increasing the largest element. References: - https://en.wikipedia.org/wiki/Addition_chain - ->>> solution(14) -45 """ @@ -71,6 +67,8 @@ def solution(n: int = 200) -> int: 0 >>> solution(2) 1 + >>> solution(14) + 45 >>> solution(15) 50 """ From 32811cdbcefea24181a8e226727de021fb0a2c00 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 14 Apr 2025 21:17:58 +0300 Subject: [PATCH 6/9] Update sol1.py --- project_euler/problem_122/sol1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index 3fe1e3bae3d4..aa1fe6dbeece 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -38,7 +38,7 @@ def solve(nums: list[int], goal: int, depth: int) -> bool: """ - Checks if nums can can have a sum equal to goal, given that length of nums does + Checks if nums can have a sum equal to goal, given that length of nums does not exceed depth. >>> solve([1], 2, 2) From 30b351b9d076c1c12f242d69c500d0ed393c6b8d Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 14 Apr 2025 21:22:38 +0300 Subject: [PATCH 7/9] Update sol1.py --- project_euler/problem_122/sol1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index aa1fe6dbeece..55657aa53384 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -72,7 +72,7 @@ def solution(n: int = 200) -> int: >>> solution(15) 50 """ - m = [0] + sum = 0 for i in range(2, n + 1): max_length = 0 while True: @@ -80,8 +80,8 @@ def solution(n: int = 200) -> int: max_length += 1 if solve(nums, i, max_length): break - m.append(len(nums)) - return sum(m) + sum += max_length + return sum if __name__ == "__main__": From b64e230d12c6287f9f77f87caba740e81d6800c9 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 14 Apr 2025 21:22:57 +0300 Subject: [PATCH 8/9] Update sol1.py --- project_euler/problem_122/sol1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index 55657aa53384..a68d4cde0c83 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -24,7 +24,8 @@ n^6 x n^6 = n^12 n^12 x n^3 = n^15 -We shall define m(k) to be the minimum number of multiplications to compute n^k; for example m(15) = 5. +We shall define m(k) to be the minimum number of multiplications to compute n^k; +for example m(15) = 5. Find sum_{k = 1}^200 m(k). From 136f6225b044d49efe77ba245e55d493d2918225 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 14 Apr 2025 21:25:48 +0300 Subject: [PATCH 9/9] Update sol1.py --- project_euler/problem_122/sol1.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/project_euler/problem_122/sol1.py b/project_euler/problem_122/sol1.py index a68d4cde0c83..cd8b1e67708c 100644 --- a/project_euler/problem_122/sol1.py +++ b/project_euler/problem_122/sol1.py @@ -53,7 +53,7 @@ def solve(nums: list[int], goal: int, depth: int) -> bool: if el + nums[-1] == goal: return True nums.append(el + nums[-1]) - if solve(nums, goal, depth): + if solve(nums=nums, goal=goal, depth=depth): return True del nums[-1] return False @@ -73,16 +73,16 @@ def solution(n: int = 200) -> int: >>> solution(15) 50 """ - sum = 0 + total = 0 for i in range(2, n + 1): max_length = 0 while True: nums = [1] max_length += 1 - if solve(nums, i, max_length): + if solve(nums=nums, goal=i, depth=max_length): break - sum += max_length - return sum + total += max_length + return total if __name__ == "__main__":