All possible distributions for the array, from among

I'm not quite sure how to state this, so I'll just give examples.

If I write:

some_method(["a", "b"], 3) 

I would like for him to return some form

 [{"a" => 0, "b" => 3}, {"a" => 1, "b" => 2}, {"a" => 2, "b" => 1}, {"a" => 3, "b" => 0}] 

If I move to

 some_method(%w(abc), 2) 

The expected return value should be

 [{"a" => 2, "b" => 0, "c" => 0}, {"a" => 1, "b" => 1, "c" => 0}, {"a" => 1, "b" => 0, "c" => 1}, {"a" => 0, "b" => 2, "c" => 0}, {"a" => 0, "b" => 1, "c" => 1}, {"a" => 0, "b" => 0, "c" => 2}] 

Describing this is difficult, so thanks in advance if you answer this question!

+8
ruby permutation
source share
2 answers

Here is one way to do this:

 def some_method ary, num permutations = (0..num).to_a.repeated_permutation(ary.size).select do |ary| ary.reduce(:+) == num end return permutations.map { |a| (ary.zip a).to_h } end p some_method ["a", "b"], 3 #=> [{"a"=>0, "b"=>3}, {"a"=>1, "b"=>2}, {"a"=>2, "b"=>1}, {"a"=>3, "b"=>0}] p some_method %w(abc), 2 #=> [{"a"=>0, "b"=>0, "c"=>2}, {"a"=>0, "b"=>1, "c"=>1}, {"a"=>0, "b"=>2, "c"=>0}, {"a"=>1, "b"=>0, "c"=>1}, {"a"=>1, "b"=>1, "c"=>0}, {"a"=>2, "b"=>0, "c"=>0}] 

Updated answer based on @seph hint

+7
source share

This method uses recursion.

 def meth(keys_remaining, total_remaining) first_key, *rest_keys = keys_remaining return [{ first_key=>total_remaining }] if rest_keys.empty? (0..total_remaining).flat_map { |n| meth(rest_keys, total_remaining-n).map { |g| { first_key=>n }.merge(g) } } end meth ["a", "b", "c"], 2 #=> [{"a"=>0, "b"=>0, "c"=>2}, {"a"=>0, "b"=>1, "c"=>1}, {"a"=>0, "b"=>2, "c"=>0}, {"a"=>1, "b"=>0, "c"=>1}, {"a"=>1, "b"=>1, "c"=>0}, {"a"=>2, "b"=>0, "c"=>0}] meth ["a", "b", "c", "d"], 4 #=> [{"a"=>0, "b"=>0, "c"=>0, "d"=>4}, {"a"=>0, "b"=>0, "c"=>1, "d"=>3}, # {"a"=>0, "b"=>0, "c"=>2, "d"=>2}, {"a"=>0, "b"=>0, "c"=>3, "d"=>1}, # {"a"=>0, "b"=>0, "c"=>4, "d"=>0}, {"a"=>0, "b"=>1, "c"=>0, "d"=>3}, # {"a"=>0, "b"=>1, "c"=>1, "d"=>2}, {"a"=>0, "b"=>1, "c"=>2, "d"=>1}, # {"a"=>0, "b"=>1, "c"=>3, "d"=>0}, {"a"=>0, "b"=>2, "c"=>0, "d"=>2}, # {"a"=>0, "b"=>2, "c"=>1, "d"=>1}, {"a"=>0, "b"=>2, "c"=>2, "d"=>0}, # {"a"=>0, "b"=>3, "c"=>0, "d"=>1}, {"a"=>0, "b"=>3, "c"=>1, "d"=>0}, # {"a"=>0, "b"=>4, "c"=>0, "d"=>0}, {"a"=>1, "b"=>0, "c"=>0, "d"=>3}, # {"a"=>1, "b"=>0, "c"=>1, "d"=>2}, {"a"=>1, "b"=>0, "c"=>2, "d"=>1}, # {"a"=>1, "b"=>0, "c"=>3, "d"=>0}, {"a"=>1, "b"=>1, "c"=>0, "d"=>2}, # {"a"=>1, "b"=>1, "c"=>1, "d"=>1}, {"a"=>1, "b"=>1, "c"=>2, "d"=>0}, # {"a"=>1, "b"=>2, "c"=>0, "d"=>1}, {"a"=>1, "b"=>2, "c"=>1, "d"=>0}, # {"a"=>1, "b"=>3, "c"=>0, "d"=>0}, {"a"=>2, "b"=>0, "c"=>0, "d"=>2}, # {"a"=>2, "b"=>0, "c"=>1, "d"=>1}, {"a"=>2, "b"=>0, "c"=>2, "d"=>0}, # {"a"=>2, "b"=>1, "c"=>0, "d"=>1}, {"a"=>2, "b"=>1, "c"=>1, "d"=>0}, # {"a"=>2, "b"=>2, "c"=>0, "d"=>0}, {"a"=>3, "b"=>0, "c"=>0, "d"=>1}, # {"a"=>3, "b"=>0, "c"=>1, "d"=>0}, {"a"=>3, "b"=>1, "c"=>0, "d"=>0}, # {"a"=>4, "b"=>0, "c"=>0, "d"=>0}] 
+5
source share

All Articles