Golfscript - 56 50 49 48 41 40 38 37 ký tự
n%{~),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;}/
Lưu ý: việc này xử lý nhiều dòng đầu vào, nhanh (1/8 giây để thực hiện các trường hợp kiểm tra) và không phá vỡ bất kỳ đầu vào hợp pháp nào.
(Phiên bản đầu tiên cũng là chương trình Golfscript đầu tiên của tôi; cảm ơn eBusiness đã chỉ ra một số thủ thuật mà tôi đã bỏ lỡ).
Để làm cho bài viết này trở thành một bài viết giáo dục hữu ích, đây là một lời giải thích về cách thức hoạt động của nó. Chúng tôi bắt đầu với sự tái phát f(n, k) = k * (f(n-1, k) + f(n-1, k-1))
. Điều này có thể được hiểu một cách kết hợp khi nói rằng để đặt n
các quả bóng có thể phân biệt vào k
các thùng có thể phân biệt sao cho mỗi thùng chứa ít nhất một quả bóng, bạn chọn một trong các k
thùng cho quả bóng đầu tiên ( k *
) và sau đó nó sẽ chứa ít nhất một quả bóng nữa ( f(n-1, k)
) hoặc nó sẽ không ( f(n-1, k-1)
).
Các giá trị kết quả từ dạng này là một lưới; lấy n
làm chỉ mục hàng và k
làm chỉ mục cột và lập chỉ mục từ 0, nó bắt đầu
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 ...
. . . . . . . .
. . . . . . . .
. . . . . . . .
Vì vậy, chuyển sang chương trình,
n%{~ <<STUFF>> }/
chia đầu vào thành các dòng và sau đó cho mỗi dòng đánh giá nó, đặt n
và k
trên ngăn xếp, sau đó gọi <<STUFF>>
, như sau:
),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;
Điều này tính toán các k+1
mục đầu tiên của n+1
hàng thứ của lưới đó. Ban đầu ngăn xếp là n k
.
),
đưa ra ngăn xếp n [0 1 2 ... k]
{!}%
cho ngăn xếp của n [1 0 0 ... 0]
nơi có k
0s.
\{ <<MORE STUFF>> }*
đưa n
lên đỉnh và làm cho nó số lần chúng ta thực hiện <<MORE STUFF>>
.
Ngăn xếp của chúng tôi hiện là một hàng của bảng: [f(i,0) f(i,1) ... f(i,k)]
0.@
đặt một vài số 0 trước mảng đó. Cái đầu tiên sẽ là j
và cái thứ hai sẽ là f(i,j-1)
.
{ <<FINAL LOOP>> }/
các vòng lặp thông qua các phần tử của mảng; đối với mỗi cái, nó đặt nó lên trên cùng của ngăn xếp và sau đó thực thi thân vòng lặp.
.@+2$*@)@
là thao tác ngăn xếp nhàm chán để lấy ... j f(i,j-1) f(i,j)
và sản ... j*(f(i,j-1)+f(i,j)) j+1 f(i,j)
;;]
xuất bật ra khỏi phần còn lạik+1 f(i,k)
và tập hợp mọi thứ thành một mảng, sẵn sàng cho vòng tiếp theo.
Cuối cùng, khi chúng ta tạo n
hàng thứ ba của bảng,
)p;
lấy phần tử cuối cùng, in nó và loại bỏ phần còn lại của hàng.
Đối với hậu thế, ba giải pháp 38-char theo nguyên tắc này:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/