mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
Performance: 80% faster Project Euler 145 (#10445)
* Performance: 80% faster Project Euler145 * Added timeit benchmark * >>> slow_solution() doctest
This commit is contained in:
parent
3ba2338479
commit
1969259868
|
@ -17,17 +17,17 @@ EVEN_DIGITS = [0, 2, 4, 6, 8]
|
|||
ODD_DIGITS = [1, 3, 5, 7, 9]
|
||||
|
||||
|
||||
def reversible_numbers(
|
||||
def slow_reversible_numbers(
|
||||
remaining_length: int, remainder: int, digits: list[int], length: int
|
||||
) -> int:
|
||||
"""
|
||||
Count the number of reversible numbers of given length.
|
||||
Iterate over possible digits considering parity of current sum remainder.
|
||||
>>> reversible_numbers(1, 0, [0], 1)
|
||||
>>> slow_reversible_numbers(1, 0, [0], 1)
|
||||
0
|
||||
>>> reversible_numbers(2, 0, [0] * 2, 2)
|
||||
>>> slow_reversible_numbers(2, 0, [0] * 2, 2)
|
||||
20
|
||||
>>> reversible_numbers(3, 0, [0] * 3, 3)
|
||||
>>> slow_reversible_numbers(3, 0, [0] * 3, 3)
|
||||
100
|
||||
"""
|
||||
if remaining_length == 0:
|
||||
|
@ -51,7 +51,7 @@ def reversible_numbers(
|
|||
result = 0
|
||||
for digit in range(10):
|
||||
digits[length // 2] = digit
|
||||
result += reversible_numbers(
|
||||
result += slow_reversible_numbers(
|
||||
0, (remainder + 2 * digit) // 10, digits, length
|
||||
)
|
||||
return result
|
||||
|
@ -67,7 +67,7 @@ def reversible_numbers(
|
|||
|
||||
for digit2 in other_parity_digits:
|
||||
digits[(length - remaining_length) // 2] = digit2
|
||||
result += reversible_numbers(
|
||||
result += slow_reversible_numbers(
|
||||
remaining_length - 2,
|
||||
(remainder + digit1 + digit2) // 10,
|
||||
digits,
|
||||
|
@ -76,6 +76,42 @@ def reversible_numbers(
|
|||
return result
|
||||
|
||||
|
||||
def slow_solution(max_power: int = 9) -> int:
|
||||
"""
|
||||
To evaluate the solution, use solution()
|
||||
>>> slow_solution(3)
|
||||
120
|
||||
>>> slow_solution(6)
|
||||
18720
|
||||
>>> slow_solution(7)
|
||||
68720
|
||||
"""
|
||||
result = 0
|
||||
for length in range(1, max_power + 1):
|
||||
result += slow_reversible_numbers(length, 0, [0] * length, length)
|
||||
return result
|
||||
|
||||
|
||||
def reversible_numbers(
|
||||
remaining_length: int, remainder: int, digits: list[int], length: int
|
||||
) -> int:
|
||||
"""
|
||||
Count the number of reversible numbers of given length.
|
||||
Iterate over possible digits considering parity of current sum remainder.
|
||||
>>> reversible_numbers(1, 0, [0], 1)
|
||||
0
|
||||
>>> reversible_numbers(2, 0, [0] * 2, 2)
|
||||
20
|
||||
>>> reversible_numbers(3, 0, [0] * 3, 3)
|
||||
100
|
||||
"""
|
||||
# There exist no reversible 1, 5, 9, 13 (ie. 4k+1) digit numbers
|
||||
if (length - 1) % 4 == 0:
|
||||
return 0
|
||||
|
||||
return slow_reversible_numbers(length, 0, [0] * length, length)
|
||||
|
||||
|
||||
def solution(max_power: int = 9) -> int:
|
||||
"""
|
||||
To evaluate the solution, use solution()
|
||||
|
@ -92,5 +128,25 @@ def solution(max_power: int = 9) -> int:
|
|||
return result
|
||||
|
||||
|
||||
def benchmark() -> None:
|
||||
"""
|
||||
Benchmarks
|
||||
"""
|
||||
# Running performance benchmarks...
|
||||
# slow_solution : 292.9300301000003
|
||||
# solution : 54.90970860000016
|
||||
|
||||
from timeit import timeit
|
||||
|
||||
print("Running performance benchmarks...")
|
||||
|
||||
print(f"slow_solution : {timeit('slow_solution()', globals=globals(), number=10)}")
|
||||
print(f"solution : {timeit('solution()', globals=globals(), number=10)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f"{solution() = }")
|
||||
print(f"Solution : {solution()}")
|
||||
benchmark()
|
||||
|
||||
# for i in range(1, 15):
|
||||
# print(f"{i}. {reversible_numbers(i, 0, [0]*i, i)}")
|
||||
|
|
Loading…
Reference in New Issue
Block a user