编程拼图 - 斐波那契

时间:2015-08-20 19:31:27

标签: c algorithm

此问题之前存在一些混淆。以前,原始海报和那些回应的人认为这是计算第n个斐波纳契数的破坏函数,但实际上它是一个计算第n个主要斐波那契数的函数,它是来自Stack Exchange的codegolf的编程谜题。

f(n){int i=1,j=0,k;for(;n;n-=k==i)for(j=i-j,i+=j,k=2;i%k&&k++<i;);return i;}

这是

中的C 76字符示例

https://codegolf.stackexchange.com/questions/6994/find-the-nth-fibonnaci-prime-in-the-shortest-code

对于32位有符号整数,n的范围是1到10.前10个素数斐波纳契数是:2,3,5,13,​​89,233,1597,28657,514229,433494437。

问题是这个功能如何运作?

codegolf的原始资料不包括解释。这可能属于codegolf,但之前的问题是在SO处提出的,我希望上一个问题的海报会看到这个问题并回答他/她的问题。

1 个答案:

答案 0 :(得分:3)

让我们先缩进它:

int f(int n)
{
    int i = 1, j = 0, k;
    for (; n; n -= k == i)
        for (j = i - j, i += j, k = 2; i % k && k++ < i;) ;
    return i;
}
对于合理的输入,

n非零,因此第一个循环将执行。请注意,k == i尚未评估,因为第一个for的正文必须先执行,因此k未初始化并不重要。

有关此的更多数学演示,请注意j = f(0) = 0i = f(2) = 1是第一个和第三个Fibonacci数。从n = 2j = f(n-2) = 0i = f(n) = 1开始,为了推进j和i,我们有:

j = i - j = f(n) - f(n-2) = f(n-1)
i = i + j = f(n) + f(n-1) = f(n+1)
n = n + 1

对于每个外部循环,ij将前进到内循环初始化中的下一个斐波那契数字。

j =  1 == f(1), i =  2 == f(3)
j =  1 == f(2), i =  3 == f(4)
j =  2 == f(3), i =  5 == f(5)
j =  3 == f(4), i =  8 == f(6)
j =  5 == f(5), i = 13 == f(7)

这证实了我们的模式:我们可以从前几次迭代中看到ij提前两步。

i % k && k++ < i

这只是一个素性测试:它在k等于i时停止(如果i为素数就会发生这种情况 - 同时k++ < i在技术上永远不会失败是的,因为第一个条件将首先评估为false,但它具有有用的副作用)或ki的正确除数(因此i不是素数)。它不是最有效的,但它确实有效。

k++置于for循环的条件部分可以正确地增加它并保存更多字符(好吧,我认为只有一个)。

n -= k == i

如果i没有素数,则不会更改n,因此将检查下一个斐波纳契数(因为i迭代斐波纳契数列) 。如果i是素数,那么它递减n,它会减少我们找到的素数斐波那契数的数量,并且无论如何都会检查下一个素数。当它达到0时,我们会找到n

  

问题是这个功能如何运作?

它的工作原理是顺序计算Fibonacci数并测试每个数的素数,直到它找到n这样的素数。

一旦你清理了一点代码,就没什么特别的了。很大程度上只是很多人会写的强力算法,虽然由于素性检查而效率稍低,而且由于想要尽可能多地保存字符而难以阅读。

最突出的部分是ij的计算,它使ij提前两步。这个技巧也可能具有保存最多字符的效果。