-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnth_for_fibonacci.py
57 lines (44 loc) · 1.86 KB
/
nth_for_fibonacci.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
from math import sqrt
from math import floor
import decimal
def nth_fib(x, _len):
"""Calculating nth term through Binet's formula with accurate intefer precision"""
decimal.getcontext().prec = _len * 2
nth_fib = (
(1 + decimal.Decimal(5).sqrt()) ** x - (1 - decimal.Decimal(5).sqrt()) ** x
) / (2 ** x * decimal.Decimal(5).sqrt())
return int(nth_fib)
def nth_fib_without_precision(x, _len):
"""Calculating nth term through Binet's formula with no accurate precision (incorrect digits after 13th)"""
nth_fib = (
(1 + decimal.Decimal(5).sqrt()) ** x - (1 - decimal.Decimal(5).sqrt()) ** x
) / (2 ** x * decimal.Decimal(5).sqrt())
return int(nth_fib)
def nth_fib_len(x, _len):
return len(str(nth_fib(x, _len)))
def nth_for_fib(number):
"""Yields the nth position"""
str_number = str(number)
_len = len(str_number)
n = (
6 + 5 * (int(_len * 0.75) - 1) + 4 * round((3 * (_len - 1)) / 13)
if _len == 8 or _len == 4
else 6 + 5 * int(_len * 0.75) + 4 * round((3 * (_len - 1)) / 13)
)
n_begin, n_end, n_hop, n_jump = n - 5, n + 5, n + 10, n + 15
if _len > nth_fib_len(n, _len):
if _len == nth_fib_len(n_end, _len):
nth = [n, n_end + 3]
elif _len == nth_fib_len(n_hop, _len):
nth = [n_end, n_hop + 3]
elif _len == nth_fib_len(n_jump, _len):
nth = [n_hop, n_jump + 3]
else:
raise ValueError(
"Uh oh! The number is over 8.88e187 or 901th place. For some reason the equation for n doesn't work with numbers over 8.88e187. I'll have to work on the n's algorithm more for this."
)
elif _len <= nth_fib_len(n, _len):
nth = [n_begin, n]
for _ in range(nth[0], nth[1] + 1):
if list(str_number)[:13] == list(str(nth_fib_without_precision(_, _len)))[:13]:
yield _