斐波那契-很大的n个数字的六个最高有效数字(最右边)

时间:2019-09-30 20:07:44

标签: python fibonacci

我试图通过仅保留最右边的六个数字来有效地计算第n个斐波那契值,该值可能非常大。例如fib(1000000)仅返回546875。

我知道一些递归矩阵求幂算法,并且我一直在测试O(log n)实现,如下所示-

def solution(n):
    fibs = {0: 0, 1: 1}

    def fib(n):
    # recursive helper function
        if n in fibs: 
            return fibs[n]
        if n % 2 == 0:
            fibs[n] = ((2 * fib((n / 2) - 1)) + fib(n / 2)) * fib(n / 2) % 1000000
            return fibs[n]
        else:
            fibs[n] = (fib((n - 1) / 2) ** 2) + (fib((n+1) / 2) ** 2) % 1000000
            return fibs[n]

    answer = fib(n)
    return answer % 1000000

所有答案似乎都有效,直到n =1000000。所有后来的10指数应该返回相同的答案吗? 10 ^ k,其中k = [7、8、9、10 ...]全部返回546875(一百万的值)。我认为它们应该是因为当您将它们乘以10 ^ 6时,这些值具有相同的零余数。所以我想知道这种实现是否正确?

1 个答案:

答案 0 :(得分:2)

因此,我做了一些简单的代码来证明/反证您当前的定理,我偶然发现了这种特殊的模式:代码的最后6位的斐波那契数列似乎每150万个序列重复一次。

这是100万,1000万,1亿等值匹配的部分原因; 1000万-900万= 100万,但900万= 6 * 150万。

因此,要回答您的问题,您需要在代码中实现的所有步骤是:首先将模数n乘以1,500,000,然后计算答案,例如:

answer = fib(n%1500000)

我已经提供了我用来查找模数何时重复的代码(find_repeating_length)以及以下用于检查模数是否按预期工作的函数(检查)。

希望有帮助!

def solution(n):
    fibs = {0: 0, 1: 1}

    def fib(n):
        # simple linear-time fib function
        if n in fibs:
            return fibs[n]
        fibs[n] = (fibs[n-1]+fibs[n-2]) % 1000000
        return fibs[n]

    def find_repeating_length():
        find_number = [0, 1] # find these two numbers of the sequence
        for i in range(0, 10000001):
            n_0 = fib(i)
            if (n_0 in find_number):
                print(str(n_0) + ":" + str(i))

    def check(): # check that first 10,000,000 nums follow sequence
        for i in range(2, 10000001): 
            n_0 = fib(i)
            if (i >= 1500000):
                left = n_0
                right = fib(i - 1500000)
                # if (left == right):
                #    print("Success at " + str(i) + " Values: " +
                #          str(n_0))
                if (left != right):
                    return("Fail at " + str(i) + " Values: " +
                           str(n_0) + ":" + str(right))

            return "Success, repeats"
    find_repeating_length()
    print(check())


solution()

输出(格式简短,以value:sequence格式输出)

  

0:0   1:1   1:2   0:750000   1:1499999

     

0:1500000   1:1500001   1:1500002   0:2250000   1:2999999

     

0:3000000   1:3000001   1:3000002   0:3750000   1:4499999

     

0:4500000   1:4500001   1:4500002   0:5250000   1:5999999

     

0:6000000   1:6000001   1:6000002   0:6750000   1:7499999

     

0:7500000   1:7500001   1:7500002   0:8250000   1:8999999

     

0:9000000   1:9000001   1:9000002   0:9750000

     

成功,重复