ruby-on-rails - 用 Ruby on Rails 哈希来计算每个值的总和

  显示原文与译文双语对照的内容
109 1

我有如下所示的哈希:

input = {
"Hulk" => 25,
"IronMan" => 75,
"Groot" => 51,
"Captain America" =>50,
"Spider Man" => 40,
"Thor" => 50,
"Black Panther" => 49
}

我需要找到一组超级魔术,它的价值将是 100,和它的他值一样,比如 船长,= 100.

我可以使用以下索引迭代散列:

hash.each_with_index { |(key,value),index|.. . }

使用内部循环比较每个值。

有什么更好和简单的方法来解决这个问题?

时间:原作者:0个回答

139 2

你可以实现线性复杂度 O(N) 性能智能

input = { 
"Hulk" => 25,
"IronMan" => 75,
"Groot" => 51,
"Captain America" => 50,
"Spider Man" => 40,
"Thor" => 50,
"Black Panther" => 49
}
# Create inverse lookup map
inverse_input = input.each.with_object(Hash.new([])){ |(k, v), h| h[v] += [k] }
#=> {25=>["Hulk"], 75=>["IronMan"], 51=>["Groot"], 50=>["Captain America","Thor"], 40=>["Spider Man"], 49=>["Black Panther"]}
input.flat_map do |hero, power| 
 # Get heroes with needed power only
 other_heroes = inverse_input[100 - power]
 # Remove current hero from the list
 other_but_this = other_heroes.reject{ |name| name == hero }
 # Map over remaining heroes 
 # and sort them for later `uniq` filtering
 other_but_this.map { |h| [hero, h].sort }
end.compact.uniq
# compact will remove nils
# uniq will remove duplicates
#=> [["Hulk","IronMan"], ["Black Panther","Groot"], ["Captain America","Thor"]]
原作者:
91 1

可能的解决方案是:

all_options = input.map { |a| input.without(a).map { |b| [a, b] } }.flatten(1).sort.uniq
valid_options = all_options.select { |r| r.sum(&:second) == 100 }

修改,可以使用 input.combination(2) ( 哎呀) 实现第一行。这个问题可以通过以下方法解决:

input.combination(2).select { |r| r.sum(&:second) == 100 }.map(&:to_h)
原作者:
94 5

如果输入不大,则可以使用 Array#combination:

1.upto(input.size).
 flat_map do |i|
 input.to_a.combination(i).select do |arrs|
 arrs.map(&:last).reduce(:+) == 100
 end
 end.
 map(&:to_h)
#⇒ [{"Hulk"=>25,"IronMan"=>75},
# {"Groot"=>51,"Black Panther"=>49},
# {"Captain America"=>50,"Thor"=>50}]

如果你确定只有 2个英雄是 100的功率和,那么将 1.upto(input.size) 循环替换为 2 中的循环。在这种情况下即使是巨大的输入也足够快。

原作者:
130 5

try

input["Thor"] + input["Captain America"]

你创建的输入对象是一个哈希,最简单的方法是从哈希中获取与它的关联的密钥:

hash["key"]
原作者:
83 4

我想这就是你要找

resultArr = []
input.keys.each do |keyName|
 input.each do |inKey, inValue|
 ((resultArr <<[keyName, inKey]) if ((input[keyName] + inValue) == 100)) unless (keyName == inKey)
 end
end
result = []
resultArr.each do |resArr| result <<resArr.sort end
result.uniq!
puts result
原作者:
...