|
1 | 1 | # fibonacci.py
|
2 | 2 | """
|
3 |
| -Calculates the Fibonacci sequence using iteration, recursion, and a simplified |
4 |
| -form of Binet's formula |
| 3 | +Calculates the Fibonacci sequence using iteration, recursion, memoization, |
| 4 | +and a simplified form of Binet's formula |
5 | 5 |
|
6 |
| -NOTE 1: the iterative and recursive functions are more accurate than the Binet's |
7 |
| -formula function because the iterative function doesn't use floats |
| 6 | +NOTE 1: the iterative, recursive, memoization functions are more accurate than |
| 7 | +the Binet's formula function because the iterative function doesn't use floats |
8 | 8 |
|
9 | 9 | NOTE 2: the Binet's formula function is much more limited in the size of inputs
|
10 | 10 | that it can handle due to the size limitations of Python floats
|
11 | 11 | """
|
12 | 12 |
|
13 | 13 | from math import sqrt
|
14 | 14 | from time import time
|
| 15 | +from typing import Callable |
15 | 16 |
|
16 | 17 |
|
17 | 18 | def time_func(func, *args, **kwargs):
|
@@ -86,6 +87,35 @@ def fib_recursive_term(i: int) -> int:
|
86 | 87 | return [fib_recursive_term(i) for i in range(n + 1)]
|
87 | 88 |
|
88 | 89 |
|
| 90 | +def fib_memoization() -> Callable[[int], int]: |
| 91 | + """ |
| 92 | + Calculates the nth fibonacci number using Memoization |
| 93 | + >>> fib_memoization()(5) |
| 94 | + 5 |
| 95 | + >>> fib_memoization()(100) |
| 96 | + 354224848179261915075 |
| 97 | + >>> fib_memoization()(25) |
| 98 | + 75025 |
| 99 | + >>> fib_memoization()(40) |
| 100 | + 102334155 |
| 101 | + """ |
| 102 | + # Cache must be outside recursuive function |
| 103 | + # other it will reset every time it calls itself. |
| 104 | + cache: dict[int, int] = {1: 1, 2: 1} # Prefilled cache |
| 105 | + |
| 106 | + def rec_fn_memoized(num: int) -> int: |
| 107 | + if num < 1: |
| 108 | + raise Exception("n is negative") |
| 109 | + if num in cache: |
| 110 | + return cache[num] |
| 111 | + |
| 112 | + value = rec_fn_memoized(num - 1) + rec_fn_memoized(num - 2) |
| 113 | + cache[num] = value |
| 114 | + return value |
| 115 | + |
| 116 | + return rec_fn_memoized |
| 117 | + |
| 118 | + |
89 | 119 | def fib_binet(n: int) -> list[int]:
|
90 | 120 | """
|
91 | 121 | Calculates the first n (0-indexed) Fibonacci numbers using a simplified form
|
@@ -127,4 +157,5 @@ def fib_binet(n: int) -> list[int]:
|
127 | 157 | num = 20
|
128 | 158 | time_func(fib_iterative, num)
|
129 | 159 | time_func(fib_recursive, num)
|
| 160 | + time_func(fib_memoization(), num) |
130 | 161 | time_func(fib_binet, num)
|
0 commit comments