# Example 1
People = ["Terry", "Merry"]
Fruit = ["Apple","Grape","Peach"]
# Possible solutions:
[
{"Terry"=>"Apple","Merry"=>"Grape"},
{"Terry"=>"Apple","Merry"=>"Peach"},
{"Terry"=>"Grape","Merry"=>"Apple"},
{"Terry"=>"Grape","Merry"=>"Peach"},
{"Terry"=>"Peach","Merry"=>"Apple"},
{"Terry"=>"Peach","Merry"=>"Grape"},
]
# Example 2
People = ["Terry", "Merry", "Perry"]
Fruit = ["Apple","Grape"]
# Possible solutions:
[
{"Terry"=>"Apple","Merry"=>"Grape","Perry"=>nil},
{"Terry"=>"Apple","Merry"=>nil,"Perry"=>"Grape"},
{"Terry"=>"Grape","Merry"=>"Apple","Perry"=>nil},
{"Terry"=>"Grape","Merry"=>nil,"Perry"=>"Apple"},
{"Terry"=>nil,"Merry"=>"Apple","Perry"=>"Grape"},
{"Terry"=>nil,"Merry"=>"Grape","Perry"=>"Apple"},
]
試圖遞回地解決這個問題(對于這個練習是必要的,但如果你認為遞回是不可能的,請告訴我)。
我覺得基本上我首先為一個隨機的人分配一個水果,然后將其添加到所有可能的解決方案中,這些解決方案是由分配剩余人剩余水果的較小子集產生的。
例如,對于示例 1,我為 Terry 分配了一個蘋果,然后將其與 Merry 可以獲得的剩余可能選項(葡萄或桃子)進行匯總。
然后只需重復更改分配給第一個隨機人的水果(例如,在示例 1 中,特里先得到葡萄然后是桃子)。
我覺得這聽起來很簡單,但我很掙扎。
uj5u.com熱心網友回復:
它可以遞回地完成如下。
def hmmm(people, fruit)
adj_fruit = fruit [nil]*([people.size-fruit.size, 0].max)
recurse(adj_fruit).map { |a| people.zip(a).to_h }
end
def recurse(fruit_left, fruit_selected = [])
return [fruit_selected fruit_left] if fruit_left.size == 1
fruit_left.each_with_object([]) do |f,a|
recurse(fruit_left - [f], fruit_selected [f]).each { |e| a << e }
end
end
hmmm(["Terry", "Merry"], ["Apple", "Grape", "Peach"])
#=> [{"Terry"=>"Apple", "Merry"=>"Grape"}, {"Terry"=>"Apple", "Merry"=>"Peach"},
# {"Terry"=>"Grape", "Merry"=>"Apple"}, {"Terry"=>"Grape", "Merry"=>"Peach"},
# {"Terry"=>"Peach", "Merry"=>"Apple"}, {"Terry"=>"Peach", "Merry"=>"Grape"}]
這里 adj_fruit #=> ["Apple", "Grape", "Peach"]
hmmm(["Terry", "Merry", "Perry"], ["Apple", "Grape"])
#=> [{"Terry"=>"Apple", "Merry"=>"Grape", "Perry"=>nil},
# {"Terry"=>"Apple", "Merry"=>nil, "Perry"=>"Grape"},
# {"Terry"=>"Grape", "Merry"=>"Apple", "Perry"=>nil},
# {"Terry"=>"Grape", "Merry"=>nil, "Perry"=>"Apple"},
# {"Terry"=>nil, "Merry"=>"Apple", "Perry"=>"Grape"},
# {"Terry"=>nil, "Merry"=>"Grape", "Perry"=>"Apple"}]
在這里adj_fruit #=> ["Apple", "Grape", nil]。
我們可以通過從最后一行中洗掉來看到map的接收器。hmmm.map { |a| people.zip(a).to_h }
def hmmm(people, fruit)
adj_fruit = fruit [nil]*([people.size-fruit.size, 0].max)
recurse(adj_fruit)
end
hmmm(["Terry", "Merry"], ["Apple","Grape","Peach"])
#=> [["Apple", "Grape", "Peach"], ["Apple", "Peach", "Grape"],
# ["Grape", "Apple", "Peach"], ["Grape", "Peach", "Apple"],
# ["Peach", "Apple", "Grape"], ["Peach", "Grape", "Apple"]]
更傳統的解決方案,例如以下解決方案,將不使用遞回。
def hmmm(people, fruit)
(fruit [nil]*[people.size - fruit.size, 0].max).
permutation(people.size).
map { |a| people.zip(a).to_h }
end
這將產生與上面所示的遞回解決方案相同的回傳值。
請參閱Array#permutation和Enumerable#zip。
uj5u.com熱心網友回復:
如果len(people) <= len(fruit),那么你可以使用
for pieces in itertools.permutations(fruit, len(people)):
assign the pieces of fruit to the people in order
如果len(people) > len(fruit),則使用
for eaters in itertools.permutations(people, len(fruit))
assign the eaters to the fruit in order, and the others get nothing
我不知道如何將兩個單獨的案例合并為一個案例
我現在看到這應該是遞回解決的。誤讀原文。
讓我們來看看可能性
任務(人,水果):
如果
len(people) == 0,那么你就完成了,有了空的解決方案。(不要與沒有解決方案混淆。)如果
len(fruit) == 0,那么沒有人得到任何果實。同樣,這是一個實際的解決方案。如果
len(people) <= len(fruit),則第一個人得到一些水果,附加到其余人得到剩余水果的所有可能結果上。如果
len(people) > len(fruit),那么第一個人要么得到一塊水果,要么不得到一塊水果,然后遞回地其他人得到剩下的任何東西。
留給您如何撰寫代碼的練習。
uj5u.com熱心網友回復:
對于任何人的未來參考,這是我使用遞回的答案。
請注意,“nil”多計;由于“nil”被視為唯一條目,因此代碼讀取{"Terry"=>"apple","Merry"=>"nil","Perry"=>"nil"}和{"Terry"=>"apple","Perry"=>"nil","Merry"=>"nil"}作為 2 個不同的解決方案。我沒有進一步調查,因為這對于作為其中一部分的練習來說并不是非常現實。
出于同樣的原因,我也沒有進一步調查,但使用字串"nil"與nil產生不同的結果
def pure5(people, fruit, solution = [])
people_count = people.size
fruit_count = fruit.size
diff = people_count - fruit_count
diff.times { fruit << "nil" } if diff > 0
people.each do |p|
fruit.each do |f|
if people.size == 1
obj = {}
obj[p] = f
solution << obj
else
partial_solution = pure5(people - [p], fruit - [f])
partial_solution.each do |s|
s[p] = f
end
solution = solution partial_solution
end
end
return solution
end
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/342931.html
