mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-04-24 22:53:36 +00:00
* 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>
90 lines
2.6 KiB
Python
90 lines
2.6 KiB
Python
"""
|
|
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() = }")
|