91 lines
2.2 KiB
Python
91 lines
2.2 KiB
Python
"""
|
|
Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:
|
|
|
|
21 22 23 24 25
|
|
20 7 8 9 10
|
|
19 6 1 2 11
|
|
18 5 4 3 12
|
|
17 16 15 14 13
|
|
|
|
It can be verified that the sum of the numbers on the diagonals is 101 .
|
|
|
|
What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
|
|
"""
|
|
|
|
import time
|
|
from functools import lru_cache
|
|
|
|
|
|
def timer(func):
|
|
def wrapper(*args, **kwargs):
|
|
start_time = time.time()
|
|
result = func(*args, **kwargs)
|
|
end_time = time.time()
|
|
print(f"{func.__name__} time: {end_time - start_time:.8f} seconds")
|
|
return result
|
|
|
|
return wrapper
|
|
|
|
|
|
def sum_right(length: int) -> int:
|
|
sumo = 0
|
|
last = 1
|
|
for i in range(1, length + 1):
|
|
sumo += last + 2 * (i - 1)
|
|
last += 2 * (i - 1)
|
|
return sumo
|
|
|
|
|
|
@lru_cache(maxsize=None)
|
|
def sum_left(length: int) -> tuple[list[int], int]:
|
|
if length == 1:
|
|
return [1], 1
|
|
else:
|
|
two, sum_o = sum_left(length - 2)
|
|
i = length // 2
|
|
max_two = max(two)
|
|
new_two = [max_two + i * 4, max_two + i * 8]
|
|
return new_two, sum_o + sum(new_two)
|
|
|
|
|
|
def sum_of_diagonals(length: int) -> int:
|
|
if length % 2 == 0:
|
|
raise ValueError("Input must be an odd number")
|
|
return sum_left(length)[1] + sum_right(length) - 1
|
|
|
|
|
|
@timer
|
|
def main_pro(length: int) -> None:
|
|
sum_o = sum_of_diagonals(length)
|
|
print(sum_o)
|
|
|
|
|
|
@timer
|
|
def main_math(length: int) -> None:
|
|
if length % 2 == 0:
|
|
raise ValueError("Input must be an odd number")
|
|
n = length // 2
|
|
sum_o = 1 + 10 * n**2 + (16 * n**3 + 26 * n) / 3
|
|
print(int(sum_o))
|
|
|
|
|
|
@timer
|
|
def main_math_pro(length: int) -> None:
|
|
if length % 2 == 0:
|
|
raise ValueError("Input must be an odd number")
|
|
n = length // 2
|
|
maxnum = int(length**2)
|
|
sumo = 1
|
|
for i in range(n, 0, -1):
|
|
delta = 2 * i
|
|
sumo += 4 * maxnum - 6 * delta
|
|
maxnum -= delta * 4
|
|
print(int(sumo))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
length = 1001
|
|
main_math(length)
|
|
main_pro(length)
|
|
main_math_pro(length)
|