2014-04-11 42 views
-1

這裏是一個組合:我可以從這個散列中得到多少種可能的組合?

 
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 

如果有一個公式請分享

所有的答案讚賞。

+1

每個「對」中可能有多少項目?從你的第一個例子看來,你正在尋找數組值中的兩個或更多項目的所有組合? – maerics

+0

對不起,剛纔看到你的問題,它可能是一個,兩個或所有的鍵值不超過一個值 –

+0

':present,:third,:singular,:active,:indicators,:habitual'等不是一對。 – sawa

回答

2

要獲得所有組合的列表,你可以做到以下幾點:

OPTIONS.values.map{ |v| v + [nil]}.inject(&:product).map(&:flatten).map(&:compact).uniq 

它所做的是:

  • 增加nil到每個列表(它沒有被選擇的選項)
  • 創建每個列表之一的每個組合
  • 上面創建列表名單的,所以我們將其壓扁到列表
  • 從任何combintation刪除任何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 
+0

嗯......這個項目是重複的... ':現在,:第三,:奇異的,:活躍的,:指示性的,:習慣性的# –

+0

有趣的... don '不知道爲什麼會發生這種情況,添加'uniq'來刪除重複項目 –

+0

該死的,我很疑惑,你的回答是一個紅寶石答案,基本上我可以抓住這個代碼....但是獲得更多命中的人在學術上更正確... hmmmm –

4

如果我理解正確的問題,其公式爲:

(|A1|+1)*(|A2|+1)*...*(|An|+1) - 1 

Ai代表集#i的(例如緊張,人),和|Ai|是集Ai的大小。 這個想法是,每一組大小N有N + 1個選項 - N個值中的一個,或者這個集合中沒有任何值。這些組合是唯一的,因爲任何兩種組合的代表至少有一組不同。

最後的減號是爲了消除空組合。 您提供的數據,其結果是4031

+0

你應該把'| foo |'解釋爲「被稱爲foo的集合的大小」。 。 。答案是簡潔的(並且是正確的IMO),但可以使用OP不熟悉的符號 –

+0

@NeilSlater:你說得對,我會添加更多細節。 –

+1

OP沒有排除空的「對」,是嗎? ;-) –

相關問題