数组的所有可能分布,来自一个数字
All possible distributions for an array, from a number
我不太清楚如何表达这一点,所以我只是举个例子。
如果我写:
some_method(["a", "b"], 3)
我想要return某种形式的
[{"a" => 0, "b" => 3},
{"a" => 1, "b" => 2},
{"a" => 2, "b" => 1},
{"a" => 3, "b" => 0}]
如果我通过
some_method(%w(a b c), 2)
预期的 return 值应该是
[{"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}]
很难描述这个问题,如果您回答这个问题,请提前致谢!
这是一种方法:
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}]
根据@seph 的提示更新了答案
此方法使用递归。
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}]
我不太清楚如何表达这一点,所以我只是举个例子。
如果我写:
some_method(["a", "b"], 3)
我想要return某种形式的
[{"a" => 0, "b" => 3},
{"a" => 1, "b" => 2},
{"a" => 2, "b" => 1},
{"a" => 3, "b" => 0}]
如果我通过
some_method(%w(a b c), 2)
预期的 return 值应该是
[{"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}]
很难描述这个问题,如果您回答这个问题,请提前致谢!
这是一种方法:
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}]
根据@seph 的提示更新了答案
此方法使用递归。
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}]