From 4939e8463fc34c936a309d513cfe8153343cb9d5 Mon Sep 17 00:00:00 2001 From: Caeden Perelli-Harris Date: Sat, 7 Jan 2023 16:56:39 +0000 Subject: [PATCH] Create cached fibonacci algorithm (#8084) * feat: Add `fib_recursive_cached` func * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * doc: Show difference in time when caching algorithm Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- maths/fibonacci.py | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/maths/fibonacci.py b/maths/fibonacci.py index e0da66ee5..d58c9fc68 100644 --- a/maths/fibonacci.py +++ b/maths/fibonacci.py @@ -16,6 +16,7 @@ fib_memoization runtime: 0.0107 ms fib_binet runtime: 0.0174 ms """ +from functools import lru_cache from math import sqrt from time import time @@ -92,6 +93,39 @@ def fib_recursive(n: int) -> list[int]: return [fib_recursive_term(i) for i in range(n + 1)] +def fib_recursive_cached(n: int) -> list[int]: + """ + Calculates the first n (0-indexed) Fibonacci numbers using recursion + >>> fib_iterative(0) + [0] + >>> fib_iterative(1) + [0, 1] + >>> fib_iterative(5) + [0, 1, 1, 2, 3, 5] + >>> fib_iterative(10) + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + >>> fib_iterative(-1) + Traceback (most recent call last): + ... + Exception: n is negative + """ + + @lru_cache(maxsize=None) + def fib_recursive_term(i: int) -> int: + """ + Calculates the i-th (0-indexed) Fibonacci number using recursion + """ + if i < 0: + raise Exception("n is negative") + if i < 2: + return i + return fib_recursive_term(i - 1) + fib_recursive_term(i - 2) + + if n < 0: + raise Exception("n is negative") + return [fib_recursive_term(i) for i in range(n + 1)] + + def fib_memoization(n: int) -> list[int]: """ Calculates the first n (0-indexed) Fibonacci numbers using memoization @@ -163,8 +197,9 @@ def fib_binet(n: int) -> list[int]: if __name__ == "__main__": - num = 20 + num = 30 time_func(fib_iterative, num) - time_func(fib_recursive, num) + time_func(fib_recursive, num) # Around 3s runtime + time_func(fib_recursive_cached, num) # Around 0ms runtime time_func(fib_memoization, num) time_func(fib_binet, num)