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.@
在该数组之前放置两个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
表的第t行时,
)p;
获取最后一个元素,将其打印,然后丢弃该行的其余部分。
对于后代,基于此原理的三个38个字符的解决方案:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/