前n个斐波纳契数列元素


11

有一个众所周知的问题,在这里,要求在短时间内(至少字符)斐波那契序列发生器。

我想知道是否有人可以在非常短的空间内生成斐波那契数列的前N个元素。我正在尝试用python来做,但是我对任何语言的简短回答都感兴趣。函数F(N)生成序列的前N个元素,或者将它们作为函数的返回值返回或打印出来。

有趣的是,似乎代码高尔夫球的答案以开头1 1 2,而不是0 1 1 2。这是代码高尔夫球规范还是通用编程规范?(维基百科说斐波那契数列从零开始。)。

Python示例(前5个元素):

def f(i,j,n):
    if n>0:
        print i;
        f(j,i+j,n-1)
f(1,1,5)

1
我认为这与链接的问题太相似。那里的大多数解决方案都可以轻松修改以处理first-n情况。
hammar 2012年

3
在我所见过的任何地方,基本案例都定义为F_0 = 0, F_1 = 1或等效F_1 = 1, F_2 = 1。区别在于您是要从索引0(在编程中更常见)还是在索引1(在数学中更常见)开始序列。
hammar 2012年

1
F_0 = 0, F_1 = 1使用矩阵表示定义具有明确的好处[[1 1][1 0]]^n = [[F_{n+1} F_n][F_n F_{n-1}]]
彼得·泰勒

1
@Peter:既然是一个比另一个更喜欢的理由(出于审美的原因,我长期以来一直倾向于0、1,但不要相信那些会自己压入)。
dmckee ---前主持人小猫,

1
我意识到这是一个相当大的挑战,但是请注意,您已经接受了并非最短的答案。由于这是一场代码高尔夫比赛,因此最短的答案应该是被标记为接受的答案。
Alex A.

Answers:


39

C

不用担心,但这是一个有趣的示例:

f(n){return n<4?1:f(--n)+f(--n);}
main(a,b){for(scanf("%d",&b);a++<=b;printf("%d ",f(a)));}

证明有效。


我为此感到非常自豪:我很无聊,所以我重新排列了代码(添加了一些小添加),使其在每一行代表斐波那契数列中的值。

                         #                                // 1
                         f                                // 1
                         //                               // 2
                        (n)                               // 3
                       {/**/                              // 5
                      return n                            // 8
                    <2 ? 1:f(--n)                         // 13
                +f(--n); } main(a, b)                     // 21
          {a = 0, b = 0;scanf("%d",&b); for(              // 34
;a < b; a+=1) { int res = f(a); printf("%d ", res); } }   // 55

证明有效。


真好 90个字符(不包含换行符)。保存2个字节:a++<=b-> a++-breturn--n<3?1:f(n)+f(n-1)。另外,scanf如果您需要输入n,则可以避免argc
ugoren

爱它!这是一个很好的例子,说明--n在同一表达式中两个实例的顺序的未定义行为无关紧要。辉煌!
托德·雷曼

顺便说一句,我认为您4实际上应该有一个3。正如目前用编写的那样<4,产生的序列是1、1、1、2、3、5、8 ...这是一个太多的1。
托德·雷曼

另外,如果要正确处理序列的第零个元素,则可以添加2个字符并将代码更改为return n<3?n>0:f(--n)+f(--n);
Todd Lehman

6

哈斯克尔(26)

令人惊讶的是,这仅比J解决方案长一个字符。

f =(`take`s)
s = 0:扫描l(+)1s

我通过以下方式剃掉了一些字符:

  1. 使用take二元运算符;
  2. 使用scanl代替详细zipWith

从字面上看,我花了大约半个小时才了解这里发生的事情,而且它s是如此优雅,我不知道有人会想到这样的解决方案!我不知道的是您可以s在定义时再次使用s。(我仍然是初学者=)
虚假的人,

5

这是一个单线Python。它使用浮点数,因此可能有些浮点数n不再准确。

F=lambda n:' '.join('%d'%(((1+5**.5)/2)**i/5**.5+.5)for i in range(n))

F(n)返回一个字符串,其中包含n以空格分隔的第一个斐波那契数。


