语言不可知论 - 斐波那契代码高尔夫



以尽可能少的字符数生成斐波那契数列。任何语言都可以,除了使用一个运算符 f 定义的语言,该运算符打印斐波那契数

起点:25哈斯克尔中的 14 个字符:

f=0:1:zipWith(+)f(tail f)

f=0:scanl(+)1f

18个字符的英语。

"斐波那契数列"

好吧,我失败了。 :)

13 个字符的 Golfscript:

2,~{..p@+.}do

更新以解释脚本的操作:

  1. 2, 会生成一系列[0 1]
  2. ~将该数组放在堆栈上
  3. 因此,在我们运行do时,我们从 0 1 开始堆栈(堆栈顶部为 1)

do循环:

  1. 每个.都复制堆栈的顶部项目;在这里,我们这样做两次(在初始运行时留下0 1 1 1
  2. p打印出最上面的值(留给我们0 1 1
  3. @旋转堆栈中的前 3 个项目,使最上面的第三个项目位于顶部 ( 1 1 0
  4. + 将堆栈中的前 2 个项目添加(留下 1 1 个)
  5. .复制顶部值,以便do循环可以检查其真实性(以确定是否继续)

在心理上跟踪几个循环就足以告诉你,这是生成斐波那契序列值所需的加法。

由于 GolfScript 具有 bignum,因此永远不会有整数溢出,因此do循环末尾的堆栈顶部值永远不会为 0。因此,脚本将永远运行。

RePeNt, 9, 8 个字符

1↓[2?+1]

或 10 个字符,打印:

1↓[2?+↓£1]

运行方式:

RePeNt "1↓[2?+1]"

RePeNt是我编写的基于堆栈的玩具语言(并且仍在改进中),其中所有运算符/函数/块/循环都使用反向波兰符号(RPN)。

Command      Explanation                                              Stack
-------      -----------                                              -----
1            Push a 1 onto the stack                                  1
↓            Push last stack value                                    1 1
[            Start a do-while loop                                    1 1
2?           Push a two, then pop the 2 and copy the last 2 stack     1 1 1 1
             items onto the stack
+            Add on the stack                                         1 1 2
↓£           Push last stack value then print it                      1 1 2
1            Push a 1 onto the stack                                  1 1 2 1
]            Pop value (1 in this case), if it is a 0 exit the loop   1 1 2
             otherwise go back to the loop start.

答案就在堆栈上,它像这样构建自己:

1 1
1 1 2
1 1 2 3
1 1 2 3 5

它永远不会终止(它具有 C#/JAVA do { } while(true) 循环的等式),因为序列永远不会终止,但终止解决方案可以这样编写:

N_1↓nI{2?+}

这是 12 个字符。

我想知道是否有人会读到这个:(

语言:C++编译器错误
字符: 205

#define t template <int n> struct 
#define u template <> struct f
t g { int v[0]; };
t f { enum { v = f<n-1>::v + f<n-2>::v }; g<v> x;};
u<1> { enum { v = 1 }; };
u<0> { enum { v = 0 }; };
int main() { f<10> x; }

Perl 6 - 22 个字符:

sub f{1,1...{$^a+$^b}}

x86 (C-callable) realmode, 14 bytes.
输入在堆栈上为  n,在 AX 中返回  Fn    。

59 31 C0 E3 08 89 C3 40 93 01 D8 E2 FB C3

Brainfuck,33个字符:

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

22 个字符,带 dc:

1[pdd5**v1++2/lxx]dsxx

使用以下任一方式调用:

DC -e'1[PDD5**v1++2/lxx]dsxx'

或:

echo '1[PDD5**v1++2/lxx]dsxx' |直流

注意:不是我的作品,是从perlmonk偷来的。

J,非递归函数的 27 个字符:

f=:3 :'{:}.@(,+/)^:y(0 1x)'

+/对列表求和。
(,+/)将列表的总和追加到其尾部。
}.@(,+/)对列表求和,将元素追加到其尾部,然后删除第一个元素。
}.@(,+/)^:y y次迭代上述函数。
}.@(,+/)^:y(0 1x)将上述函数应用于列表(0,1)x使其成为整数)。
{:}.@(,+/)^:y(0 1x) 采用上述输出列表的最后一个元素。
f=:3 :'{:}.@(,+/)^:y(0 1x)'f定义为一个变量y上的函数。

记录:

  • 路亚(66个字符):function f(n)if n<2 then return n else return f(n-1)+f(n-2)end end
  • JavaScript (41 个字符): function f(n){return n<2?n:f(n-1)+f(n-2)}
  • 爪哇(41个字符):int f(int n){return n<2?n:f(n-1)+f(n-2);}

我不太擅长超级简洁的语言... :-P

克里斯是对的,我只是采用了简单的递归算法。实际上,Lua 中的线性甚至更短(感谢多项分配)!JavaScript 就没那么幸运了,Java 更糟糕,不得不声明 vars......

  • 路亚(60个字符):function f(n)a=1;b=0;for i=1,n do a,b=b,a+b end return b end
  • JavaScript (60 个字符): function f(n){a=1;b=i=0;for(;i++<n;){x=a+b;a=b;b=x}return b}
  • 爪哇(71个字符):int f(int n){int a=1,b=0,i=0;for(;i++<n;){int x=a+b;a=b;b=x;}return b;}

我会用local a,b=1,0编写Lua的代码,但它更长,所以让我们污染_G! ;-)Idem for JS.

