forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsol1.py
89 lines (70 loc) · 2.58 KB
/
sol1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""
Project Euler Problem 122: https://projecteuler.net/problem=122
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
However it is yet possible to compute it in only five multiplications:
n x n = n^2
n^2 x n = n^3
n^3 x n^3 = n^6
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.
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.
References:
- https://en.wikipedia.org/wiki/Addition_chain
"""
def solve(nums: list[int], goal: int, depth: int) -> bool:
"""
Checks if nums 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:
if el + nums[-1] == goal:
return True
nums.append(el + nums[-1])
if solve(nums=nums, goal=goal, depth=depth):
return True
del nums[-1]
return False
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(14)
45
>>> solution(15)
50
"""
total = 0
for i in range(2, n + 1):
max_length = 0
while True:
nums = [1]
max_length += 1
if solve(nums=nums, goal=i, depth=max_length):
break
total += max_length
return total
if __name__ == "__main__":
print(f"{solution() = }")