-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPisanoPeriodTable.py
121 lines (103 loc) · 3.06 KB
/
PisanoPeriodTable.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python
""" Pisano period.
"""
__author__ = 'Andrew Rowles'
__email__ = '[email protected]'
import numpy as np
# The list length of the Fibonacci Sequence
FIB_LIM = 15000
MODULO = list(range(1598,10000))
#MODULO = 3
def F():
""" Generate sequence of Fibonacci numbers.
"""
a, b = 0, 1
yield 0
while True:
a, b = b, a + b
yield a
def fibonacci_modulo(lim=FIB_LIM, mod=MODULO):
""" Generate sequence of Fibonacci numbers modulo mod.
Parameters
----------
lim: integer
The number of Fibonacci numbers to generate.
mod: integer
The modulo.
Return a list of the Fibonacci numbers modulo.
"""
fibs = []
fib_seq = F()
for n in range(lim):
fibs.append(next(fib_seq) % mod)
return fibs
def find_period(l):
""" Finds the period of list of numbers.
Parameters
----------
l: integer[]
The sequence of numbers.
Return
------
steps: integer
The period.
Returns None, if no period is found.
"""
steps = 1
for i in range(1, len(l)):
if l[i] == l[0]:
if l[:i] == l[i:i+i]:
return steps
steps += 1
return None
def pisano_period(mod=MODULO, lim=FIB_LIM, console=False):
""" Calculate the Pisano period.
Parameters
----------
mod: integer
...
lim: integer
...
"""
# Sequence of Fibonacci numbers modulo mod
mod_fibs = fibonacci_modulo(mod=mod, lim=lim)
# Find the Pisano period
period = find_period(mod_fibs)
if console and period:
print('Pisano Period modulo %s' % mod)
print('Period Length: %s' % find_period(mod_fibs))
s = mod_fibs[:period]
string = ' '.join(str(e) for e in s)
string = string.replace(' 0 ','\n0 ')
#print(string)
print('---')
# Nateloop
focus = mod/2
for ii in range(0,len(s)):
if s[ii] > focus:
s[ii] = mod-s[ii]
string = ' '.join(str(e) for e in s)
string = string.replace(' 0 ','\n0 ')
#print(string)
# pie chart of Nateloop
# generate slices
per = find_period(mod_fibs)
ratio = 100 / per
s_flip = [-e+max(s) for e in s]
# convert Pisano period to grayscale hex values
s0 = [hex(round(255 * e/max(s_flip))) for e in s] # stretch range to 0-255
s0 = [e.replace('0x','') for e in s0] # remove 0x from beginning
for ii in range(0,len(s0)):
if len(s0[ii]) == 1:
s0[ii] = '0' + s0[ii]
s0 = ['#'+e*3 for e in s0]
zeroes = s.count(0)
return mod,find_period(mod_fibs),zeroes
def main():
chart = []
for ii in range(min(MODULO),max(MODULO)+1):
[m,p,z] = pisano_period(ii,FIB_LIM,True)
chart.append([m,p,z])
return chart
table = main()
np.savetxt('table_'+str(min(MODULO)+1)+'_'+str(max(MODULO)+1)+'.csv',table,delimiter=',')