を使用することをお勧めしArray#product
ます。
[:a, :b].product [4,5]
これにより、必要な出力が得られます。
irb(main):001:0> [:a, :b].product [4,5]
=> [[:a, 4], [:a, 5], [:b, 4], [:b, 5]]
irb(main):002:0>
順列の怠惰なジェネレーターが必要な場合は、以前にこのようなものを作成しました。ただし、計算する順列が多数ある場合は、時間がかかる可能性があることを警告します。このファイルの最初の40〜45行から必要なものを取得できるはずです(このファイルはとにかく実験でした)。
秘訣は、Ruby 1.9.2を使用して列挙子を作成し、配列の配列を処理することです。したがって、最初に配列を無限に循環する列挙子を作成し、配列の配列列挙子で最初の出力セットを追跡し、それが2回目にヒットしたときにループを終了します。これが、そのようなループを終了する方法を理解する唯一の方法でした。
def infinite_iterator(array)
Enumerator.new do |result|
loop do
array.cycle { |item| result << item }
end
end
end
def cartesian_iterator(data)
Enumerator.new do |result|
first = data.map { |p| p.next }
result << first
i = 1
parts = first.dup
loop do
parts[2-i] = data[2-i].next
break if parts == first
result << parts.join
i = ((i + 1) % parts.size)
end
end
end
array = [ infinite_iterator([:a,:b]), infinite_iterator([4,5]) ]
generator = cartesian_iterator(array)
generator.each { |a| p a }