斐波那契函数或序列


115

斐波纳契数列是数字,其中该序列中的每个数字是其之前的两个数字之和的序列。序列中的前两个数字均为1。

这是前几个词

1 1 2 3 5 8 13 21 34 55 89 ...

编写最短的代码,其中之一:

  • 生成不间断的斐波那契数列。

  • Given n计算n序列的th个项。(索引为1或零)

您可以使用标准形式的输入和输出。

(我提供了两种选择,以防其中一种比另一种更容易用您选择的语言来做。)


对于采用的函数,必须支持n一个相当大的返回值(最小的斐波那契数(Fibonacci number)至少适合您计算机的正常字长)。


排行榜

Answers:


48

Perl 6,10个字符:

匿名无限斐波那契序列列表:

^2,*+*...*

如同:

0, 1, -> $x, $y { $x + $y } ... Inf;

因此,您可以将其分配给数组:

my @short-fibs = ^2, * + * ... *;

要么

my @fibs = 0, 1, -> $x, $y { $x + $y } ... Inf;

并使用以下方法获取前十一个值(从0到10):

say @short-fibs[^11];

或搭配:

say @fibs[^11];

等等,您也可以从匿名列表本身获取前50个数字:

say (^2,*+*...*)[^50]

返回:

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
10946 17711 28657 46368 75025 121393 196418 317811 514229 832040
1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169
63245986 102334155 165580141 267914296 433494437 701408733 1134903170 
1836311903 2971215073 4807526976 7778742049

和一些简单的基准:

real    0m0.966s
user    0m0.842s
sys     0m0.080s

带有:

$ time perl6 -e 'say (^2, *+* ... *)[^50]'

紧急行动


我什至不认为^2可以代替0,1。+1
Konrad Borowski

2
这不再有效,您必须将其写为|^2,*+*...*,与的字节数相同0,1,*+*...*
布拉德·吉尔伯特b2gills,2015年

5
Perl太奇怪了。
Cyoce '16

这个答案写在什么版本的Perl 6上?
CalculatorFeline

3
@CalculatorFeline发生了一个很大的变化,称为GLR(大列表重构),它发生在2015年12月25日首次正式发布之前。直到那个时候,该代码都可以正常工作。
布拉德·吉尔伯特b2gills '18

73

操脑,22招

+>++[-<<[->+>+<<]>>>+]

生成斐波那契数列,该斐波那契数列逐渐在存储带上移动。


5
美丽!绝对美丽!也许不是……反正为此+1 :)
PerHornshøj-Schierbeck2011年

2
在压缩的Brainfuck中为3.344或4个字节。(6 ln(22))/ ln(256)
Will Sherwood

24
16个字节:+[[<+>->+>+<<]>]
primo

3
14个字节:+[.[>+>+<<-]>]
Charlim

2
@Stefnotch当然,较短的是破坏性的。上面的解决方案以磁带上的斐波那契序列结尾,这也是16字节解决方案所做的事情。
primo


37

C#4,58字节

流(69;如果弱键入为65,则为65 IEnumerable

(假设为的using指令System.Collections.Generic。)

IEnumerable<int>F(){int c=0,n=1;for(;;){yield return c;n+=c;c=n-c;}}

单值(58)

int F(uint n,int x=0,int y=1){return n<1?x:F(n-1,y,x+y);}

6
鉴于nuintn==0可以缩短为n<1。通过在泛型类型后舍弃空格并x在比必要范围更大的范围内声明,流可以节省一些字符。实际上,x完全放弃了:n+=c;c=n-c;
Peter Taylor

1
@Peter:谢谢,我有空的时候会编辑。
乔恩·斯基特

您的单值版本只要我的递归lambda表达式能回答...好!
安德鲁·格雷

1
@ wizzwizz4如果我没记错的话,如果!n可以的话,那么n只要你翻转条件就可以了。
Cyoce

3
@JonSkeet Aw。我在这里以为我会在C#击败Jon Skeet ... :-)
wizzwizz4 '18年

32

GolfScript,12岁

现在只有12个字符!

1.{.@.p+.}do

+1不错的工作。如果您输入的字符数少于13个字符,我会立即接受您的回答(当然,除非有人做出的回答更短)。:-P
Chris Jester-Young

1
我喜欢挑战。做完了!;-)
jtjacques 2011年

很好,你赢了。至少,直到某人做得更短(如果可能的话)。:-P
Chris Jester-Young

5
这个定义几乎和“斐波那契”这个名字本身一样短!+1
agent-j

23

> <> -15个字符

0:nao1v LF a+@:n:<o

虽然您可以将其缩短为0:nao1v LF a+@:n:<o您想要的时间。给出15 :)实际上,这也使输出内容更具可读性……
断定

5
13个字符:01r:nao$:@+$r
randomra

21

J,10个字符