我当时在考虑这样做,但认为时间太长。我没有考虑使用地板。非常好。
克里斯·哈珀

啊,Binet的公式。我也使用了它并且它很准确,如果您将0设为第一个,那么它至少可以显示到第59个斐波那契数。此后,数字变得太大并开始使用指数。
elssar 2012年

70个字符(1行)以定义功能。+ 4 + crlf来调用。非常好!
沃伦·P

5

GolfScript,16个字符

~0 1@{.2$+}*;;]`

输出示例:

$ ruby golfscript.rb ~/Code/golf/fib.gs <<< "12"
[0 1 1 2 3 5 8 13 21 34 55 89]

4

Perl,50个字符

sub f{($a,$b,$c)=@_;$c--&&say($a)&&f($b,$a+$b,$c)}

4

Scala 71:

def f(c:Int,a:Int=0,b:Int=1):Unit={println(a);if(c>0)f(c-1,b,a+b)};f(9)

版画

0
1
1
2
3
5
8
13
21
34

凉。我什至还没有和Scala一起玩。今晚我将在家里尝试。
沃伦·P

3

Perl,29个 28字节

perl -E'say$b+=$;=$b-$;for-pop..--$;' 8
1
1
2
3
5
8
13
21

说明

这基于经典的$b += $a = $b-$a递归,其工作原理如下:

  • 在每个循环的开始,$a包含F(n-2)$b包含F(n)
  • 之后$a = $b-$a $a包含F(n-1)
  • 之后$b += $a $b包含F(n+1)

这里的问题是初始化。经典的方式是,$b += $a = $b-$a || 1但是随后的顺序1 2 3 5 ...

通过将斐波那契数列向左扩展:

... 5 -3 2 -1 1 0 1 1 2 3 5 ...

您会看到正确的起点是$a = -1$b = 0。初始化$ a可以与设置循环结合使用

最后替换$a$;以消除空格for


2

我可以给您提供两行Python解决方案。这会将它们作为列表返回。

f = lambda n: 1 if n < 2 else f(n-1) + f(n-2)
g = lambda m: map(f, range(0,m))

print g(5)

您可以通过添加另一个映射使它们成为字符串然后添加联接来将它们打印出来,但这对我来说似乎不必要。

不幸的是,我不知道如何将递归lambda放入map,所以我陷入了两行。


它的目的是g(100)什么?;)
Llama先生2012年

@GigaWatt嘿,OP从未说过必须做到合理。渐近运行时间是否像O(n(1.62)^ n)一样?
克里斯·哈珀

这是您(可以)执行此操作的一种方法。请注意,f(n)使用n<=0return整数并n>0返回列表,所以..可能并不理想:f = lambda n: map(f, (-x for x in range(0, n))) if n > 0 else -n if n > -2 else f(n+1) + f(n+2)
Dillon Cower 2012年

顺便说一句,您错过了0答案的第一位。更改f为退货n if n < 2是一种解决方法。:)
Dillon Cower 2012年

@DC我喜欢您的解决方案。很有创意。是的,我让我从1、1开始,因为那是我一直学习的方式。我认为更改它很容易。
克里斯·哈珀

2

Python(78个字符)

我使用Binet的公式来计算斐波那契数-

[(1 + sqrt(5))^ n-(1-sqrt(5)^ n] / [(2 ^ n)sqrt(5)]

这里的其他答案不是那么少,但是男孩很快

n=input()
i=1
x=5**0.5
while i<=n:
    print ((1+x)**i-(1-x)**i)/((2**i)*x)
    i+=1

1
Python(12个字符):print"11235":)
Joel Cornett

您可以通过消除圆括号来除去2个字符2**i**具有比*
Joel Cornett

binet公式中的第二项从小开始,直到变小。您可以完全忽略它,而只需将第一项的结果四舍五入到最接近的整数(或加0.5并四舍五入)
Ton Hospel



2

J,25个字符

我意识到J解决方案可能不是您想要的,但是无论如何,这里都是一个。:-)

0 1(],+/&(_2&{.))@[&0~2-~

用法:

    0 1(],+/&(_2&{.))@[&0~2-~ 6
0 1 1 2 3 5
    0 1(],+/&(_2&{.))@[&0~2-~ 10
0 1 1 2 3 5 8 13 21 34

怎么运行的:

从右开始(因为从右到左读取J程序),

2-~ 6~运营商反转参数动词,所以这是一样的6-2

现在忽略括号中的部分,0 1(...)@[&0~ x将动词放在括号中,并x使用列表0 1作为输入执行它的时间- ~再次反转这里的参数,给出x (...)@[&0 ] 0 1,这意味着我可以将输入保留在函数的末尾。

括号内是叉子],+/&(_2&{.)它是由三个动词起来- ],+/&(_2&{.)

叉子a b c使用三个动词并按如下方式使用它们:(x a y) b (x c y)其中xy是叉子的参数。该,是这个叉中心动词和加入的结果x ] yx +/&(_2&{.) y在一起。

]返回不变的左参数,结果x ] yx

+/&(_2&{.)从给定列表中获取最后两个项目(_2&{.)-在这种情况下0 1-然后将它们加在一起+/&s充当胶水)。

一旦动词操作完毕,结果就会反馈给下一次运行,从而生成序列。


2

TI-Basic,43个字符

:1→Y:0→X
:For(N,1,N
:Disp X
:Y→Z
:X+Y→Y
:Z→X
:End

该代码可以直接插入到主程序中,也可以制成第一个引用的单独程序。


这是我所见过的第一个TI-BASIC解决方案,不是我一个人:) +1
Timtech

另外,请注意其他人,由于可以删除换行符,因此这里不包括换行符。
Timtech

我刚刚得到了TI-92大键盘键盘计算器。谢谢你这个
沃伦·P

2

APL(33)

{⍎'⎕','←0,1',⍨'←A,+/¯2↑A'⍴⍨9×⍵-2}

用法:

   {⍎'⎕','←0,1',⍨'←A,+/¯2↑A'⍴⍨9×⍵-2}7
0 1 1 2 3 5 8

框字符A是APL的一部分还是缺少字形?
沃伦·P

@WarrenP:如果您指的是从左数第四个字符,则称其为“ quad”,看起来应该像这样。应该只有一个盒子。
marinus 2014年


1

Powershell-35个字符

Powershell接受管道输入,因此我坚信n |in n | <mycode>不应违背我的意愿,而只是在语言中启动“功能”的一部分。

第一个解决方案假设我们从0开始:

%{for($2=1;$_--){($2=($1+=$2)-$2)}}

第二种解决方案假设我们可以从1开始:

%{for($2=1;$_--){($1=($2+=$1)-$1)}}

调用示例: 5 | %{for($2=1;$_--){($1=($2+=$1)-$1)}}

产量:

1
1
2
3
5

有趣的是,尝试避免for()循环的开销导致了相同的字符数:%{$2=1;iex('($1=($2+=$1)-$1);'*$_)}


1

Python,43个字符

这是三种根本不使用Binet公式的单线。

f=lambda n:reduce(lambda(r,a,b),c:(r+[b],a+b,a),'.'*n,([],1,0))[0]
f=lambda n:map(lambda x:x.append(x[-1]+x[-2])or x,[[0,1]]*n)[0]
def f(n):a=0;b=1;exec'print a;a,b=b,a+b;'*n

我从来没有reduce这么严重地虐待过。


1
reduce滥用行为+1
沃伦·P

1

dc,32个字符:

实际上,这将始终显示两个前1个,因此该功能仅对N> = 2起作用。

?2-sn1df[dsa+plarln1-dsn0<q]dsqx

C,75个字符:

没有公认的答案那么酷,但是更短,更快:

main(n,t,j,i){j=0,i=scanf("%d",&n);while(n--)t=i,i=j,printf("%d\n",j+=t);}
额外:

CL,64个字符:

这个学期我最常用的书签之一就是一个有趣的示例,它比这里的其他许多书签都短,而且只是loop宏的直接调用-基本上只是一个语句!我将其删除为所有空白:

(loop repeat n for x = 0 then y and y = 1 then(+ x y)collect y)

非常简短,而且可读性强!要读取输入,n (包括周围的空格)可以替换为(read),并添加3个字符。


是否... main有四个论点?

1
它需要尽可能多的东西。在这种情况下,它只是(用来)定义一些稍后使用的变量:)
daniero


1

Python 2,38字节

对先前发布的解决方案的改进:

a=b=1
exec'print a;a,b=b,a+b;'*input()

这使用exec和字符串乘法来避免循环。

Python 3,46字节

在Python 3中效率不高:

a=b=1
exec('print(a);a,b=b,a+b;'*int(input()))

通过切换到Python 2,您可以节省9个字节:在线试用!您可能可以将Python 2版本添加到您的答案中。
斯蒂芬

@Stephen好点!更新。
罗素·施瓦茨

0

C99,58个字符

以下函数用nFibonacci序列中从0开始的第一个值填充整数数组。

void f(int*a,int n){for(int p=0,q=1;n--;q+=*a++)*a=p,p=q;}

测试工具,将其n作为命令行参数:

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
     int n = (argc > 1) ? atoi(argv[1]) : 1;
     int a[n];
     f(a, n);
     for (int i = 0; i < n; ++i)
          printf("%d\n", a[i]);
}


0

PHP,87

function f($n,$a=array(0,1)){echo' '.$a[0];$n>0?f(--$n,array($a[1],array_sum($a))):'';}

使用array_sum和递归函数生成序列。

例如:

 $ php5 fibo.php 9
 0 1 1 2 3 5 8 13 21 34 


0

Scala,65个字符

(Seq(1,0)/:(3 to 9)){(s,_)=>s.take(2).sum+:s}.sorted map println

例如,这将打印前9个斐波那契数字。对于从控制台输入获取序列长度的更有用的版本,需要70个字符:

(Seq(1,0)/:(3 to readInt)){(s,_)=>s.take(2).sum+:s}.sorted map println

当心使用范围将其限制为Int值。



0

Lua,85个字节

我正在学习Lua,所以我想将此语言添加到池中。

function f(x)
    return (x<3) and 1 or f(x-1)+f(x-2)
end
for i=1,io.read() do
    print(f(i))
end

整个过程用了85个字符,并且该参数作为命令行参数。另一个好处是易于阅读。


0

假,20个字符

^1@[1-$][@2ø+$.\9,]#

输入应该在运行此之前在堆栈上。


0

Pyt,3个字节

ř⁻Ḟ

在线尝试!

ř创建一个数组[1、2、3,...,x]
every每一项减1(因为Ḟ的索引为0)
Ḟ对于x中的每个项目都将其转换为等效的fibonacci


0

x86机器码-379字节

具有ELF标头的版本为484字节:

00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
00000010: 0200 0300 0100 0000 c080 0408 3400 0000  ............4...
00000020: 0000 0000 0000 0000 3400 2000 0200 2800  ........4. ...(.
00000030: 0000 0000 0100 0000 0000 0000 0080 0408  ................
00000040: 0000 0000 e401 0000 0010 0000 0500 0000  ................
00000050: 0010 0000 0100 0000 0000 0000 0090 0408  ................
00000060: 0000 0000 0000 0000 0000 1000 0600 0000  ................
00000070: 0010 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 51b9 0090 0408 8801 31c0 ba01 0000 00eb  Q.......1.......
00000090: 0351 89c1 31c0 89c3 43b0 04cd 8031 c099  .Q..1...C....1..
000000a0: 4259 c300 0000 0000 0000 0000 0000 0000  BY..............
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 31c0 9942 b903 9004 08c6 4101 0ac6 4102  1..B......A...A.
000000d0: 01c6 4103 013a 7103 0f84 ff00 0000 3a71  ..A..:q.......:q
000000e0: 0374 2680 4103 050f b641 036b c008 0041  .t&.A....A.k...A
000000f0: 048a 4104 e887 ffff ff80 6904 30c6 4103  ..A.......i.0.A.
00000100: 0183 e903 3a71 0375 da8a 4104 e86f ffff  ....:q.u..A..o..
00000110: ff3a 7106 0f84 ba00 0000 0fb6 4105 8841  .:q.........A..A
00000120: 060f b641 0788 4105 0fb6 4107 0041 06c6  ...A..A...A..A..
00000130: 4107 003a 7106 0f84 8800 0000 c641 0701  A..:q........A..
00000140: fe49 063a 7106 0f84 7800 0000 c641 0702  .I.:q...x....A..
00000150: fe49 063a 7106 0f84 6800 0000 c641 0703  .I.:q...h....A..
00000160: fe49 063a 7106 0f84 5800 0000 c641 0704  .I.:q...X....A..
00000170: fe49 063a 7106 744c c641 0705 fe49 063a  .I.:q.tL.A...I.:
00000180: 7106 7440 c641 0706 fe49 063a 7106 7434  q.t@.A...I.:q.t4
00000190: c641 0707 fe49 063a 7106 7428 c641 0708  .A...I.:q.t(.A..
000001a0: fe49 063a 7106 741c c641 0709 fe49 063a  .I.:q.t..A...I.:
000001b0: 7106 7410 fe41 08fe 4109 fe49 060f b641  q.t..A..A..I...A
000001c0: 0688 4107 c641 0601 83c1 033a 7106 0f85  ..A..A.....:q...
000001d0: 46ff ffff 3a71 030f 8501 ffff ffb3 0031  F...:q.........1
000001e0: c040 cd80                                .@..

无标题版本(即要评分的版本):

00000000: 67c6 4101 0a67 c641 0201 67c6 4103 0167  g.A..g.A..g.A..g
00000010: 3a71 030f 842a 0167 3a71 0374 2e67 8041  :q...*.g:q.t.g.A
00000020: 0305 6667 0fb6 4103 666b c008 6700 4104  ..fg..A.fk..g.A.
00000030: 678a 4104 e80d 0167 8069 0430 67c6 4103  g.A....g.i.0g.A.
00000040: 0166 83e9 0367 3a71 0375 d267 8a41 04e8  .f...g:q.u.g.A..
00000050: f200 673a 7106 0f84 df00 6667 0fb6 4105  ..g:q.....fg..A.
00000060: 6788 4106 6667 0fb6 4107 6788 4105 6667  g.A.fg..A.g.A.fg
00000070: 0fb6 4107 6700 4106 67c6 4107 0067 3a71  ..A.g.A.g.A..g:q
00000080: 060f 84a3 0067 c641 0701 67fe 4906 673a  .....g.A..g.I.g:
00000090: 7106 0f84 9200 67c6 4107 0267 fe49 0667  q.....g.A..g.I.g
000000a0: 3a71 060f 8481 0067 c641 0703 67fe 4906  :q.....g.A..g.I.
000000b0: 673a 7106 0f84 7000 67c6 4107 0467 fe49  g:q...p.g.A..g.I
000000c0: 0667 3a71 0674 6167 c641 0705 67fe 4906  .g:q.tag.A..g.I.
000000d0: 673a 7106 7452 67c6 4107 0667 fe49 0667  g:q.tRg.A..g.I.g
000000e0: 3a71 0674 4367 c641 0707 67fe 4906 673a  :q.tCg.A..g.I.g:
000000f0: 7106 7434 67c6 4107 0867 fe49 0667 3a71  q.t4g.A..g.I.g:q
00000100: 0674 2567 c641 0709 67fe 4906 673a 7106  .t%g.A..g.I.g:q.
00000110: 7416 67fe 4108 67fe 4109 67fe 4906 6667  t.g.A.g.A.g.I.fg
00000120: 0fb6 4106 6788 4107 67c6 4106 0166 83c1  ..A.g.A.g.A..f..
00000130: 0367 3a71 060f 8521 ff67 3a71 030f 85d6  .g:q...!.g:q....
00000140: fe00 0000 6651 66b9 7801 0000 6788 0166  ....fQf.x...g..f
00000150: 31c0 66ba 0100 0000 eb05 6651 6689 c166  1.f.......fQf..f
00000160: 31c0 6689 c366 43b0 04cd 8066 31c0 6699  1.f..fC....f1.f.
00000170: 6642 6659 c300 0000 0000 00              fBfY.......

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.