为了完整起见,这里是终端递归版本。Lua 的那个,使用尾部调用,和线性的一样快(但 69 个字符,它是最长的!) - 需要用三个参数 n,1,0 调用它们。

  • 路亚(69个字符,更长!):function f(n,a,b)if n<1 then return b else return f(n-1,b,a+b)end end
  • JavaScript (44 个字符): function f(n,a,b){return n<1?b:f(n-1,b,a+b)}
  • 爪哇(52个字符):int f(int n,int a,int b){return n<1?b:f(n-1,b,a+b);}

评论后更正(感谢塞巴斯蒂安),这不是一个序列解决方案,所以这里我们使用 42 个字符(包括 ):

def f(a=0,b=1):
 while 1:yield a;a,b=b,a+b

下面的旧帖子

蟒蛇,38个字符。

f=lambda n:n if n<2 else f(n-1)+f(n-2)

不是那么短,但在我看来最具可读性:P

编辑:这是分析方法(如果有人需要在python中看到它:-)

f=lambda n:int(.5+(.5+5**.5/2)**n/5**.5)

Windows XP(及更高版本)批处理脚本。当给定单个参数 - amount 时,此批处理函数生成 amount+1 斐波那契数,并将它们作为变量 %r%(369 个字符或 347 个字符 - 如果我们删除缩进)中的字符串(BATCH 实际上没有集合)返回:

:f
    set i=0
    set r=1
    set n=1
    set f=0
    :l
        if %n% GTR %~1 goto e
        set f=%f% %r%
        set /A s=%i%+%r%
        set i=%r%
        set r=%s%
        set /A n+=1
        goto l
    :e
    set r=%f%
    exit /B 0

这是完整的脚本,以查看它的实际效果(只需将其复制粘贴到CMD或BAT文件中并运行它):

@echo off
call :ff 0
call :ff 1
call :ff 2
call :ff 3
call :ff 5
call :ff 10
call :ff 15
call :ff 20
exit /B 0
:ff
    call :f "%~1"
    echo %~1: %r%
    exit /B 0
:f
    set i=0
    set r=1
    set n=1
    set f=0
    :l
        if %n% GTR %~1 goto e
        set f=%f% %r%
        set /A s=%i%+%r%
        set i=%r%
        set r=%s%
        set /A n+=1
        goto l
    :e
    set r=%f%
    exit /B 0

Microsoft 批处理 - 15 个字符

古老的挑战,但世界必须知道这是可能的:

%1
%0 %1%2 %1 #

输出是一元中的 stderr,只计算 # 个字符。根据主机系统的空间限制,它可能只生成前 14 个数字左右。

语言:

dc, 字符计数: 20

更短的直流解决方案。

dc -e'1df[dsa+plarlbx]dsbx'

F#:

(0,1)|>Seq.unfold(fun(a,b)->Some(a,(b,a+b)))

44 字符

这是我最好的使用方案,45个字符:

(let f((a 0)(b 1))(printf"~a,"b)(f b(+ a b)))

MS Excel:11个字符:

=SUM(A1:A2)

在前2个单元格中键入1,然后将上述公式放在单元格A3中。将公式复制到电子表格中。

由于第 74 行的浮点舍入而开始失去准确性。
超过 10^307 并在第 1477 行溢出到#NUM!错误。

生成斐波那契数列。序列序列!

C#

我看到很多答案实际上并没有生成序列,而是使用递归只给你位置 *n 的斐波那契数,当循环生成序列时,在更高的 n 值下会变得越来越慢。

using System;
static void Main()
{
  var x = Math.Sqrt(5);
  for (int n = 0; n < 10; n++)
    Console.WriteLine((Math.Pow((1 + x) / 2, n) - Math.Pow((1 - x) / 2, n)) / p) ;
}
let rec f l a b =function 0->a::l|1->b::l|n->f (a::l) b (a+b) (n-1) in f [] 1 1;;