使用泰勒级数系数的内置计算,因此可能很少有欺骗性。在这里学到的。

   (%-.-*:)t.

   (%-.-*:)t. 0 1 2 3 4 5 10 100
0 1 1 2 3 5 55 354224848179261915075

2
@aditsu (q:^-^:p) 664 729p偶数的地方。J是可能是好它做什么谜语。:)
randomra

2
更好的(<:^-^:>) 4是:is 81<:^-^:> 4is 53.5982
randomra

2
这里展示的表情符号是所有J代码都应努力的方向。另外,另一种选择是+/@:!&i.-使用9个字节。
2016年

1
@miles非常好!您应该发布它,因为它与我的完全不同。
randomra

21

Hexagony18岁 14 12

感谢Martin 6个字节!

1="/}.!+/M8;

展开:

  1 = "
 / } . !
+ / M 8 ;
 . . . .
  . . .

在线尝试


老了,回答。之所以这样,是因为图像和说明可能对新的Hexagony用户有用。

!).={!/"*10;$.[+{]

展开:

  ! ) .
 = { ! /
" * 1 0 ;
 $ . [ +
  { ] .

这将打印用换行符分隔的斐波那契数列。

在线尝试!但是请注意,在线解释器并不真正喜欢无限输出。

说明

该程序有两个“子例程”,每个子例程由两个使用的IP之一运行。第一个例程打印换行符,第二个例程进行斐波那契计算和输出。

第一个子例程从第一行开始,并在整个过程中从左向右移动。它首先在内存指针处打印值(初始化为零),然后在内存指针处将值递增1。无操作后,IP跳至第三行,该行首先切换到另一个存储单元,然后打印换行符。由于换行符具有正值(其值为10),所以代码将始终跳到下一行的第五行。第五行将内存指针返回到我们的斐波那契数,然后切换到另一个子例程。当我们从该子例程返回时,IP将在执行无操作后跳回到第三行。

第二个子例程从右上角开始,然后开始向东南移动。空转后,我们被弹起,沿第二条线向西行驶。在将内存指针移至下一个位置之前,此行将打印当前的斐波那契数。然后,IP跳至第四行,在此使用前两个计算下一个斐波那契数。然后,它将控制权交还给第一个子例程,但是当它重新获得对程序的控制权时,它将继续进行直到遇到跳转为止,在该跳转处,它在最初用于将其指向西方的镜像上反弹,并返回第二行。


初步的漂亮图片!

图像的左侧是程序,右侧表示存储器。蓝色框是第一个IP,两个IP都指向要执行的下一条指令。

enter image description here

注意:图片可能只对那些图像编辑程序技能同样有限的人看起来很漂亮:PI将再增加至少2次迭代,从而使*操作员的使用更加清晰。

注意2:在编写了大部分内容后,我只看到了alephalpha的答案,我认为由于分离,它仍然很有价值,但是我们程序的实际斐波那契部分非常相似。另外,这是我见过的最小的Hexagony程序,使用了多个IP,因此我认为保留它可能会很好:P


您应该链接到用于制作漂亮图片的任何内容,然后将链接放在esolangs.org/wiki/Hexagony上
mbomb007 '16

1
@ mbomb007我使用gimp手动创建每个框架,然后将图像上传到一些gif制作网站。尽管在此过程中有几次我考虑制作一个工具来完成它,但考虑到它是多么乏味。
FryAmTheEggman '16

@FryAmTheEggman令人印象深刻!挑战一下。我确定有人会发布答案。:D如果您可以创建一个类似于fish在线解释器的网站,那就更好了。
mbomb007 '16

@ mbomb007对于这个网站上的挑战可能有点雄心勃勃,更不用说它可能会因为真正广泛而遭受很大的痛苦。我认为我不会发布,但是如果您认为自己有很好的呈现方式,可以随时进行。另外,我相信Timwi为六角形创建了C#ide,尽管我从未使用过它,因为我没有对mono感到困扰。
FryAmTheEggman '16

1
@ mbomb007顺带一提,ide住在这里,上次忘记链接它。
FryAmTheEggman '16

18

108

 MoO moO MoO mOo MOO OOM MMM moO moO
 MMM mOo mOo moO MMM mOo MMM moO moO
 MOO MOo mOo MoO moO moo mOo mOo moo

17

Python 2,34个字节

Python,使用递归... StackOverflow来了!

def f(i,j):print i;f(j,i+j)
f(1,1)

15

果冻,3个字节

+¡1

在线尝试!

这个怎么运作

+¡1    Niladic link. No implicit input.
       Since the link doesn't start with a nilad, the argument 0 is used.

  1    Yield 1.
+      Add the left and right argument.
 ¡     For reasons‡, read a number n from STDIN.
       Repeatedly call the dyadic link +, updating the right argument with
       the value of the left one, and the left one with the return value.

‡浏览 ¡左侧的两个链接。由于只有一个,因此它必须是循环的主体。因此,从输入中读取数字。由于没有命令行参数,因此将从STDIN中读取该数字。


12

Golfscript-单一号码-10/12/11

从标准输入中获取12个字符:

~0 1@{.@+}*;

堆栈中已有11个字符用于输入:

0 1@{.@+}*;

10个字符,用于进一步将1定义为第0个斐波那契数:

1.@{.@+}*;

1
选项为“给定n,计算第n个斐波那契数”。因此~,放弃,您将拥有11个字符并n进入堆栈并离开F_n堆栈。
彼得·泰勒

12

红宝石

29 27 25 24字符

p a=b=1;loop{b=a+a=p(b)}

编辑:使其成为无限循环。;)


13
有人注意到b=a+a=b是回文吗?:)
st0le 2011年

