forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfibonacci_search.py
103 lines (87 loc) · 2.19 KB
/
fibonacci_search.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""
This is pure Python implementation of fibonacci search.
Resources used:
https://en.wikipedia.org/wiki/Fibonacci_search_technique
For doctests run following command:
python3 -m doctest -v fibonacci_search.py
For manual testing run:
python3 fibonacci_search.py
"""
import sys
from functools import lru_cache
@lru_cache
def fibonacci(k: int) -> int:
"""Finds fibonacci number in index k.
Parameters
----------
k : int
Index of fibonacci.
Returns
-------
int
Fibonacci number in position k.
>>> print(fibonacci(0))
0
>>> print(fibonacci(2))
1
>>> print(fibonacci(5))
5
>>> print(fibonacci(15))
610
"""
if k == 0:
return 0
elif k == 1:
return 1
else:
return fibonacci(k - 1) + fibonacci(k - 2)
def fibonacci_search(arr: list, val: int) -> int:
"""A pure Python implementation of a fibonacci search algorithm.
Parameters
----------
arr : list
List of sorted elements.
val : int
Element to search in list.
Returns
-------
int
The index of the element in the array.
-1 if the element is not found.
>>> print(fibonacci_search([4, 5, 6, 7], 4))
0
>>> print(fibonacci_search([4, 5, 6, 7], -10))
-1
>>> print(fibonacci_search([-18, 2], -18))
0
>>> print(fibonacci_search([5], 5))
0
>>> print(fibonacci_search(['a', 'c', 'd'], 'c'))
1
>>> print(fibonacci_search(['a', 'c', 'd'], 'f'))
-1
>>> print(fibonacci_search([], 1))
-1
>>> print(fibonacci_search([.1, .4 , 7], .4))
1
>>> fibonacci_search([], 9)
-1
"""
n = len(arr)
# Find m such that F_m >= n where F_i is the i_th fibonacci number.
m = next(x for x in range(sys.maxsize ** 10) if fibonacci(x) >= n)
k = m
offset = 0
while k != 0:
if arr[offset + fibonacci(k - 1)] == val:
return fibonacci(k - 1)
elif val < arr[offset + fibonacci(k - 1)]:
k = k - 1
elif val > arr[offset + fibonacci(k - 1)]:
offset += fibonacci(k - 2)
k = k - 2
else:
return -1
if __name__ == "__main__":
import doctest
doctest.testmod()