我需要计算从投掷K个N面骰子中可能出现的不同点数组合。我的定义是,例如{1,1,2,3,4}等同于{1,4,3,1,2}(顺序无关紧要),但与{1,1,3,3,3}不同(它们不是相同的结果集)。例如:Yahtzee是一款涉及投掷5个6面骰子的游戏——至少在重新投掷之前如此——因此不同的投掷次数为252。当N=K时,会导致OEIS序列A001700。
如果我没有犯错,这可以通过"(N-1+K)选(N-1)"或等效地"(N+K-1)选K"来给出,即J语言中的
此外,所有这些的单调情况都没有意义:
如果我没有犯错,这可以通过"(N-1+K)选(N-1)"或等效地"(N+K-1)选K"来给出,即J语言中的
K ! <: K + N
。这让我想到了四种不同的隐式表示方法:
d =: ([ ! [: <: +)
。简单的train,没有括号,尽管我需要使用大写字母。d =: ([ (! <:) +)
。没有大写字母,但内部hook需要加括号。d =: (] !&<: +)
。只有三个动词的train,但使用了一个Compose。它使用了(<: N) ! <: K + N
版本。d =: (([ ! +) * ] % +)
。这个将"C(N+K-1,K)"重写为"C(N+K,K)*N/(N+K)"。它更丑陋,但在0个面数的0个骰子的情况下,它给出0而不是1,这可能是一个较少荒谬的答案。
此外,所有这些的单调情况都没有意义:
1 0 0 0 0 ...
前三者和0 1 1 1 ...
第四者。这个动词的更合理的单调形式应该是反身形式,如d~
所示,因此把这个动词定义为(d~ : d)
是否更好?
(*&* * [ (! <:) +)
?这是个好主意。你不能只对积进行符号函数处理,因为我认为用N面骰子掷0次有一种组合意义。但这个想法引导我们到了(*@] * [ (! <:) +)
,它符合要求。不错! - algorithmshark(*@] * [ (! <:) +)
符合要求,那么(* *) @ ([ (! <:) +)
也应该符合。如果零面骰子只能朝一个方向投掷,那么( (* *) (! <:) + )
也可以使用。 - bob