Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

All possible distributions for an array, from a number

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

If I write:

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

I'd like it to return some form of

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

If I pass in

some_method(%w(a b c), 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 hard, so thanks in advance if you answer this question!

like image 745
clapp Avatar asked Sep 26 '16 05:09

clapp


People also ask

Is is possible to make all elements in the array equal?

Explanation: There is no way you can make all elements equal.

How do you find the probability of an array?

The probability of can be found out using the below formula: Probability = total number of K present / size of array. First, count the number of K's and then the probability will be the number of K's divided by N i.e. count / N.

How do you find multiples of a number in an array?

Simple Approach is to traverse over every value of 'k' in whole array and count total multiples by checking modulus of every element of array i.e., for every element of i (0 < i < n), check whether arr[i] % k == 0 or not. If it's perfectly divisible of k, then increment count.


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(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}]

Updated the answer based on tip by @seph

like image 146
Wand Maker Avatar answered Oct 20 '22 13:10

Wand Maker


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}] 
like image 32
Cary Swoveland Avatar answered Oct 20 '22 12:10

Cary Swoveland