Golfscript - 56 50 49 48 41 40 38 37 caractères
n%{~),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;}/
Remarque: cela gère plusieurs lignes d'entrée, est rapide (1/8 s pour faire les cas de test) et ne se casse pour aucune entrée légale.
(La première version était également mon tout premier programme Golfscript; merci à eBusiness d'avoir signalé plusieurs trucs que j'ai manqués).
Afin d'en faire également un poste éducatif utile, voici une explication de son fonctionnement. Nous commençons par la récurrence f(n, k) = k * (f(n-1, k) + f(n-1, k-1))
. Ceci peut être compris de manière combinatoire comme disant que pour placer n
des boules distinctes dans k
des seaux reconnaissables de telle sorte que chaque seau contient au moins une balle, vous choisissez l'un des k
seaux pour la première balle ( k *
), puis soit il contiendra au moins une balle supplémentaire ( f(n-1, k)
) ou ce ne sera pas ( f(n-1, k-1)
).
Les valeurs qui en résultent forment une grille; prenant n
comme l'index de ligne et k
comme l'index de colonne et l'indexation à la fois à partir de 0, il commence
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 ...
. . . . . . . .
. . . . . . . .
. . . . . . . .
Passons donc au programme,
n%{~ <<STUFF>> }/
divise l'entrée en lignes, puis pour chaque ligne l'évalue, en mettant n
et k
sur la pile, puis appelle <<STUFF>>
, comme suit:
),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;
Ceci calcule les premières k+1
entrées de la n+1
e ligne de cette grille. Initialement, la pile est n k
.
),
donne pile de n [0 1 2 ... k]
{!}%
donne pile d' n [1 0 0 ... 0]
où il y a des k
0.
\{ <<MORE STUFF>> }*
amène le n
haut et le fait le nombre de fois que nous exécutons <<MORE STUFF>>
.
Notre pile est actuellement une ligne du tableau: [f(i,0) f(i,1) ... f(i,k)]
0.@
met quelques 0 avant ce tableau. Le premier sera j
et le second sera f(i,j-1)
.
{ <<FINAL LOOP>> }/
boucle à travers les éléments du tableau; pour chacun, il le place en haut de la pile puis exécute le corps de la boucle.
.@+2$*@)@
est la manipulation de la pile ennuyeuse pour prendre ... j f(i,j-1) f(i,j)
et donner lieu ... j*(f(i,j-1)+f(i,j)) j+1 f(i,j)
;;]
apparaît sur les restesk+1 f(i,k)
et rassemble tout dans un tableau, prêt pour le prochain tour de boucle.
Enfin, lorsque nous avons généré la n
e ligne du tableau,
)p;
prend le dernier élément, l'imprime et supprime le reste de la ligne.
Pour la postérité, trois solutions de 38 caractères sur ce principe:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/