我的Fibonacci序列发生器出了什么问题?

时间:2013-04-16 00:31:51

标签: python fibonacci

我正在尝试解决Problem #25 on Project Euler。这是我到目前为止所得到的:

def fibonacci(length):
    fibs = [0,1]
    while length > len(fibs):
        fibs.append(fibs[-1] + fibs[-2])        
    return fibs

fibs = fibonacci(5000)

for i in fibs:
    if len(str(i)) > 1000:
        print i

        ## The location of the number in the Fibonacci set.
        print [j for j, x in enumerate(fibs) if x == i]

我测试的每个号码(包括一些large ones)都会出现一个匹配项,但Project Euler并不接受我得到的答案。

我读到答案是第4782个数字,但我得到的是第一个超过1000位的数字是4787,

11867216745258291596767088485966669273798582100095758927648586619975930687764095025968215177396570693265703962438125699711941059562545194266075961811883693134762216371218311196004424123489176045121333888565534924242378605373120526670329845322631737678903926970677861161240351447136066048164999599442542656514905088616976279305745609791746515632977790194938965236778055329967326038544356209745856855159058933476416258769264398373862584107011986781891656652294354303384242672408623790331963965457196174228574314820977014549061641307451101774166736940218594168337251710513138183086237827524393177246011800953414994670315197696419455768988692973700193372678236023166645886460311356376355559165284374295661676047742503016358708348137445254264644759334748027290043966390891843744407845769620260120918661264249498568399416752809338209739872047617689422485537053988895817801983866648336679027270843804302586168051835624516823216354234081479331553304809262608491851078404280454207286577699580222132259241827433

和项目欧拉说我尝试的每一个答案都是错误的。 (显然我还没试过4782,因为那会是作弊。)

我非常接近,显然出现了问题,但是什么?

6 个答案:

答案 0 :(得分:3)

您正在检查len(str(i)) > 1000,根据问题陈述,您应该检查len(str(i)) == 1000

此外,您误解了您作为斐波那契数字链接的答案中的数字。实际上,如果你仔细阅读,那就是调用fib函数的次数。您的斐波那契数4782是正确的。

答案 1 :(得分:2)

根据第25个问题解决方案的projecteuler论坛,你是对的。

和以1322开头的第二个大数字......不是斐波纳契数。

检查x是否为斐波纳契数的一些函数:

   import decimal
   def check_fib(n):
       a, b = decimal.Decimal(5*(n**2) + 4), decimal.Decimal(5*(n**2) - 4)
       return any(int(x.sqrt())==x for x in (a, b))

答案 2 :(得分:1)

正如thkang所指出的那样,伙计号码是错误的,请参阅wims评论。你的算法有效。

def fibonacci(length):
    fibs = [0,1]
    while length > len(fibs):
        fibs.append(fibs[-1] + fibs[-2])        
    return fibs

fibs = fibonacci(5000)
for i,n in enumerate(fibs):

    if len(str(n)) >= 1000:
        print i
        print n
        break

以下是我以前解决的问题,我得到的答案与你相同。

def fib():
    x, y = 0, 1
    while True:
        yield x
        x += y
        x, y = y, x
f = fib()
for i,n in enumerate(f):
    if len(str(n)) >= 1000:
        print i
        print n
        break

答案 3 :(得分:1)

除问题(和问题)外,您还可以使用Generating Functionology Fibonnaci函数直接获取fibonnaci数字。

from decimal import Decimal
from math import sqrt

#sqrt_5 = Decimal(sqrt(5))
sqrt_5 = decimal.Decimal(5).sqrt() # As thkang suggested!
fib = lambda n: (1/sqrt_5)*( (2/(-1+ sqrt_5))**(n+1) - (2/(-1-sqrt_5))**(n+1))

for i in xrange(10000):
   if fib(i).adjusted()+1 == 1000:
      print i+1

4782是第一个有1000位数字的代码。

产出:[4782,4783,4784,4785 4786]。

关于使用生成函数http://www.math.ufl.edu/~joelar/generatingfibonacci.pdf

的斐波纳契公式

答案 4 :(得分:0)

您可以在没有任何编程的情况下找到解决方案。

我们知道,如果数字m在十进制表示中使用至少k个数字 log_10(M)的GT。= K-1

所以基本上我们所要做的就是解决不平等问题:

log_10(F_N)GT; = 999

使用F_n的显式形式,您知道它是((1 + Sqrt(5))/ 2)^ n / Sqrt(5)的最接近整数。我们可以将此近似值用于F_n。请记住,这有一个小错误,但我们稍后会处理它。

所以不平等就变成了:

log_10(((1 + SQRT(5))/ 2)^ N / SQRT(5))> = 999

使用一些对数身份和一些排序后,它看起来像:

N'GT; =(999 + log_10(SQRT(5)))/ log_10((1 + SQRT(5))/ 2)〜= 4781.8592

所以我们的最终答案应该是围绕着这个,让我们讨论一下我之前提到过的错误。 近似误差是((1-Sqrt(5))/ 2)^ n / Sqrt(5)。 (1-Sqrt(5))/ 2~ = -0.68,其绝对值小于1,所以在取幂后,它越来越接近0.(-0.68)^ 4781是一个非常小的数,所以区别在F_n的对数和我们使用的近似值(那些是大约1000的数字)之间甚至更小。如果不精确计算,考虑到F_n的大小,可以完全忽略这种差异。 因此,解是最小整数n,其中n> = 4781.8592,即4782。

答案 5 :(得分:0)

此生成器提供整数,我已经测试了fib(21)

from decimal import Decimal
from math import sqrt

while True:
#sqrt_5 = Decimal(sqrt(5))
    sqrt_5 = Decimal(5).sqrt() # As thkang suggested!
    fib = lambda n: (1/sqrt_5)*( (2/(-1+ sqrt_5))**(n) - (2/(-1-sqrt_5))**(n))
    a=input()
    if a=="x":
        break
    d=round(fib(int(a)))

    print("\t"+str(d))

要退出该计划,只需输入x

即可