すべての組み合わせについて配列を n 個に分割する(Ruby)
Array#divide(n) です。遊びで作ってみました。
配列を n 個に分割する、すべての組み合わせをブロックに渡します。ブロックが与えられなければ Enumerator を返します。
[*2..6].divide(3) {|i| p i} #=> #[[2], [3], [4, 5, 6]] #[[2], [3, 4], [5, 6]] #[[2], [3, 4, 5], [6]] #[[2, 3], [4], [5, 6]] #[[2, 3], [4, 5], [6]] #[[2, 3, 4], [5], [6]] p "Ruby".chars.divide(3).with_object([]) {|i, h| h << i.map(&:join)} #=>[["R", "u", "by"], ["R", "ub", "y"], ["Ru", "b", "y"]]
あんまり使いみちは思いつかないのですが(笑)。
コード。
divide.rb
class Array def divide(n) if !n.class.ancestors.include?(Integer) or !n.between?(1, size) raise ArgumentError, "can not devide into #{n}." end e = Enumerator.new do |y| [*0...size - 1].combination(n - 1) do |ar| ar.sort! take_num = [] ([-1] + ar + [size - 1]).each_cons(2) {|i, j| take_num << j - i} result = [] tmp = self take_num.each do |i| result << tmp.take(i) tmp = tmp.drop(i) end y << result end end block_given? ? loop {yield(e.next)} : e end end