Golfscript - 56 50 49 48 41 40 38 37 символов
n%{~),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;}/
Примечание: это обрабатывает несколько строк ввода, быстро (1/8 секунды, чтобы выполнить тестовые случаи) и не прерывается для любого легального ввода.
(Первая версия была также моей первой в истории программой Golfscript; спасибо eBusiness за указание на несколько уловок, которые я пропустил).
Чтобы сделать этот пост полезным, вот объяснение того, как оно работает. Начнем с повторения f(n, k) = k * (f(n-1, k) + f(n-1, k-1))
. Комбинатически это можно понимать как выражение, что для помещения n
различимых шаров в k
различимые ведра так, чтобы в каждом ведре был хотя бы один шарик, вы выбираете одно из k
ведер для первого шарика ( k *
), а затем либо оно будет содержать хотя бы еще один шарик ( 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;
Это вычисляет первые k+1
записи n+1
th-й строки этой сетки. Изначально стек есть n k
.
),
дает стек n [0 1 2 ... k]
{!}%
дает стек, n [1 0 0 ... 0]
где есть k
0.
\{ <<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;
берём последний элемент, печатаем его и отбрасываем оставшуюся часть строки.
Для потомков три 38-символьных решения по этому принципу:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/