可能な限り少ない文字数でフィボナッチ数列を生成します。f
フィボナッチ数を出力する1つの演算子、で定義した言語を除いて、どの言語でも問題ありません。
開始点:Haskellで25 14文字:
f=0:1:zipWith(+)f(tail f)
f=0:scanl(+)1f
可能な限り少ない文字数でフィボナッチ数列を生成します。f
フィボナッチ数を出力する1つの演算子、で定義した言語を除いて、どの言語でも問題ありません。
開始点:Haskellで25 14文字:
f=0:1:zipWith(+)f(tail f)
f=0:scanl(+)1f
英語の18文字。
「フィボナッチ数列」
わかりました、失敗します。:)
Golfscriptの13文字:
2,~{..p@+.}do
スクリプトの操作を説明するために更新します。
2,
の配列を作成します[0 1]
~
その配列をスタックに置きますdo
開始します。0 1
do
ループ:
.
がスタックの一番上のアイテムを複製します。ここでは、これを2回行います(0 1 1 1
最初の実行時に残します)p
最上位の値を出力します(を残します0 1 1
)@
スタックの上位3つのアイテムを回転して、一番上の3番目が一番上になるようにします(1 1 0
)+
スタックの上位2つのアイテムを追加します(残す1 1
).
do
ループがその真実性をチェックできるように(続行するかどうかを決定するために)、最上位の値を複製しますこれを精神的に追跡することで、フィボナッチ数列の値を生成するために必要な追加が行われることがわかります。
GolfScriptにはbignumがあるため、整数のオーバーフローが発生することはなく、do
ループの最後のスタックの最上位の値が0になることはありません。したがって、スクリプトは永久に実行されます。
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#/JAVAdo { } while(true)
ループと同等です) が、終了ソリューションは次のように記述できます。
N_1↓nI{2?+}
これは12文字です。
誰かがこれを読むことがあるだろうか:(
Perl 6 - 22 文字:
sub f{1,1...{$^a+$^b}}
言語: 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; }
Brainfuck、33 文字:
+.>+.[<[>+>+<<-]>.[<+>-]>[<+>-]<]
x86 (C 呼び出し可能) リアルモード、14 バイト。 入力はスタック上の nであり、AX で
F nを返します。
59 31 C0 E3 08 89 C3 40 93 01 D8 E2 FB C3
dc を含む 22 文字:
1[pdd5**v1++2/lxx]dsxx
次のいずれかで呼び出します。
dc -e'1[pdd5**v1++2/lxx]dsxx'
または:
echo '1[pdd5**v1++2/lxx]dsxx' | 直流
注: perlmonksから密猟した私の作品ではありません。
J、非再帰関数の場合は 27 文字:
f=:3 :'{:}.@(,+/)^:y(0 1x)'
+/
リストを合計します。
(,+/)
リストの合計を末尾に追加します。
}.@(,+/)
リストを合計し、末尾に要素を追加し、最初の要素を削除します。
}.@(,+/)^:y
上記の関数y
時間を繰り返します。
}.@(,+/)^:y(0 1x)
上記の関数をリストに適用します(0,1)
(これx
により整数になります)。
{:}.@(,+/)^:y(0 1x)
上記の出力リストの最後の要素を取ります。は、1 つの変数に対する関数であると
f=:3 :'{:}.@(,+/)^:y(0 1x)'
定義されています。f
y
コメントの後で修正されました(Sebastianに感謝)、それはシーケンスソリューションではなかったので、ここでは42文字(\ nを含む)を使用します。
def f(a=0,b=1):
while 1:yield a;a,b=b,a+b
Python、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)
記録のために:
function f(n)if n<2 then return n else return f(n-1)+f(n-2)end end
function f(n){return n<2?n:f(n-1)+f(n-2)}
int f(int n){return n<2?n:f(n-1)+f(n-2);}
私は超簡潔な言語にあまり精通していません... :-P
Chris の言うとおりです。単純な再帰アルゴリズムを採用しただけです。実際、線形のものは Lua ではさらに短くなっています (複数代入のおかげです)! JavaScript はそれほど幸運ではなく、Java はさらに悪く、変数を宣言する必要があります...
function f(n)a=1;b=0;for i=1,n do a,b=b,a+b end return b end
function f(n){a=1;b=i=0;for(;i++<n;){x=a+b;a=b;b=x}return b}
int f(int n){int a=1,b=0,i=0;for(;i++<n;){int x=a+b;a=b;b=x;}return b;}
Lua のコードを で書きますlocal a,b=1,0
が、長くなるので _G を汚染しましょう! ;-) JSの同上。
完全を期すために、ターミナル再帰バージョンを次に示します。末尾呼び出しを使用する Lua のものは、線形のものと同じくらい高速です (ただし、69 文字で、これが最も長いです!) - n、1、0 の 3 つのパラメーターでそれらを呼び出す必要があります。
function f(n,a,b)if n<1 then return b else return f(n-1,b,a+b)end end
function f(n,a,b){return n<1?b:f(n-1,b,a+b)}
int f(int n,int a,int b){return n<1?b:f(n-1,b,a+b);}
Microsoftバッチ-15文字
古い挑戦ですが、世界はそれが可能であることを知らなければなりません:
%1
%0 %1%2 %1 #
出力は、#文字のみをカウントして、unaryでstderrに出力されます。ホストシステムのスペース制限によっては、最初の14個程度の数字しか生成されない場合があります。
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
より短いDCソリューション。
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 を超え#NUM!
、行 1477 でオーバーフローしてエラーになります。
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文字ですが、線形時間で実際にシーケンスを生成します。
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) ;
}
フィボナッチ数列を生成します。シーケンスシーケンス!
@アンドレア・アンブ
反復的な pythonicfibonacci()
のバージョンは次のようになります。
def fibonacci(a=0, b=1):
while True:
yield b
a, b = b, a+b
ルビー (30 文字):
def f(n)n<2?n:f(n-1)+f(n-2)end
BrainF**k:
>+++++>+>+<[[>]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[>+>+<<-]>>[<<+>>-]<[<]>-]
これで最初の 5 が生成されます。さらに生成するには、先頭の 5 + を more に置き換えます。例:
>++++++++++++++++++++++>+>+<[[>]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[>+>+<<-]>>[<<+>>-]<[<]>-]
タブで区切られた 0 から上へのフィボナッチ数の無限リストを出力します (9,
最初の行を削除することで 29 文字に減らすことができますが、数字の間に空白はありません)。
残念ながら、私が試したすべての Befunge-93 インタープリターは 65k 後にオーバーフローするように見えるため、出力は 46368 (これはF 24です) までしか正しくありません。
#v::1p1>01g:.\:01p+9,# > ^
Javascript の Befunge-93 インタープリターとVisual Befunge Applet Fullで動作することが確認されています (上記の注意事項あり) 。
これは完全にオリジナルの作業であり (つまり、このコードを誰からもコピーしたものではありません)、現在 Rosetta Code にある Befunge ソリューションよりもはるかに短いことを誇りに思います。
ルア - 49 文字
function f(n)return n<2 and n or f(n-1)+f(n-2)end
Delphi Prism(Delphi for .net)
f:func<int32,int32>:=n->iif(n>1,f(n-1)+f(n-2),n)
49文字
かなり古い投稿ですが、
f(){int cn=2,*n=calloc(9,9);n[1]=1;while(cn<32)printf("%d ",n[cn]=n[cn-1]+n[cn++-2]);}
C で 85 文字。
前の Ruby の例は、セミコロンまたは改行なしでは機能しないため、実際には 32 文字です。指定されたインデックスの値を返すだけでなく、実際にシーケンスを出力する最初の例を次に示します。
Ruby:
改行を含む 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)}
C の 33 文字:
F(n){return n<2?n:F(n-1)+F(n-2);}
最初のn項:
(+/@(2&{.),])^:n i.2
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
最短ではありませんが、投稿時点で最速です。:-)
float f(float n) {
return (pow(1+sqrt(5.0))/2.0),n) - pow(1+sqrt(5.0))/2.0),n)/sqrt(n));
}
明晰
f = 1 fby 1 fby f + prev f;
スペースを含めて 27 文字。
ユーフォリア: 44 文字
object f=1&1 loop do f&=f[$]+f[$-1]until 0
RAM または double がなくなるまで生成し続けます。
Java反復 (73)
void f(int n){for(int a=1,b=1;n-->0;b=a+(a=b)){System.out.print(a+",");}}
ルビー (46)
def f(n);a,b=1,1;1.upto(n){p a;b=a+(a=b);};end
更新:Ruby(42)
def f(n);a=b=1;n.times{p a;b=a+(a=b);};end
レックス:
arg n;a=1;b=1;do i=1 to n;say ab;a=a+b;b=a+b;end