Here ya go....
# Provides the cross-product of two or more Enumerables.
# This is the class-level method. The instance method
# calls on this.
···
On Jan 30, 11:07 am, "diam" <d...@ensta.fr> wrote:
> understood. actually i have a VERY fast implementation already that
> was written by Michael Neuman. to be so fast it's very ugly though 
> want to see?
Yes please,
The API and the efficiency are both important for a potential standard
library,
(so the name should be carefully choosen !)
-- Maurice
#
# Enumerable.cross([1,2], [4], ["apple", "banana"])
# #=> [[1, 4, "apple"], [1, 4, "banana"], [2, 4, "apple"], [2,
4, "banana"]]
#
# Enumerable.cross([1,2], [3,4])
# #=> [[1, 3], [1, 4], [2, 3], [2, 4]]
#
#--
# TODO Make a more efficient version just for Array (?)
#++
def cartesian_product(*enums, &block)
raise if enums.empty?
gens = enums.map{|e| Generator.new(e)}
return if gens.any? {|g| g.end?}
sz = gens.size
res =
tuple = Array.new(sz)
loop do
# fill tuple
(0 ... sz).each { |i|
tuple[i] = gens[i].current
}
if block.nil?
res << tuple.dup
else
block.call(tuple.dup)
end
# step forward
gens[-1].next
(sz-1).downto(0) do |i|
if gens[i].end?
if i > 0
gens[i].rewind
gens[i-1].next
else
return res
end
end
end
end #loop
end
alias :cart, :cartesian_product
end
# The instance level version of <tt>Enumerable::cartesian_product</
.
#
# a =
# [1,2].cart([4,5]){|elem| a << elem }
# a #=> [[1, 4],[1, 5],[2, 4],[2, 5]]
#
#--
# TODO Make a more efficient version just for Array (?)
#++
def cart(*enums, &block)
Enumerable.cart(self, *enums, &block)
end
alias :cart, :cartesian_product
end