这是一个组合:
OPTIONS = { :tense => [:present, :past, :future], :person => [:third, :first, :second], :plurality => [:singular, :plural], :diathesis => [:active, :passive], :mood => [:indicative, :imperative, :subjunctive], :aspect => [:habitual, :perfective, :habitual, :progressive, :perfect, :prospective] }
只有一个规则,一个键可以使用一个值
这意味着这些对可能
1. :present, :third, :singular, :active, :indicative, :habitual 2. :present, :third 3. :present, :third, :indicative, :habitual 4. ... etc
然而这些不是:
1. :present, :past, :future 2. :first, :third, :present 3. ... etc
如果有公式,请分享
感谢所有答案。
答案 0 :(得分:4)
如果我正确理解了这个问题,公式是:
(|A1|+1)*(|A2|+1)*...*(|An|+1) - 1
Ai
代表集合#i(例如时态,人物),而|Ai|
代表集合Ai
的大小。
这个想法是每个N大小的集合都有N + 1个选项 - N个值中的一个,或者这个集合中没有值。这些组合是唯一的,因为任何两种组合在至少一组的代表中不同。
最后的减号用于消除空组合。 根据您提供的数据,结果为4031.
答案 1 :(得分:2)
要获取所有组合的列表,您可以执行以下操作:
OPTIONS.values.map{ |v| v + [nil]}.inject(&:product).map(&:flatten).map(&:compact).uniq
它的作用是:
nil
添加到每个列表(未选择的选项)nil
样本组合:
[:future, :first, :active, :perfect]
以上内容将包含空组合([]
),但如果您只想包含两个或更多元素的组合,则可以添加.select { |cmb| cmb.length > 1 }
。
现在你可以算一下:
OPTIONS.values.map{ |v| v + [nil]}.inject(&:product).map(&:flatten).uniq.
map(&:compact).count
# => 3456
OPTIONS.values.map{ |v| v + [nil]}.inject(&:product).map(&:flatten).uniq.
map(&:compact).select { |cmb| cmb.length > 1 }.count
# => 3437
<强>更新强>
@EyalSchneider建议我将他的公式添加到我的答案中,以便更完整:
(|A1|+1)*(|A2|+1)*...*(|An|+1) - 1
基本上它意味着product
中的组合数量是所有相关数组的所有大小的乘积:
OPTIONS.values.map { |x| x.length + 1 }.inject(:*) - 1
# => 4031