Reputation: 1520
I am doing something very much like the knapsack problem, in which I want to iterate over all combinations of an arbitrary number of inputs.
For example, if my function takes 3 arrays, I want to get all i×j×k combinations. If my function takes 5 arrays, I want to get all i×j×k×l×m combinations.
Example one:
result = all_products([1,2,3,4,5], [1,2,3], [10,20,30,40,50,60,70,80])
result.length == 120
Example two:
result = all_products([1,2,3], [1,2,3], [1,2,3], [1,2,3], [1,2,3], [1,2,3])
result.length == 729
But I don't know how many arrays I am going to take in.
What's the way to do this in Ruby?
This is NOT asking how to find all pairs of 1 array. My input arrays will likely all be different.
Here is what I tried so far:
def self.all_combinations(*sets)
input = *sets;
prod = sets.inject(1) { |p,a| p * a.length }
prod.times do |p|
args = []
index = p
input.each do |array|
quotient = index / array.length
remainder = index % array.length
args << array[remainder]
index = quotient
pp args
end
end
Upvotes: 1
Views: 171
Reputation: 1352
I would start off with getting the 'product' of 2 arrays:
def product2(array1, array2)
array1.map { |e1| array2.map { |e2| e1*e2 } }.flatten
end
You can then generalize to any number of arrays:
def all_products(*arrays)
arrays.reduce([1]) { |result, array| product2(result, array) }
end
You might want to handle corner cases (for example empty arrays or no input arrays at all)
Upvotes: 1