вы можете достичь линейной сложности O(N)
производительность
РЕДАКТИРОВАТЬ Я предположил, что вы ищете комбинации 2, что, как я понял, неверно.
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"]]
Если длина ввода мала, вы можете выбрать более короткое O(N^2)
решение:
input.to_a.
permutation(2).
select{|(n1,v1), (n2, v2)| n1 != n2 && v1 + v2 == 100 }.
map{ |l,r| [l.first, r.first].sort }.
uniq
#=> [["Hulk", "IronMan"], ["Black Panther", "Groot"], ["Captain America", "Thor"]]