diff --git a/solutions/0028.NumDiagonals/euler_28.py b/solutions/0028.NumDiagonals/euler_28.py new file mode 100644 index 0000000..d6b6ce0 --- /dev/null +++ b/solutions/0028.NumDiagonals/euler_28.py @@ -0,0 +1,90 @@ +""" +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) diff --git a/solutions/0028.NumDiagonals/readme.md b/solutions/0028.NumDiagonals/readme.md new file mode 100644 index 0000000..1dbeb6e --- /dev/null +++ b/solutions/0028.NumDiagonals/readme.md @@ -0,0 +1 @@ +https://oeis.org/A114254