Skip to content

Commit 21581ea

Browse files
polosodhruvmanila
poloso
andauthored
Fix: Multiple errors in fibonacci search. (TheAlgorithms#2659)
* 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 * Fix: sort of modules and delete typehint. * Apply suggestions from code review Co-authored-by: Dhruv <[email protected]> * Correct invocation of lru_cache. * Add check for input in fibonacci and doctest. * Correct typehints to comply to numpy style. * Correct ValueError to TypeError. Co-authored-by: Dhruv <[email protected]> * Correct doctest for TypeError. * Rename single letter names as mentioned in CONTRIBUTING.md. * Fix: Bug in big lists. * Remove print(.) in doctests. * Refactor iterator to while loop. * Update searches/fibonacci_search.py Co-authored-by: Dhruv <[email protected]>
1 parent ef53bbd commit 21581ea

File tree

1 file changed

+116
-38
lines changed

1 file changed

+116
-38
lines changed

Diff for: searches/fibonacci_search.py

+116-38
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,129 @@
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 functools import lru_cache
1014

1115

12-
def fibonacci_search(arr, val):
16+
@lru_cache()
17+
def fibonacci(k: int) -> int:
18+
"""Finds fibonacci number in index k.
1319
20+
Parameters
21+
----------
22+
k :
23+
Index of fibonacci.
24+
25+
Returns
26+
-------
27+
int
28+
Fibonacci number in position k.
29+
30+
>>> fibonacci(0)
31+
0
32+
>>> fibonacci(2)
33+
1
34+
>>> fibonacci(5)
35+
5
36+
>>> fibonacci(15)
37+
610
38+
>>> fibonacci('a')
39+
Traceback (most recent call last):
40+
TypeError: k must be an integer.
41+
>>> fibonacci(-5)
42+
Traceback (most recent call last):
43+
ValueError: k integer must be greater or equal to zero.
1444
"""
15-
>>> fibonacci_search([1,6,7,0,0,0], 6)
45+
if not isinstance(k, int):
46+
raise TypeError("k must be an integer.")
47+
if k < 0:
48+
raise ValueError("k integer must be greater or equal to zero.")
49+
if k == 0:
50+
return 0
51+
elif k == 1:
52+
return 1
53+
else:
54+
return fibonacci(k - 1) + fibonacci(k - 2)
55+
56+
57+
def fibonacci_search(arr: list, val: int) -> int:
58+
"""A pure Python implementation of a fibonacci search algorithm.
59+
60+
Parameters
61+
----------
62+
arr
63+
List of sorted elements.
64+
val
65+
Element to search in list.
66+
67+
Returns
68+
-------
69+
int
70+
The index of the element in the array.
71+
-1 if the element is not found.
72+
73+
>>> fibonacci_search([4, 5, 6, 7], 4)
74+
0
75+
>>> fibonacci_search([4, 5, 6, 7], -10)
76+
-1
77+
>>> fibonacci_search([-18, 2], -18)
78+
0
79+
>>> fibonacci_search([5], 5)
80+
0
81+
>>> fibonacci_search(['a', 'c', 'd'], 'c')
1682
1
17-
>>> fibonacci_search([1,-1, 5, 2, 9], 10)
83+
>>> fibonacci_search(['a', 'c', 'd'], 'f')
84+
-1
85+
>>> fibonacci_search([], 1)
1886
-1
87+
>>> fibonacci_search([.1, .4 , 7], .4)
88+
1
1989
>>> fibonacci_search([], 9)
20-
0
90+
-1
91+
>>> fibonacci_search(list(range(100)), 63)
92+
63
93+
>>> fibonacci_search(list(range(100)), 99)
94+
99
95+
>>> fibonacci_search(list(range(-100, 100, 3)), -97)
96+
1
97+
>>> fibonacci_search(list(range(-100, 100, 3)), 0)
98+
-1
99+
>>> fibonacci_search(list(range(-100, 100, 5)), 0)
100+
20
101+
>>> fibonacci_search(list(range(-100, 100, 5)), 95)
102+
39
21103
"""
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
104+
len_list = len(arr)
105+
# Find m such that F_m >= n where F_i is the i_th fibonacci number.
106+
i = 0
107+
while True:
108+
if fibonacci(i) >= len_list:
109+
fibb_k = i
110+
break
111+
i += 1
112+
offset = 0
113+
while fibb_k > 0:
114+
index_k = min(
115+
offset + fibonacci(fibb_k - 1), len_list - 1
116+
) # Prevent out of range
117+
item_k_1 = arr[index_k]
118+
if item_k_1 == val:
119+
return index_k
120+
elif val < item_k_1:
121+
fibb_k -= 1
122+
elif val > item_k_1:
123+
offset += fibonacci(fibb_k - 1)
124+
fibb_k -= 2
125+
else:
126+
return -1
49127

50128

51129
if __name__ == "__main__":

0 commit comments

Comments
 (0)