Golfscript - 56 50 49 48 41 40 38 37 karakter
n%{~),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;}/
Catatan: ini menangani banyak jalur input, cepat (1/8 detik untuk mengerjakan kasus uji), dan tidak merusak input hukum apa pun.
(Versi pertama juga merupakan program Golfscript pertama saya; terima kasih kepada eBusiness karena menunjukkan beberapa trik yang saya lewatkan).
Untuk menjadikan ini sebagai pos pendidikan yang bermanfaat juga, berikut ini penjelasan cara kerjanya. Kita mulai dengan pengulangan f(n, k) = k * (f(n-1, k) + f(n-1, k-1))
. Hal ini dapat dipahami secara kombinatoris dengan mengatakan bahwa untuk menempatkan n
bola yang dapat dibedakan dalam k
ember yang dapat dibedakan sedemikian rupa sehingga setiap ember berisi setidaknya satu bola, Anda memilih salah satu k
ember untuk bola pertama ( k *
) dan kemudian ia akan mengandung setidaknya satu bola lagi ( f(n-1, k)
) atau itu tidak akan ( f(n-1, k-1)
).
Nilai yang dihasilkan dari formulir ini berupa kisi; mengambil n
sebagai indeks baris dan k
sebagai indeks kolom dan pengindeksan dari 0 dimulai
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 ...
. . . . . . . .
. . . . . . . .
. . . . . . . .
Jadi beralih ke program,
n%{~ <<STUFF>> }/
Membagi input menjadi garis dan kemudian untuk setiap baris mengevaluasinya, meletakkan n
dan k
di stack, dan kemudian memanggil <<STUFF>>
, yaitu sebagai berikut:
),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;
Ini menghitung k+1
entri pertama dari n+1
baris ke-k dari kisi itu. Awalnya tumpukan itu n k
.
),
memberi tumpukan n [0 1 2 ... k]
{!}%
memberi tumpukan di n [1 0 0 ... 0]
mana ada k
0s.
\{ <<MORE STUFF>> }*
membawa n
ke atas dan membuatnya menjadi berapa kali kita mengeksekusi <<MORE STUFF>>
.
Tumpukan kami saat ini adalah deretan tabel: [f(i,0) f(i,1) ... f(i,k)]
0.@
menempatkan beberapa 0 sebelum array itu. Yang pertama akan menjadi j
dan yang kedua akan f(i,j-1)
.
{ <<FINAL LOOP>> }/
loop melalui elemen array; untuk masing-masing menempatkannya di atas tumpukan dan kemudian menjalankan loop body.
.@+2$*@)@
adalah manipulasi stack membosankan untuk mengambil ... j f(i,j-1) f(i,j)
dan menghasilkan ... j*(f(i,j-1)+f(i,j)) j+1 f(i,j)
;;]
muncul dari sisak+1 f(i,k)
dan mengumpulkan semuanya menjadi sebuah array, siap untuk putaran berikutnya loop.
Akhirnya, ketika kita telah membuat n
baris ke-5 dari tabel,
)p;
ambil elemen terakhir, cetak, dan buang sisa baris.
Untuk anak cucu, tiga solusi 38-char pada prinsip ini:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/