Skip to content

Commit 527ea43

Browse files
committed
Fix: Multiple errors in fibonacci search.
- Test lists were not ordered, this is required for Fibonacci search - Place documentation of function inside function - Create multiple different tests including, float, char and negatives - Add type hints in line with TheAlgorithms#2128
1 parent 2388bf4 commit 527ea43

File tree

1 file changed

+88
-38
lines changed

1 file changed

+88
-38
lines changed

Diff for: searches/fibonacci_search.py

+88-38
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,101 @@
1-
# run using python fibonacci_search.py -v
2-
31
"""
4-
@params
5-
arr: input array
6-
val: the value to be searched
7-
output: the index of element in the array or -1 if not found
8-
return 0 if input array is empty
2+
This is pure Python implementation of fibonacci search.
3+
4+
Resources used:
5+
https://en.wikipedia.org/wiki/Fibonacci_search_technique
6+
7+
For doctests run following command:
8+
python3 -m doctest -v fibonacci_search.py
9+
10+
For manual testing run:
11+
python3 fibonacci_search.py
912
"""
13+
from __future__ import annotations
14+
from functools import lru_cache
15+
import sys
16+
17+
18+
@lru_cache()
19+
def fibonacci(k: int) -> int:
20+
"""Finds fibonacci number in index k.
1021
22+
Parameters
23+
----------
24+
k : int
25+
Index of fibonacci.
1126
12-
def fibonacci_search(arr, val):
27+
Returns
28+
-------
29+
int
30+
Fibonacci number in position k.
1331
32+
>>> print(fibonacci(0))
33+
0
34+
>>> print(fibonacci(2))
35+
1
36+
>>> print(fibonacci(5))
37+
5
38+
>>> print(fibonacci(15))
39+
610
1440
"""
15-
>>> fibonacci_search([1,6,7,0,0,0], 6)
41+
if k == 0:
42+
return 0
43+
elif k == 1:
44+
return 1
45+
else:
46+
return fibonacci(k - 1) + fibonacci(k - 2)
47+
48+
49+
def fibonacci_search(arr: List[int], val: int) -> int:
50+
"""A pure Python implementation of a fibonacci search algorithm.
51+
52+
Parameters
53+
----------
54+
arr : List[int]
55+
List of sorted elements.
56+
val : int
57+
Element to search in list.
58+
59+
Returns
60+
-------
61+
int
62+
The index of the element in the array.
63+
-1 if the element is not found.
64+
65+
>>> print(fibonacci_search([4, 5, 6, 7], 4))
66+
0
67+
>>> print(fibonacci_search([4, 5, 6, 7], -10))
68+
-1
69+
>>> print(fibonacci_search([-18, 2], -18))
70+
0
71+
>>> print(fibonacci_search([5], 5))
72+
0
73+
>>> print(fibonacci_search(['a', 'c', 'd'], 'c'))
1674
1
17-
>>> fibonacci_search([1,-1, 5, 2, 9], 10)
75+
>>> print(fibonacci_search(['a', 'c', 'd'], 'f'))
1876
-1
77+
>>> print(fibonacci_search([], 1))
78+
-1
79+
>>> print(fibonacci_search([.1, .4 , 7], .4))
80+
1
1981
>>> fibonacci_search([], 9)
20-
0
82+
-1
2183
"""
22-
fib_N_2 = 0
23-
fib_N_1 = 1
24-
fibNext = fib_N_1 + fib_N_2
25-
length = len(arr)
26-
if length == 0:
27-
return 0
28-
while fibNext < len(arr):
29-
fib_N_2 = fib_N_1
30-
fib_N_1 = fibNext
31-
fibNext = fib_N_1 + fib_N_2
32-
index = -1
33-
while fibNext > 1:
34-
i = min(index + fib_N_2, (length - 1))
35-
if arr[i] < val:
36-
fibNext = fib_N_1
37-
fib_N_1 = fib_N_2
38-
fib_N_2 = fibNext - fib_N_1
39-
index = i
40-
elif arr[i] > val:
41-
fibNext = fib_N_2
42-
fib_N_1 = fib_N_1 - fib_N_2
43-
fib_N_2 = fibNext - fib_N_1
44-
else:
45-
return i
46-
if (fib_N_1 and index < length - 1) and (arr[index + 1] == val):
47-
return index + 1
48-
return -1
84+
n = len(arr)
85+
# Find m such that F_m >= n where F_i is the i_th fibonacci number.
86+
m = next(x for x in range(sys.maxsize ** 10) if fibonacci(x) >= n)
87+
k = m
88+
offset = 0
89+
while k != 0:
90+
if arr[offset + fibonacci(k - 1)] == val:
91+
return fibonacci(k - 1)
92+
elif val < arr[offset + fibonacci(k - 1)]:
93+
k = k - 1
94+
elif val > arr[offset + fibonacci(k - 1)]:
95+
offset += fibonacci(k - 2)
96+
k = k - 2
97+
else:
98+
return -1
4999

50100

51101
if __name__ == "__main__":

0 commit comments

Comments
 (0)