2
是的,st0le做过:)
gnibbler,2011年

我知道我参加晚会很晚,但是有人可以解释一下该b=a+a=b部分的工作原理吗?似乎无法绕过我的头。
拉玛先生先生2012年

3
@GigaWatt,这样想,指令从左到右执行...所以newb=olda+(a=oldb)
st0le 2012年

您可以使用loop以下方法保存2个字符:p 1,a=b=1;loop{p b=a+a=b}
Patrick Oscity 2012年

11

Mathematica,9个字符

Fibonacci

如果不允许使用内置函数,这是一个明确的解决方案:

Mathematica,33 32 31个字符

#&@@Nest[{+##,#}&@@#&,{0,1},#]&

#&@@Nest[{#+#2,#}&@@#&,{0,1},#]&32个字符。
chyanog

1
@chyanog 31:#&@@Nest[{+##,#}&@@#&,{0,1},#]&
巫师先生

1
@Wizard先生24个字符(26个字节):Round[GoldenRatio^#/√5]&
JungHwan Min

1
或23个字符(27个字节):Round[((1+√5)/2)^#/√5]&
JungHwan Min '18

10

DC(20字节)

作为奖励,它甚至被混淆了;)

zzr[dsb+lbrplax]dsax

编辑:我可能会指出,如果您等待足够长的时间,它将打印斐波纳契数列中的所有数字。


13
我不会称它为混淆的-混淆的代码应该很难理解,就DC而言,这里的代码是完全简单的。
Nabb 2011年

10

前奏,12字节

Prelude实际上具有相当竞争力的几个挑战之一:

1(v!v)
  ^+^

这需要Python解释器该解释器将值打印为十进制数字而不是字符。

说明

在Prelude中,所有行都是并行执行的,指令指针遍历程序的各列。每行都有自己的堆栈,该堆栈初始化为零。

1(v!v)
  ^+^
| Push a 1 onto the first stack.
 | Start a loop from here to the closing ).
  | Copy the top value from the first stack to the second and vice-versa.
   | Print the value on the first stack, add the top two numbers on the second stack.
    | Copy the top value from the first stack to the second and vice-versa.

循环将永远重复,因为第一个堆栈永远不会0在顶部。

请注意,这从开始斐波那契数列0


10

六边形,6字节

不竞争,因为语言比问题新。

1.}=+!

取消高尔夫:

  1 .
 } = +
  ! .

它打印斐波那契数列,不带任何分隔符。


2
这有个小问题,它不会在数字之间打印任何分隔符。但是,在挑战中并没有完全明确说明这一点。(我真的很高兴有人正在使用Hexagony。:))–
Martin Ender

9

TI-BASIC,11

传奇的TI-BASIC高尔夫球手肯尼斯·哈蒙德(“ Weregoose”),来自该网站。以O(1)时间运行,并认为0是斐波纳契数列的第0个项。

