重複を許可する配列の組み合わせを返す
Array#combination だと、重複は許可されないので自作
仕様
- サイズn の重複を許可した組み合わせを返す
- 同一値の重複は許可するけど、順序が異なるだけの組み合わせは返さない
- [1,1,2] があったら、[1,2,1]や、[2,1,1] は返さない
コード
class Array def duplicate_combination(max_depth) b([], 0, max_depth).map {|obj| obj.sort }.uniq end def b(buf, depth, max_depth, result = []) depth = depth + 1 self.each do |k| new_buf = (buf + [k]).flatten if max_depth > depth b(new_buf, depth, max_depth, result) else result << new_buf end end result end private :b end
使い方
p [1,2,3,4,5].duplicate_combination(3) # [[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 1, 5], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 3], [1, 3, 4], [1, 3, 5], [1, 4, 4], [1, 4, 5], [1, 5, 5], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 2, 5], [2, 3, 3], [2, 3, 4], [2, 3, 5], [2, 4, 4], [2, 4, 5], [2, 5, 5], [3, 3, 3], [3, 3, 4], [3, 3, 5], [3, 4, 4], [3, 4, 5], [3, 5, 5], [4, 4, 4], [4, 4, 5], [4, 5, 5], [5, 5, 5]]
そんなかんじ