Skip to content

Commit d123cbc

Browse files
Solution for the Euler Project Problem 122 (#12655)
* Add initial version for euler project problem 122. * Add doctests and documentation for the project euler problem 122. * Update sol1.py * Update sol1.py * Update sol1.py * Update sol1.py * Update sol1.py * Update sol1.py * Update sol1.py --------- Co-authored-by: Maxim Smolskiy <mithridatus@mail.ru>
1 parent cc621f1 commit d123cbc

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

project_euler/problem_122/__init__.py

Whitespace-only changes.

project_euler/problem_122/sol1.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""
2+
Project Euler Problem 122: https://projecteuler.net/problem=122
3+
4+
Efficient Exponentiation
5+
6+
The most naive way of computing n^15 requires fourteen multiplications:
7+
8+
n x n x ... x n = n^15.
9+
10+
But using a "binary" method you can compute it in six multiplications:
11+
12+
n x n = n^2
13+
n^2 x n^2 = n^4
14+
n^4 x n^4 = n^8
15+
n^8 x n^4 = n^12
16+
n^12 x n^2 = n^14
17+
n^14 x n = n^15
18+
19+
However it is yet possible to compute it in only five multiplications:
20+
21+
n x n = n^2
22+
n^2 x n = n^3
23+
n^3 x n^3 = n^6
24+
n^6 x n^6 = n^12
25+
n^12 x n^3 = n^15
26+
27+
We shall define m(k) to be the minimum number of multiplications to compute n^k;
28+
for example m(15) = 5.
29+
30+
Find sum_{k = 1}^200 m(k).
31+
32+
It uses the fact that for rather small n, applicable for this problem, the solution
33+
for each number can be formed by increasing the largest element.
34+
35+
References:
36+
- https://en.wikipedia.org/wiki/Addition_chain
37+
"""
38+
39+
40+
def solve(nums: list[int], goal: int, depth: int) -> bool:
41+
"""
42+
Checks if nums can have a sum equal to goal, given that length of nums does
43+
not exceed depth.
44+
45+
>>> solve([1], 2, 2)
46+
True
47+
>>> solve([1], 2, 0)
48+
False
49+
"""
50+
if len(nums) > depth:
51+
return False
52+
for el in nums:
53+
if el + nums[-1] == goal:
54+
return True
55+
nums.append(el + nums[-1])
56+
if solve(nums=nums, goal=goal, depth=depth):
57+
return True
58+
del nums[-1]
59+
return False
60+
61+
62+
def solution(n: int = 200) -> int:
63+
"""
64+
Calculates sum of smallest number of multiplactions for each number up to
65+
and including n.
66+
67+
>>> solution(1)
68+
0
69+
>>> solution(2)
70+
1
71+
>>> solution(14)
72+
45
73+
>>> solution(15)
74+
50
75+
"""
76+
total = 0
77+
for i in range(2, n + 1):
78+
max_length = 0
79+
while True:
80+
nums = [1]
81+
max_length += 1
82+
if solve(nums=nums, goal=i, depth=max_length):
83+
break
84+
total += max_length
85+
return total
86+
87+
88+
if __name__ == "__main__":
89+
print(f"{solution() = }")

0 commit comments

Comments
 (0)