2016-09-26 13 views
8

Tôi không hoàn toàn chắc chắn làm thế nào để nói rõ điều này, vì vậy tôi sẽ chỉ đưa ra các ví dụ.Tất cả các bản phân phối có thể cho một mảng, từ một số

Nếu tôi viết:

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

tôi muốn nó trở lại một số hình thức

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

Nếu tôi vượt qua trong

some_method(%w(a b c), 2) 

Giá trị lợi nhuận kỳ vọng nên

[{"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}] 

Mô tả điều này thật khó, vì vậy cảm ơn trước nếu bạn trả lời câu hỏi này!

+1

@smarx Tôi thậm chí không chắc chắn nên bắt đầu từ đâu, vì vậy chưa có gì. – clap

+2

Vâng, hãy quay lại khi bạn có gì đó! Stack Overflow không phải là một nơi tuyệt vời để đặt câu hỏi như thế này. Xem http://stackoverflow.com/help/how-to-ask. – smarx

+1

Có logic nào cho đầu ra dự kiến ​​không? Ví dụ, tại sao đầu ra đầu tiên không có '{" a "=> 1," b "=> 3}' –

Trả lời

7

Dưới đây là một cách để làm điều này:

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

cập nhật câu trả lời dựa trên mũi bằng @seph

+2

Rất tốt. Tôi nghĩ nếu bạn sử dụng 'repeat_permutation' bạn đang ở đó. – seph

+0

Cảm ơn @seph - Tôi không biết về phương pháp đó. Dường như nó đang hoạt động tốt. –

+0

@CarySwoveland - Tôi đôi khi giống như tuyên bố trở lại rõ ràng - nó làm cho tôi thoải mái khi đọc mã. Tôi đồng ý rằng tùy chọn của nó. –

5

Phương pháp này sử dụng đệ quy.

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}] 
Các vấn đề liên quan