Golfscript- 56 50 49 48 41 40 38 37 chars
n%{~),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;}/
注:これは複数行の入力を処理し、高速(テストケースを実行するのに1/8秒)であり、正当な入力に対して中断しません。
(最初のバージョンは、私の最初のGolfscriptプログラムでもありました。見逃したいくつかのトリックを指摘してくれたeBusinessに感謝します)。
これを有益な教育記事にするために、その仕組みについて説明します。繰り返しから始めf(n, k) = k * (f(n-1, k) + f(n-1, k-1))
ます。これは、場所にいることを言うようcombinatorically理解できるn
で区別できるボールk
の各バケットは、少なくとも1個のボールを含むように区別可能なバケツ、あなたはのいずれかの選択k
(第1ボール用バケットk *
)、その後、どちらかそれは(少なくとも1個の以上のボールが含まれていますf(n-1, k)
)またはそれは(f(n-1, k-1)
)しません。
この結果の値はグリッドを形成します。撮影n
行インデックスとして、およびk
それが起動0から両方の列インデックスとインデックスとして
1 0 0 0 0 0 0 ...
0 1 0 0 0 0 0 ...
0 1 2 0 0 0 0 ...
0 1 6 6 0 0 0 ...
0 1 14 36 24 0 0 ...
0 1 30 150 240 120 0 ...
0 1 62 540 1560 1800 720 ...
. . . . . . . .
. . . . . . . .
. . . . . . . .
だからプログラムに目を向けて、
n%{~ <<STUFF>> }/
行に入力を分割し、各ライン評価するためには、パッティングn
とk
スタックに、次に呼び出す<<STUFF>>
以下の通りであります:
),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;
これにより、そのグリッドのth行の最初のk+1
エントリが計算されますn+1
。最初のスタックはn k
です。0 がある場所の
),
スタックをn [0 1 2 ... k]
{!}%
与えます。を最上部に移動し、実行回数にします。
現在、スタックはテーブルの行です。その配列の前にいくつかの0を置きます。最初のものはとなり、2番目のものはとなります。配列の要素をループします。それぞれについて、スタックの一番上に置き、ループ本体を実行します。取るためにスタック操作を退屈され、歩留まりのオフポップ左オーバーn [1 0 0 ... 0]
k
\{ <<MORE STUFF>> }*
n
<<MORE STUFF>>
[f(i,0) f(i,1) ... f(i,k)]
0.@
j
f(i,j-1)
{ <<FINAL LOOP>> }/
.@+2$*@)@
... j f(i,j-1) f(i,j)
... j*(f(i,j-1)+f(i,j)) j+1 f(i,j)
;;]
k+1 f(i,k)
そして、すべてを配列に集めて、次のループの準備をします。
最後に、n
テーブルのth行目を生成し
)p;
たら、最後の要素を取得して印刷し、残りの行を破棄します。
後世のために、この原則に関する3つの38文字のソリューション:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/