简体   繁体   English

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

[英]What's wrong with my Fibonacci sequence generator?

I'm trying to solve Problem #25 on Project Euler . 我正试图解决Project Euler上的问题#25 Here's what I've got so far: 这是我到目前为止所得到的:

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]

Every number I've tested for (including some large ones ) comes out with a match, but Project Euler isn't accepting the answer I'm getting. 我测试过的每个数字(包括一些大数字 )都会出现一个匹配,但Project Euler并不接受我得到的答案。

I read that the answer is the 4782th number, but I'm getting that the first number with over 1000 digits is the 4787th, 我读到答案是第4782个数字,但我得到的是第一个超过1000位的数字是4787,

11867216745258291596767088485966669273798582100095758927648586619975930687764095025968215177396570693265703962438125699711941059562545194266075961811883693134762216371218311196004424123489176045121333888565534924242378605373120526670329845322631737678903926970677861161240351447136066048164999599442542656514905088616976279305745609791746515632977790194938965236778055329967326038544356209745856855159058933476416258769264398373862584107011986781891656652294354303384242672408623790331963965457196174228574314820977014549061641307451101774166736940218594168337251710513138183086237827524393177246011800953414994670315197696419455768988692973700193372678236023166645886460311356376355559165284374295661676047742503016358708348137445254264644759334748027290043966390891843744407845769620260120918661264249498568399416752809338209739872047617689422485537053988895817801983866648336679027270843804302586168051835624516823216354234081479331553304809262608491851078404280454207286577699580222132259241827433

and Project Euler is saying every answer I've tried is wrong. 和项目欧拉说我尝试过的每个答案都是错误的。 (Obviously I didn't try 4782 yet, as that would be cheating.) (显然我还没试过4782,因为那会是作弊。)

I'm tantalizingly close, and clearly something is going wrong, but what? 我非常接近,显然出现了问题,但是什么呢?

You are checking len(str(i)) > 1000 , when according to the problem statement you should be checking len(str(i)) == 1000 . 您正在检查len(str(i)) > 1000 ,根据问题陈述,您应该检查len(str(i)) == 1000

Additionally, you misinterpreted the number in the answer you've linked as a fibonacci number. 此外,您误解了您作为斐波那契数字链接的答案中的数字。 Actually, if you read carefully, it's the number of times the fib function is called. 实际上,如果你仔细阅读,那就是调用fib函数的次数。 Your fibonacci number 4782 is correct. 您的斐波那契数4782是正确的。

according to the projecteuler forum for solvers of 25th problem, you're correct. 根据第25个问题解决方案的projecteuler论坛,你是对的。

and the second big number which starts with 1322... is not a fibonacci number. 从1322开始的第二个大数字......不是斐波纳契数。

some function to check whether x is a fibonacci number: 一些函数来检查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))

As thkang pointed out that guys number is wrong, See wims comment. 正如thkang所指出的那样,伙计数量是错误的, 请参阅wims评论。 Your algorithm works. 你的算法有效。

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

Here is what I used to solve it and I get the same answers that you do. 以下是我用来解决它的问题,我得到了你所做的相同答案。

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

In addition to the question (and problem), you can use the Generating Functionology Fibonnaci Function to get the fibonnaci numbers in a direct way. 除问题(和问题)外,您还可以使用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 is the first with 1000 digits for my code. 4782是我的代码的第一个1000位数字。

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

About fibonnaci formula using Generating Functions http://www.math.ufl.edu/~joelar/generatingfibonacci.pdf 关于使用生成函数的fibonnaci公式http://www.math.ufl.edu/~joelar/generatingfibonacci.pdf

You can get to the solution without any programming. 您无需任何编程即可获得解决方案。

We know, that a number m uses at least k digits in decimal representation if log_10(m)>=k-1. 我们知道,如果log_10(m)> = k-1,则数字m在十进制表示中至少使用k个数字。

So basically all we have to do is to solve the inequality: 所以基本上我们所要做的就是解决不平等问题:

log_10(F_n)>=999 log_10(F_N)> = 999

Using the explicit form of F_n, you know it is the closest integer to ((1+Sqrt(5))/2)^n/Sqrt(5). 使用F_n的显式形式,您知道它是((1 + Sqrt(5))/ 2)^ n / Sqrt(5)的最接近整数。 We can use this approximation for F_n. 我们可以将此近似值用于F_n。 Keep in mind there is a small error in this, but we will handle it later. 请记住,这有一个小错误,但我们稍后会处理。

So the inequality becomes: 所以不平等就变成了:

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

After using some logarithmic identities and some ordering it looks like: 使用一些对数身份和一些排序后,它看起来像:

n>=(999+log_10(Sqrt(5)))/log_10((1+Sqrt(5))/2)~=4781.8592 N> =(999 + log_10(SQRT(5)))/ log_10((1 + SQRT(5))/ 2)〜= 4781.8592

So our final answer should be somewhere around this, let's discuss the error I've mentioned earlier. 所以我们的最终答案应该是围绕着这个,让我们来讨论我之前提到过的错误。 The approximation error is ((1-Sqrt(5))/2)^n/Sqrt(5). 近似误差是((1-Sqrt(5))/ 2)^ n / Sqrt(5)。 (1-Sqrt(5))/2~=-0.68, its absolute value is smaller than 1, so after exponentiation, it gets closer and closer to 0. (-0.68)^4781 is a very small number, so the difference between the logarithm of F_n and its approximation we used (those are numbers around 1000) is even smaller. (1-Sqrt(5))/ 2~ = -0.68,其绝对值小于1,所以在取幂后,它越来越接近0.(-0.68)^ 4781是一个非常小的数,所以区别在F_n的对数和我们使用的近似值(那些是大约1000的数字)之间甚至更小。 Without calculating it exactly, considering the magnitude of F_n this difference can be completely neglected. 如果不精确计算,考虑到F_n的大小,可以完全忽略这种差异。 Thus, the solution is the smallest integer n, for which n>=4781.8592, that is 4782. 因此,解是最小整数n,其中n> = 4781.8592,即4782。

This generator gives integer numbers and I have tested it up to fib(21) 这个生成器给出整数,我测试了它到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))

To quit the program, just type x 要退出程序,只需键入x

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM