require 'grid_search' class CartesianIterator include GridSearch def initialize(foo, bar) @lists = [] @tot_iter = 1 x(foo) x(bar) end def x(other) @lists << other.to_a.dup @tot_iter *= @lists[-1].size self end def each return false if @tot_iter < 1 elems = [] for list in @lists elems << list.restart_and_raw_next end yield *elems last_list_index = @lists.size-1 n = last_list_index loop do if elems[n] = @lists[n].raw_next yield *elems n = last_list_index next elsif n > 0 elems[n] = @lists[n].restart_and_raw_next n -= 1 else return true end end end def to_a array = [] self.each {|*element| array << element } array end end module Iterable def start @next_index = -1 true end alias :restart :start def next @next_index or restart raw_next end def raw_next self[@next_index += 1] end def restart_and_raw_next self[@next_index = 0] end end class Array include Iterable end