80 个字符,但真正生成序列,以线性时间。

Ruby(30个字符):

def f(n)n<2?n:f(n-1)+f(n-2)end

@Andrea Ambu

一个迭代的pythonic fibonacci() 的版本应该是这样的:

def fibonacci(a=0, b=1):
    while True:
        yield b
        a, b = b, a+b

Lua - 49 个字符

function f(n)return n<2 and n or f(n-1)+f(n-2)end

Befunge-93

31 字符

将输出一个无限的斐波那契数列表,从 0 向上,用制表符分隔(可以通过删除第一行中的9,减少到 29 个字符,代价是数字之间没有空格)。

不幸的是,我尝试过的所有 Befunge-93 解释器似乎都在 65k 之后溢出,因此输出仅在 46368(即 F24)之前是正确的。

#v::1p1>01g:.\:01p+9,#>     ^

确认可以使用Javascript中的Befunge-93解释器和Visual Befunge Applet Full。

我很自豪地说这是一个完全原创的作品(即我没有从任何人那里复制这段代码),它比目前在罗塞塔密码上的 Befunge 解决方案要短得多。

BrainF**k:

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

这将生成前 5 个。要生成更多,请将开头的 5 + 替换为更多:例如:

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

不是最短的,而是发布时最快的。

float f(float n) {
    return (pow(1+sqrt(5.0))/2.0),n) - pow(1+sqrt(5.0))/2.0),n)/sqrt(n));
}

C 语言中的 33 个字符:

F(n){return n<2?n:F(n-1)+F(n-2);}

Delphi Prism(Delphi for .net)

f:func<int32,int32>:=n->iif(n>1,f(n-1)+f(n-2),n)

49 字符

前面的 Ruby 示例在没有分号或换行符的情况下不起作用,所以它实际上是 32 个字符。下面是实际输出序列的第一个示例,而不仅仅是返回指定索引的值。

红宝石:
53 个字符,包括换行符:

def f(n);n<2?1:f(n-1)+f(n-2);end
0.upto 20 {|n|p f n}

或者,如果您想要输出可用数据结构的函数,则为 71 个字符:

def f(n);n<2?1:f(n-1)+f(n-2);end
def s(n);(0..n).to_a.map {|n| f(n)};end

或接受命令行参数,70 个字符:

def f(n);n<2?1:f(n-1)+f(n-2);end
p (0..$*[0].to_i).to_a.map {|n| f(n)}

PDP-11汇编程序(源)

    .globl  start
    .text
start:
    mov $0,(sp)
    mov $27,-(sp)
    jsr pc, lambda
print_r1:
    mov $outbyte,r3
div_loop:
    sxt r0
    div $12,r0
    add $60,r1
    movb    r1,-(r3)
    mov r0,r1
    tst r1
    jne div_loop
    mov $1,r0
    sys 4; outtext; 37
    mov $1,r0
    sys 1
lambda:
    mov 2(sp),r1
    cmp $2,r1
    beq gottwo
    bgt gotone
    sxt r0
    div $2,r0
    tst r1
    beq even
odd:
    mov 2(sp),r1
    dec r1
    sxt r0
    div $2,r0
    mov r0,-(sp)
    jsr pc,lambda
    add $2,sp
    mov r0,r3
    mov r1,r2
    mov r3,r4
    mul r2,r4
    mov r5,r1
    mov r3,r4
    add r2,r4
    mul r2,r4
    add r5,r1
    mul r3,r3
    mov r3,r0
    mul r2,r2
    add r3,r0
    rts pc
even:
    mov 2(sp),r1
    sxt r0
    div $2,r0
    dec r0
    mov r0,-(sp)
    jsr pc,lambda
    add $2,sp
    mov r0,r3
    mov r1,r2
    mov r2,r4
    mul r2,r4
    mov r5,r1
    mov r2,r4
    add r3,r4
    mul r4,r4
    add r5,r1
    mov r2,r4
    add r3,r4
    mul r2,r4
    mov r5,r0
    mul r2,r3
    add r3,r0
    rts pc
gotone:
    mov $1,r0
    mov $1,r1
    rts pc
gottwo:
    mov $1,r0
    mov $2,r1
    rts pc
    .data
outtext:
    .byte 62,63,162,144,40,106,151,142,157,156
    .byte 141,143,143,151,40,156,165,155
    .byte 142,145,162,40,151,163,40
    .byte 60,60,60,60,60
outbyte:
    .byte 12

相关内容

  • 没有找到相关文章

最新更新