フィボナッチ数列を求めるワンライナー各言語まとめ

お遊び記事です．[こちらの記事](https://qiita.com/ytaki0801/items/19059b35efe85519cfad)の姉妹版です．いやその，[某ラノベ](https://kadokawabooks.jp/product/silentwitch/)読んでたらとりあえず21番目までのフィボナッチ数列を求める~~魔術式~~ワンライナーが書きたくなりましてね，はい．

※なお，ここでいう『ワンライナー（[one-liner program](https://en.wikipedia.org/wiki/One-liner_program)）』は[シェル芸](https://ja.wikipedia.org/wiki/USP%E5%8F%8B%E3%81%AE%E4%BC%9A#%E3%82%B7%E3%82%A7%E3%83%AB%E8%8A%B8)のようなものとお考えいただけますと幸いです．高い可読性を要する開発現場で混ぜるな危険．

【2021-06-20追加】姉妹版『素数一覧』の[続編記事](https://qiita.com/ytaki0801/items/dd9a4b90e405c120efc0)を立ち上げました．こちらと同じスタイルで編集し直しています．

【2021-06-18追加】集まった記述例（2021-06-17更新時点）を動画にしてみました．
<iframe width="500" height="350" src="https://www.youtube.com/embed/Q4ptHnntWLo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 制約

フィボナッチ数を求める方法はいろいろありすぎるのと，ワンライナーの趣旨に沿うため，次の制約を設けます．基本的に，[REPL](https://ja.wikipedia.org/wiki/REPL)を用いて0～21番目の値（0番目は0，1番目は1）を求めるワンライナー実行を想定しています．

* 一般項による計算は不可
* フィボナッチ数（列）を求める標準関数・手続き等は使用不可
* ライブラリやモジュールの追加読み込み不可

こうすると，自ずと~~関数型プログラミングに近くなるかもしれません．ますます魔（略~~　気のせいでした．

なお，次は可としています．

* REPL起動時に自動的に読み込まれるライブラリやモジュール
* 大域変数代入の複文（セミコロン区切り等）
* 上限値による処理終了判定（値が10946を超えるまで求める等）

# 各言語での記述例

最も短いと思われる記述（＋筆者が直接確認した実装・バージョン）のみを載せています．より短い表現＆他言語版歓迎．

```j:J(9.0.2)
2&(0 1,+/\)~21
```
```perl:Raku(2018.12)
|^2,*+*...*>1e4
```
```:APL(Dyalog/TryAPL3.4.5)
{⍵,+/¯2↑⍵}⍣20⊢0 1
```
```py:dc(1.4.1/GNUbc1.07.1)
1 0[pdsarla+d10947>m]dsmx
```
```rb:Ruby(2.5.5)
([a=-b=1]*22).map{b=a+a=b}
```
```c:bc(1.07.1)
for(b=1;b+=a<28658;a=b-a)a
```
```pl:Perl(5.30.0)（5.10以降の-Eオプション使用）
say$@=($b+=$@)-$@for++$@..22
```
```hs:Haskell(GHC8.4.4)
let f=0:scanl(+)1f in take 22f
```
```c:calc(2.12.7.2)
for(b=1;b<2e4;a=(b+=a)-a)print a
```
```jl:Julia(1.0.3)
1|>(a,b=0)->0:21 .|>_->a=(b+=a)-a
```
```ps:PostScript(Ghostscript9.52)
[0 1 20{dup 2 index add}repeat]==
```
```py:Python3.8(CPython3.9.5)
a=-1;b=1;[b:=a+(a:=b)for _ in'_'*22]
```
```forth:Forth(Gforth0.7.3)
: f 1 0 22 0 do dup . tuck + loop ; f
```
```awk:awk(GNUAwk4.2.1)
BEGIN{for(b=1;b<2e4;b=a+(a=b))print+a}
```
```sh:IchigoJamBASIC(1.4.3web)
A=0:B=1:FORI=0TO21:?A:B=A+B:A=B-A:NEXT
```
```powershell:PowerShell(7.1.3)
$x=0;$y=1;0..21|%{$x;$x,$y=$y,($x+$y)}
```
```r:R(3.5.2)
c(a<-0,b<-1,replicate(20,b<<-a+(a<<-b)))
```
```js:JavaScript(Node.js10.24.0)
[a=-1,b=1,...Array(20)].map(c=>b=a+(a=b))
````
```st:Smalltalk(GNUSmalltalk3.2.5)
a:=-1.b:=1.(0to:21)collect:[:n|b:=a+(a:=b)]
```
```lua:Lua(5.3.3)
a=0;b=1;for i=0,21 do print(a);a,b=b,a+b end
```
```scheme:Scheme(Gauche0.9.10)
(take((rec(? a b)(lcons a(?(+ a b)a)))0 1)22)
```
```php:PHP(7.3.27)
$a=0;for($b=1;$b<2e4;$a=($b+=$a)-$a)echo"$a ";
```
```py:Python2(CPython2.7.17)
reduce(lambda x,_:x+[x[-1]+x[-2]],'_'*20,[0,1])
```
```py:Python3(CPython3.7.3)
g=lambda*a:len(a)<22and g(*a,a[-1]+a[-2])or a;g(0,1)
```
```clojure:Clojure(1.10)
(take 22((fn f[](lazy-cat[0 1](map +(f)(rest(f)))))))
```
```lisp:CommonLisp(SBCL2.0.0),Scheme(Gauche0.9.10)
(do((a 0 b)(b 1(+ a b))(l '()`(,@l ,a)))((> b 2e4)l))
```
```Java:Java(JShell11.0.11)
for(int a=0,b=1;b<1e4;System.out.println(b=a-b))a+=b;
```
```scala:Scala(2.11.12/Java11.0.11)
var a=0;var b=1;while(b<1e4){println(a);b=a+b;a=b-a;}
```
```bash:bash(5.0.3)
a=0;b=1;for i in {0..21};do echo $a;t=$((a+b));a=$b;b=$t;done
```
```kotlin:Kotlin(1.5.20)
fun f(a:Int,b:Int):Int=if(a<1e4){println(a);f(b,a+b)}else a;f(0,1)
```
```logo:LOGO(UCBLogo6.0)
MAKE "A 0 MAKE "B 1 REPEAT 22[PRINT :A MAKE "B :A+:B MAKE "A :B-:A]
```
```elixir:Elixir(iex1.12.0)
Enum.reduce(1..20,[0,1],&(&2++[&1-&1+Enum.at(&2,-2)+List.last(&2)]))
```
```lisp:EmacsLisp(GNUEmacs26.1)
(let((a 0)(b 1))(while(< b 2e4)(princ a)(princ" ")(setq b(+ a b)a(- b a))))
```
```sql:SQL(SQLite3)
WITH t(a,b)AS(SELECT 0,1 UNION SELECT b,a+b FROM t)SELECT a FROM t LIMIT 22;
```
```erl:Erlang(OTP21)
lists:reverse(lists:foldl(fun(_,A)->[hd(A)+hd(tl(A))|A] end,[1,0],lists:seq(1,20))).
```
```sh:sh(dash0.5.10)
a=0;b=1;while true;do t=$((a+b));echo $a;case $a in(10946)break;;esac;a=$b;b=$t;done
```
```vimscript:Vim(8.1)（：でコマンドラインモードに入ってから入力）
echo {g->g(g)}({g->{n,r->n<0?r :g(g)(n-1,[{g->g(g)}({g->{n,a,b->n==0?a :g(g)(n-1,b,a+b)}})(n,0,1)]+r)}})(21,[])
```
```sh:Excel(2021-06-25時点ベータ版)
=LAMBDA(g,g(g))(LAMBDA(g,(LAMBDA(n,r,IF(n<0,r,g(g)(n-1,LAMBDA(g,g(g))(LAMBDA(g,LAMBDA(n,a,b,IF(n=0,a,g(g)(n-1,b,a+b)))))(n,0,1)&" "&r))))))(21,"")
```

# 各言語での記述例（番外編）

筆者が実行未確認だったり，ワンライナーと呼ぶには微妙な実行方法（シェル経由やGUI操作，基本ライブラリ追加読込等）だったりするものです．進捗（？）によっては本来の記述例に昇格するかも．

```:Z80(ZK-80webv0.4)
8000 AF 67 6F 11 01 00 F9 E5 19 EB 82 30 FA
```
```sh:x86-64
echo '.globl main;main:mov $0,%ax;mov $1,%dx;lea f(%rip),%rdi;mov $22,%ecx;l:mov %ax,(%rdi);add $2,%rdi;add %dx,%ax;xchg %dx,%ax;loop l;mov $0,%eax;ret;.bss;f:.zero 44'|gcc -x assembler -&&./a.out
```
```sh:C(gcc8.3.0+dash0.5.10)
echo 'a;main(b){for(;b<1e4;printf("%d ",b=a-b))a+=b;}'|gcc -w -x c -&&./a.out
```
```sh:C++(g++9.3.0+dash0.5.10)
printf "#include<iostream>\\nint main(){for(int a=0,b=1;b<1e4;std::cout<<(b=a-b)<<' ')a+=b;}"|g++ -x c++ -&&./a.out
printf '#include<cstdio>\nint a,b=1;int main(){for(;b<1e4;printf("%%d ",b=a-b))a+=b;}'|g++ -x c++ -&&./a.out
```
```sh:Fortran(f778.3.0+dash0.5.10)
echo '      a=0;b=1;doi=0,21;print*,a;b=a+b;a=b-a;enddo;end'|f77 -x f77 -&&./a.out
```
```sh:GNUassembler(2.34+bash5.0.17)
as <<< '.altmacro;.macro p n;.print "\n";.endm;a=0;b=1;.rept 22;p%a;b=a+b;a=b-a;.endr'
```
```sh:Prolog(SWI-Prolog8.0.2+dash0.5.10)
echo 'assert(f(0,A,_,A)). assert((f(N,A,B,R):-X is N-1,Y is A+B,f(X,B,Y,R))). assert(p:-forall(between(0,21,X),(f(X,0,1,R),format(R),nl))). p,halt.'|swipl -q
```
```golang:Go言語(1.16.5/gore0.5.2-autoimport)
a,b:=0,1;for i:=0;i<22;i++{fmt.Println(a);a,b=b,a+b}
```
```sh:Rust(1.47.0+dash0.5.10)
echo 'fn main(){let mut a=0;let mut b=1;while a<10947{println!("{}",a);b=a+b;a=b-a;}}'|rustc -&&./rust_out
```

# 備考

## 記事に関する補足

* ~~reduceつおい．~~次々と反復構文に置き換えられてしまった…．
* Jの例は[ねっとからのぱくり](https://kquoe2.hatenablog.com/entry/20010207/p1)です．独自には記述できなかった…．→そしてそのぱくりから更に短く（コメントより）．Jにはどうあがいても短さでは勝てなさそう．→Rakuが勝った．→Jが追い上げた

## 更新履歴
* 2021-07-25：Jの記述例を変更（コメントより）
* 2021-07-20：Jの記述例を変更（コメントより）
* 2021-07-18：Jの記述例を変更（コメントより）
* 2021-06-26：Kotlinの記述例を変更（コメントより）
* 2021-06-25：Excel（ベータ版）の記述例を追加
* 2021-06-23：Python3.8の記述例を変更（コメントより）
* 2021-06-21：Perlの記述例を変更（コメントより）
* 2021-06-21：冒頭に『素数一覧』続編記事について記載
* 2021-06-20：Perlの記述例・実行方法を変更（コメントより）
* 2021-06-20：C++の記述例（番外編）を変更・追加（コメントより）
* 2021-06-20：Go言語，Rust，C++の記述例（番外編）を追加
* 2021-06-19：GNU assemblerの記述例（番外編）を変更（コメントより）
* 2021-06-19：GNU assemblerの記述例（番外編）を追加（コメントより）
* 2021-06-19：PHP，bc，calcの記述例を変更（コメントより）
* 2021-06-19：Vim，bc，calc，APL，Elixirの記述例を追加（コメント等より）
* 2021-06-18：制約欄を更に整理・書き直し
* 2021-06-18：Smalltalkの記述例を修正（Twitterより）
* 2021-06-18：Haskellの記述例を変更（Twitterより）
* 2021-06-18：冒頭にYouTubeに公開した記述例の動画（2021-06-17更新時点）を追加
* 2021-06-18：Kotlin，dc，PowerShell，Emacs Lisp，bash，PHP，Scala，LOGOの記述例を追加（コメント等より）
* 2021-06-17：Fortranの記述例（番外編）を追加（コメントより）
* 2021-06-17：制約欄を整理・書き直し
* 2021-06-17：冒頭にワンライナーに関する注意書きを追加
* 2021-06-17：Z80の記述例（番外編）を変更（コメントより）
* 2021-06-17：制約欄に『0～21番目の値（0番目は0，1番目は1）を求める』を明記
* 2021-06-17：IchigoJamBASICの記述例を番外編から移動（コメントより）
* 2021-06-17：Cの記述例（番外編）を変更（コメントより）
* 2021-06-17：awk，Haskell，PostScriptの記述例を変更（コメント，Twitterより）
* 2021-06-17：Java，Scheme（Gauche限定），sh(dash)の記述例を追加
* 2021-06-16：Cの記述例（番外編）を変更（コメントより）
* 2021-06-16：各言語での記述例（番外編）の欄を追加（Z80，x86-64，IchigoJamBASIC，C，Prolog）
* 2021-06-16：下記制約欄記載に基づきScheme/Common Lisp，awkの記述例を変更
* 2021-06-16：制約欄に『21番目の値を求める』は『値が10946を超えるまで求める』も可の旨記載
* 2021-06-16：記述例について，最新版での記述の長さ順に整列
* 2021-06-16：制約欄にREPLを用いたワンライナー実行の想定，副作用OKの旨記載
* 2021-06-16：JavaScript，Perl，Smalltalk，Python2，Python3，Rubyの記述例を変更（コメントより）
* 2021-06-16：Forth，R，SQL，Raku，Erlang，awk，Luaの記述例を追加（Twitter，コメント等より）
* 2021-06-16：確認した実装・バージョンとREPL実行の旨記載
* 2021-06-15：Ruby，Jの記述例を変更（Twitter，コメントより）
* 2021-06-15：SchemeとCommon Lispの記述例を変更・統合（Twitterより）
* 2021-06-15：Haskell，PostScript，Smalltalk，Perl，Clojure，Julia，Python3.8の記述例を追加（Twitter，コメントより）
* 2021-06-15：初版公開（Scheme，Common Lisp，Python2，Python3，Ruby，JavaScript，J）