|
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 Binet formula function uses 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 | +
|
| 12 | +RESULTS: (n = 20) |
| 13 | +fib_iterative runtime: 0.0055 ms |
| 14 | +fib_recursive runtime: 6.5627 ms |
| 15 | +fib_memoization runtime: 0.0107 ms |
| 16 | +fib_binet runtime: 0.0174 ms |
11 | 17 | """
|
12 | 18 |
|
13 | 19 | from math import sqrt
|
@@ -86,6 +92,39 @@ def fib_recursive_term(i: int) -> int:
|
86 | 92 | return [fib_recursive_term(i) for i in range(n + 1)]
|
87 | 93 |
|
88 | 94 |
|
| 95 | +def fib_memoization(n: int) -> list[int]: |
| 96 | + """ |
| 97 | + Calculates the first n (0-indexed) Fibonacci numbers using memoization |
| 98 | + >>> fib_memoization(0) |
| 99 | + [0] |
| 100 | + >>> fib_memoization(1) |
| 101 | + [0, 1] |
| 102 | + >>> fib_memoization(5) |
| 103 | + [0, 1, 1, 2, 3, 5] |
| 104 | + >>> fib_memoization(10) |
| 105 | + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] |
| 106 | + >>> fib_iterative(-1) |
| 107 | + Traceback (most recent call last): |
| 108 | + ... |
| 109 | + Exception: n is negative |
| 110 | + """ |
| 111 | + if n < 0: |
| 112 | + raise Exception("n is negative") |
| 113 | + # Cache must be outside recursuive function |
| 114 | + # other it will reset every time it calls itself. |
| 115 | + cache: dict[int, int] = {0: 0, 1: 1, 2: 1} # Prefilled cache |
| 116 | + |
| 117 | + def rec_fn_memoized(num: int) -> int: |
| 118 | + if num in cache: |
| 119 | + return cache[num] |
| 120 | + |
| 121 | + value = rec_fn_memoized(num - 1) + rec_fn_memoized(num - 2) |
| 122 | + cache[num] = value |
| 123 | + return value |
| 124 | + |
| 125 | + return [rec_fn_memoized(i) for i in range(n + 1)] |
| 126 | + |
| 127 | + |
89 | 128 | def fib_binet(n: int) -> list[int]:
|
90 | 129 | """
|
91 | 130 | Calculates the first n (0-indexed) Fibonacci numbers using a simplified form
|
@@ -127,4 +166,5 @@ def fib_binet(n: int) -> list[int]:
|
127 | 166 | num = 20
|
128 | 167 | time_func(fib_iterative, num)
|
129 | 168 | time_func(fib_recursive, num)
|
| 169 | + time_func(fib_memoization, num) |
130 | 170 | time_func(fib_binet, num)
|
0 commit comments