Skip to content

Commit 4fe9bc8

Browse files
committed
Merge branch 'feature/fibonacci' into develop
2 parents 08ae200 + 77d0efc commit 4fe9bc8

File tree

7 files changed

+153
-1
lines changed

7 files changed

+153
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ Set<Integer> set = Sets.newTreeSet();
821821

822822
**Examples**
823823

824-
- Fibonacci number: [c++](cpp-algorithm/src/dp) | Fibonacci sequence is a sequence of numbers where each number is the sum of the two preceding numbers. Fibonacci number is $n$th number in the sequence. The Fibonacci sequence is defined as follows:
824+
- Fibonacci number, CCSP#1.1: [c++](cpp-algorithm/src/dp),[python](python-algorithm/algorithm/dp) | Fibonacci sequence is a sequence of numbers where each number is the sum of the two preceding numbers. Fibonacci number is $n$th number in the sequence. The Fibonacci sequence is defined as follows:
825825
- $F_0 = 0$
826826
- $F_1 = 1$
827827
- $F_n = F_{n-1} + F_{n-2}$ (for $n > 1$)

python-algorithm/algorithm/dp/__init__.py

Whitespace-only changes.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from functools import lru_cache
2+
from typing import Dict
3+
from typing import Generator
4+
5+
6+
def fibonacci_recursive(n: int) -> int:
7+
"""
8+
Calculate the Fibonacci number of the given number.
9+
:param n: input number
10+
:return: Fibonacci number
11+
"""
12+
if n < 2: # base case
13+
return n
14+
return fibonacci_recursive(n - 2) + fibonacci_recursive(n - 1) # recursive case
15+
16+
17+
def fibonacci_memoization(n: int) -> int:
18+
"""
19+
Calculate the Fibonacci number of the given number using memoization.
20+
:param n: input number
21+
:return: Fibonacci number
22+
"""
23+
memo: Dict[int, int] = {0: 0, 1: 1} # our base cases
24+
25+
def helper(m: int) -> int:
26+
if m not in memo:
27+
memo[m] = helper(m - 1) + helper(m - 2) # memoization
28+
return memo[m]
29+
30+
return helper(n)
31+
32+
33+
@lru_cache(maxsize=None)
34+
def fibonacci_automatic_memoization(n: int) -> int:
35+
"""
36+
Calculate the Fibonacci number of the given number using automatic memoization.
37+
It uses the @lru_cache decorator to cache the results of the function.
38+
It has same definition as :func:`fibonacci_recursive`.
39+
:param n: input number
40+
:return: Fibonacci number
41+
"""
42+
if n < 2: # base case
43+
return n
44+
return fibonacci_recursive(n - 2) + fibonacci_recursive(n - 1) # recursive case
45+
46+
47+
def fibonacci_iterative(n: int) -> int:
48+
"""
49+
Calculate the Fibonacci number of the given number using iterative approach.
50+
:param n: input number
51+
:return: Fibonacci number
52+
"""
53+
if n == 0:
54+
return n # special case
55+
_last: int = 0 # initially set to fib(0)
56+
_next: int = 1 # initially set to fib(1)
57+
for _ in range(1, n):
58+
_last, _next = _next, _last + _next
59+
return _next
60+
61+
62+
def fibonacci_generator(n: int) -> Generator[int, None, None]:
63+
"""
64+
Calculate the Fibonacci number of the given number using generator approach.
65+
:param n: input number
66+
:return: Fibonacci number
67+
"""
68+
yield 0 # special case
69+
if n > 0:
70+
yield 1 # special case
71+
_last: int = 0 # initially set to fibonacci(0)
72+
_next: int = 1 # initially set to fibonacci(1)
73+
for _ in range(1, n):
74+
_last, _next = _next, _last + _next
75+
yield _next # main generation step

python-algorithm/algorithm/dp/test/__init__.py

Whitespace-only changes.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from collections import deque
2+
3+
import pytest
4+
5+
import algorithm.dp.fibonacci as fibonacci
6+
7+
8+
@pytest.mark.benchmark(group='fibonacci_recursive')
9+
@pytest.mark.parametrize(
10+
argnames='input_number, expected',
11+
argvalues=[
12+
(5, 5),
13+
(20, 6765),
14+
(30, 832_040)
15+
],
16+
ids=['case1', 'case2', 'case3'])
17+
def test_fibonacci_recursive(benchmark, input_number, expected):
18+
result = benchmark(fibonacci.fibonacci_recursive, input_number)
19+
assert expected == result
20+
21+
22+
@pytest.mark.benchmark(group='fibonacci_memoization')
23+
@pytest.mark.parametrize(
24+
argnames='input_number, expected',
25+
argvalues=[
26+
(5, 5),
27+
(20, 6765),
28+
(30, 832_040)
29+
],
30+
ids=['case1', 'case2', 'case3'])
31+
def test_fibonacci_memoization(benchmark, input_number, expected):
32+
result = benchmark(fibonacci.fibonacci_memoization, input_number)
33+
assert expected == result
34+
35+
36+
@pytest.mark.benchmark(group='fibonacci_automatic_memoization')
37+
@pytest.mark.parametrize(
38+
argnames='input_number, expected',
39+
argvalues=[
40+
(5, 5),
41+
(20, 6765),
42+
(30, 832_040)
43+
],
44+
ids=['case1', 'case2', 'case3'])
45+
def test_fibonacci_automatic_memoization(benchmark, input_number, expected):
46+
result = benchmark(fibonacci.fibonacci_automatic_memoization, input_number)
47+
assert expected == result
48+
49+
50+
@pytest.mark.benchmark(group='fibonacci_iterative')
51+
@pytest.mark.parametrize(
52+
argnames='input_number, expected',
53+
argvalues=[
54+
(5, 5),
55+
(20, 6765),
56+
(30, 832_040)
57+
],
58+
ids=['case1', 'case2', 'case3'])
59+
def test_fibonacci_iterative(benchmark, input_number, expected):
60+
result = benchmark(fibonacci.fibonacci_iterative, input_number)
61+
assert expected == result
62+
63+
64+
@pytest.mark.benchmark(group='fibonacci_generator')
65+
@pytest.mark.parametrize(
66+
argnames='input_number, expected',
67+
argvalues=[
68+
(5, 5),
69+
(20, 6765),
70+
(30, 832_040)
71+
],
72+
ids=['case1', 'case2', 'case3'])
73+
def test_fibonacci_generator(benchmark, input_number, expected):
74+
result = benchmark(fibonacci.fibonacci_generator, input_number)
75+
assert expected == deque(result, maxlen=1).pop()

python-algorithm/algorithm/search/test/test_dna_search.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
23
from algorithm.search.dna_search import Nucleotide, string_to_gene, linear_contains, binary_contains
34

45

python-algorithm/algorithm/search/test/test_generic_search.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
23
from algorithm.search.generic_search import generic_linear_contains, generic_binary_contains
34

45

0 commit comments

Comments
 (0)