int(round(√(.8)cosh(Anssinh‾¹(.5

使用方法:

2:int(round(√(.8)cosh(Anssinh‾¹(.5
                                     1

12:int(round(√(.8)cosh(Anssinh‾¹(.5
                                     144

这是如何运作的?如果进行数学运算,结果将sinh‾¹(.5)等于ln φ,因此它是Binet公式的修改版本,向下舍入而不使用(1/φ)^n校正项。的round(需要(轮9位小数),以防止舍入误差。


8

K-12

计算nn-1斐波那契数。

{x(|+\)/0 1}

只是nth斐波那契数。

{*x(|+\)/0 1}

+1还不错!如果您只可以缩小一个字符(并提供一种测试方法),我会接受您的回答。:-)
Chris Jester-Young

缩小它的唯一方法是将函数替换为对已知数字的调用:n(| + \)/ 0 1使用此解释器对其进行测试。
isawdrones


7

爪哇,55

在这里,我无法与大多数语言的简洁性竞争,但是我可以提供一种截然不同的方法,并且可能以更快的速度(恒定时间)计算第n个数字:

Math.floor(Math.pow((Math.sqrt(5)+1)/2,n)/Math.sqrt(5))

n是输入(int或long),从n = 1开始。它用 Binet的公式进行舍入而不是减法。


我喜欢这个解决方案
Andreas

这似乎对我不起作用,但是现在还很早,我可能会丢失一些东西!假设0是序列中的第一个数字,则给出0, 0, 1, 1, 3, 4, 8, 12, 21, 33前10个数字
Shaggy

@蓬松的哎呀!抱歉,我引入了一个错误-现在已修复。
汉斯·彼得·斯特尔


6

FAC:功能性APL,4个字符(!!)

不是我的,因此发布为社区Wiki。FAC是APL的一种方言,Tu Hai-Chen Tu于1985年在其博士学位论文中显然提出了FAC。他后来与Alan J. Perlis一起写了一篇名为“ FAC:一种功能性APL语言 ”的文章。APL的这种方言使用“惰性数组”,并允许使用无限长的数组。它定义了一个运算符“ iter”(),以允许某些递归序列的紧凑定义。

的单子(“一元”)情况基本上是Haskell的情况iterate,并定义为(F⌼) A ≡ A, (F A), (F (F A)), …。二进(“二进制”)的情况下类似地有所定义为两个变量:A (F⌼) B ≡ A, B, (A F B), (B F (A F B)), …。为什么这有用?好吧,事实证明,这恰好是斐波那契数列的递归。实际上,给出的例子之一是

1+⌼1

产生熟悉的序列1 1 2 3 5 8 …

因此,采用非新颖的编程语言,很可能是最短的Fibonacci实现。:D


哦,作为我(手动)批量取消维基处理的一部分,我不小心取消了对您的帖子的维基百科。那好吧。;-)
克里斯·杰斯特·杨



6

渡渡鸟,26字节

	dot F
F
	F dip
	F dip dip

在线尝试!

这个怎么运作

函数F完成所有繁重的工作;递归定义如下。

F(n) = ( F(|n - 1|), F(||n - 1| - 1|) )

每当n> 1时,我们就有| n-1 | = n-1 <n|| n-1 | -1 | = | n-1-1 | = n-2 <n,因此该函数返回(F(n-1),F(n-2))

如果n = 0,则| n-1 | = 1> 0 ; 如果n = 1,则|| n-1 | -1 | = | 0-1 | = 1 = 1。在这两种情况下,尝试的递归调用F(1)都会引发Surrender异常,因此F(0)返回0,F(1)返回1

例如,F(3)=(F(1),F(2))=(1,F(0),F(1))=(1,0,1)

最后,主要功能定义为

main(n) = sum(F(n))

因此它将F返回的向量的所有坐标相加。

例如,main(3)= sum(F(3))= sum(1,0,1)= 2



5

Desmos,61个字节

打高尔夫球

单击add slider按钮n

p=.5+.5\sqrt{5}
n=0
f=5^{-.5}\left(p^n-\left(-p\right)^{-n}\right)

最后一行是输出。

不打高尔夫球

是一种功能。

\phi =\frac{1+\sqrt{5}}{2}
f_{ibonacci}\left(n\right)=\frac{\phi ^n-\left(-\phi \right)^{-n}}{\sqrt{5}}

5

库比克斯,10个字节

非竞争性答案,因为语言比问题新颖。

Cubix是@ETHproductions开发的一种新的二维语言,将代码包装到一个大小合适的立方体上。

;.o.ON/+!)

在线尝试

以下列方式将其包裹在2 x 2的立方体上

    ; .
    o .
O N / + ! ) . .
. . . . . . . .
    . .
    . .
  • O 输出TOS的值
  • N 将换行符推入堆栈
  • / 向北反射
  • o 输出TOS的字符
  • ; 流行TOS
  • / 绕过立方体后向东反射
  • + 添加堆栈的前2个值
  • ! 如果TOS为0,则跳过下一个命令
  • ) 将TOS加1。这从本质上开始了序列。

这是一个无穷循环,使用换行符打印序列。利用大多数命令不会从堆栈中弹出值的事实。
如果忽略分隔符,则可以使用5个字节来完成.O+!)


5

Brainfuck,16,15,14 / 13个字符

+[[->+>+<<]>]  

生成斐波那契数列,并且不打印任何内容。而且,比上面的短。

+[.[->+>+<<]>]   

这个有14个字符,但打印出斐波那契数列值的ASCII字符。


1
这很好,但是我会说14字节版本仅从2nd 1开始输出是不正确的吗?如“ 1 2 3 5 8”而不是“ 1 1 2 3 5 8”?
查林

1
@Charlim哦,你是对的。我不知道2014年的想法如何。无论如何,我只是通过将打印指令移到循环的前面来修复了它。
Stefnotch
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.