diff --git a/allalgorithms/numeric/__init__.py b/allalgorithms/numeric/__init__.py index cd1f5cc..5dfa7ad 100644 --- a/allalgorithms/numeric/__init__.py +++ b/allalgorithms/numeric/__init__.py @@ -1 +1,2 @@ -from .max_numbers import find_max \ No newline at end of file +from .max_numbers import find_max +from .fibonacci import fibonacci, fibonacci_memo diff --git a/allalgorithms/numeric/fibonacci.py b/allalgorithms/numeric/fibonacci.py new file mode 100644 index 0000000..e875413 --- /dev/null +++ b/allalgorithms/numeric/fibonacci.py @@ -0,0 +1,44 @@ +# -*- coding: UTF-8 -*- +# +# Numeric Algorithms: Factorials and Memoization +# The All â–²lgorithms library for python +# +# Contributed by: Chance +# Github: @chance-nelson +# + + +def fibonacci(n): + """Compute the Fibonacci sequence number at a certain index + + This is the obvious recursive approach, and runs on the order of O(n*2). + """ + # Base case 1: fibonacci(1) == 0 + if n == 1: + return 0 + + # Base case 2: fibonacci(2) == 1 + elif n == 2: + return 1 + + return fibonacci(n-1) + fibonacci(n-2) + + +def memoize(f): + """Special decorator to add memoization to any recursive function + + Keep a cache of results from past runs. This cache can then be referenced + instead of calling the function again. + """ + memory = {} + + def inner(num): + if num not in memory: + memory[num] = f(num) + + return memory[num] + + return inner + + +fibonacci_memo = memoize(fibonacci) diff --git a/tests/test_numeric.py b/tests/test_numeric.py index 2be532d..a0c9a3f 100644 --- a/tests/test_numeric.py +++ b/tests/test_numeric.py @@ -1,6 +1,7 @@ import unittest from allalgorithms.numeric import find_max +from allalgorithms.fibonacci import fibonacci, fibonacci_memo class TestMax(unittest.TestCase): @@ -9,5 +10,15 @@ def test_find_max_value(self): test_list = [3, 1, 8, 7, 4] self.assertEqual(8, find_max(test_list)) + +class TestFibonacci(unittest.TestCase): + + def test_recursive_fibonacci(self): + self.assertEqual(8, fibonacci(7)) + + def test_memoize_fibonacci(self): + self.assertEqual(8, fibonacci(7)) + + if __name__ == "__main__": unittest.main()