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+1th-й строки этой сетки. Изначально стек есть n k.
),дает стек n [0 1 2 ... k]
{!}%дает стек, n [1 0 0 ... 0]где есть k0.
\{ <<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)и собирает все в массив, готовый к следующему обходу цикла.
Наконец, когда мы сгенерировали nth-ю строку таблицы,
)p;берём последний элемент, печатаем его и отбрасываем оставшуюся часть строки.
Для потомков три 38-символьных решения по этому принципу:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/