出于教育目的,我正在使用Python3构建代码以实现此目标:
我认为我在这个问题上做得很好,因为我处于初级/中级水平。这个问题是一个先进而非强制性的问题。
我使用缓慢但较淡的功能作为“对照组”进行了压力测试。之后,我能够创建更快的功能。
但是,对于某些 pisano周期,我的实现存在问题。 正如您在这里看到的那样: http://webspace.ship.edu/msrenault/fibonacci/fiblist.htm 一些mods可以创造巨大的Pisano周期循环...
我的功能对于像< 249这样的mod来说非常快...但是,我不知道如何处理像1570这样的mods,它生成一个总长度为4740个数字的模式/周期...这就是一个ciclical模式不涉及001我们的12113但4740数字...
我试图找到解决这个问题的方法。我能够找到解决问题的不同方法。尽管如此,我想尝试修复我的实现,使其在循环识别部分更快 - 如果这是可能的话......
这是我的代码。
coursera_input = (input())
coursera_input = (coursera_input.split())
n_in = int(coursera_input[0])
mod_in = int(coursera_input[1])
import random
def my_fibo_iter(x):
if x<=1:
return x
else:
bef_previous_elem = 0
previous_elem = 1
current = 0
count = 1
while count<x:
count = count + 1
current = bef_previous_elem + previous_elem
bef_previous_elem = previous_elem
previous_elem = current
return (current)
def fibo_iter_mod_slow(n,mod):
if n==0:
return n%mod
elif n==1:
return n%mod
else:
previous = 1%mod
bef_previous = 0%mod
count = 1
while count<(n):
current = bef_previous%mod + previous%mod
bef_previous = previous%mod
previous = current%mod
count = count + 1
return current%mod
#preciso construir um algoritmo para identificar a pisano period/cycle
def pisano_cycle(big_list):
promising_list = []
for i in big_list:
promising_list.append(i)
p_l_len = len(promising_list)
p_l_final_index = 2*p_l_len
if promising_list == big_list[p_l_len:p_l_final_index]:
break
return promising_list
def generate_big_pisano_list(mod):
big_list = []
if mod<249:
limit = 700
if 249<=mod<1000:
limit = 3001
else:
limit = 6000
for i in range(0,limit):
big_list.append(fibo_iter_mod_slow(i,mod))
return big_list
#agora eu sei gerar uma lista pisano
#sei identificar uma lista de pisano
#preciso de uma outra função
#ela deve, sabendo o padrão CÍCLICO, identificar o nth elemento desse padrão
def fibo_iter_mod_fast(n,mod):
big_pisano_list = generate_big_pisano_list(mod)
pattern = pisano_cycle(big_pisano_list)
length_patt = len(pattern)
index_analogous = (n%length_patt)
output_in_mod = pattern[index_analogous]
return output_in_mod
print (fibo_iter_mod_fast(n_in,mod_in))
如果输入的内容如下:
2816213588 30524
获得正确的输出:
10249
但这需要超过5秒......
另一个问题是当我有一个巨大的数字作为mod的输入时,例如:
案例#12/22失败:(错误回答)
输入:99999999999999999 100000
您的输出:69026
正确输出:90626
(使用时间:0.04 / 5.00,使用的内存:24100864/536870912。)
由于此部分,我的代码返回了错误的输出:
def generate_big_pisano_list(mod):
big_list = []
if mod<249:
limit = 700
if 249<=mod<1000:
limit = 3001
else:
limit = 6000
我将pisano周期的范围限制在60000个数字的范围内,显然,一些pisano周期可以超越这个......
答案 0 :(得分:3)
您应该使用模运算来计算斐波纳契数,而不是计算周期长度,其中有一个对数算法。
所需的迭代总数肯定低于明确计算pisano周期长度所需的迭代次数。
你必须利用的关系是
fib(2n) = fib(n) * ( 2 * fib(n+1) - fib(n) )
fib(2n+1) = fib(n+1) ^ 2 + fib(n) ^ 2
如果在模运算中进行乘法和加法,则可以使用整数数据类型(10 ^ 5 <2 ^ 17)来获得精确的结果。