Golfscript - 56 50 49 48 41 40 38 37 Zeichen
n%{~),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;}/
Hinweis: Dies verarbeitet mehrere Eingabezeilen, ist schnell (1/8 Sekunden für die Testfälle) und unterbricht keine legalen Eingaben.
(Die erste Version war auch mein erstes Golfscript-Programm; dank eBusiness für den Hinweis auf einige Tricks, die ich verpasst habe).
Um dies auch zu einem nützlichen Lehrbeitrag zu machen, finden Sie hier eine Erklärung, wie es funktioniert. Wir beginnen mit der Wiederholung f(n, k) = k * (f(n-1, k) + f(n-1, k-1))
. Dies kann kombinatorisch so verstanden werden, dass man, um n
unterscheidbare Bälle in k
unterscheidbare Eimer zu legen, so dass jeder Eimer mindestens einen Ball enthält, einen der k
Eimer für den ersten Ball auswählt ( k *
) und dann entweder mindestens einen weiteren Ball enthält ( f(n-1, k)
) oder es wird nicht ( f(n-1, k-1)
).
Die daraus resultierenden Werte bilden ein Raster; Es wird n
als Zeilenindex und k
als Spaltenindex verwendet und beide von 0 indiziert
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 ...
. . . . . . . .
. . . . . . . .
. . . . . . . .
Wenden wir uns also dem Programm zu.
n%{~ <<STUFF>> }/
teilt die Eingabe in Zeilen auf und wertet sie dann für jede Zeile aus, setzt n
und k
auf den Stapel und ruft dann <<STUFF>>
Folgendes auf:
),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;
Dies berechnet die ersten k+1
Einträge der n+1
dritten Zeile dieses Gitters. Anfangs ist der Stapel n k
.
),
gibt Stapel von n [0 1 2 ... k]
{!}%
gibt Stapel von, n [1 0 0 ... 0]
wo es k
0s gibt.
\{ <<MORE STUFF>> }*
bringt das n
nach oben und macht es so oft, wie wir es ausführen <<MORE STUFF>>
.
Unser Stack ist derzeit eine Zeile der Tabelle: [f(i,0) f(i,1) ... f(i,k)]
0.@
Setzt ein paar Nullen vor dieses Array. Der erste wird sein j
und der zweite wird sein f(i,j-1)
.
{ <<FINAL LOOP>> }/
Schleifen durch die Elemente des Arrays; für jeden legt es es auf den Stapel und führt dann den Schleifenkörper aus.
.@+2$*@)@
ist eine langweilige Stapelmanipulation, um Pops vom Rest zu nehmen ... j f(i,j-1) f(i,j)
und zu erzielen... j*(f(i,j-1)+f(i,j)) j+1 f(i,j)
;;]
k+1 f(i,k)
und sammelt alles in einem Array, bereit für die nächste Runde.
Wenn wir die n
dritte Zeile der Tabelle generiert haben, nehmen wir
)p;
das letzte Element, drucken es und verwerfen den Rest der Zeile.
Für die Nachwelt drei 38-Zeichen-Lösungen nach diesem Prinzip:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/