This documentation is automatically generated by online-judge-tools/verification-helper
require "spec" require "../../src/tuple/each_product" describe Tuple do it "#product_each(&block)" do result = [] of {Int32, Int32, Int64} {1..2, [3, 4], {5i64, 6i64}}.each_product do |i, j, k| i.should be_a Int32 j.should be_a Int32 k.should be_a Int64 result << {i, j, k} end result.should eq [ {1, 3, 5}, {1, 3, 6}, {1, 4, 5}, {1, 4, 6}, {2, 3, 5}, {2, 3, 6}, {2, 4, 5}, {2, 4, 6}, ] end it "#product_each" do {1..2, 3...5}.each_product.to_a.should eq [ {1, 3}, {1, 4}, {2, 3}, {2, 4}, ] typeof({1i32..2u32, 3i64...5u64}.each_product).should be < Iterator({Int32, Int64}) end end
require "spec" # require "../../src/tuple/each_product" struct Tuple def each_product(&block) : Nil {% begin %} {% for i in 0...@type.size %} self[{{i}}].each do |i{{i}}| {% end %} yield({% for i in 0...@type.size %} i{{i}}, {% end %}) {% for i in 0...@type.size %} end {% end %} {% end %} end private class ProductIterator(T, Begin, End) include Iterator(Begin) def initialize(@n : T) @index = {% begin %} { {% for i in 0...T.size %} @n[{{i}}].begin, {% end %} } {% end %}.as(Begin) @end = {% begin %} { {% for i in 0...T.size %} @n[{{i}}].exclusive? ? @n[{{i}}].end.pred : @n[{{i}}].end, {% end %} } {% end %}.as(End) @first = true end def next if @first @first = false return @index end {% begin %} {% type = @type.type_vars[0] size = type.size %} {% for i in 1..size %} if @index[{{size - i}}] < @end[{{size - i}}] @index = { {% for j in 0...size %} {% if j < size - i %} @index[{{j}}], {% elsif j == size - i %} @index[{{j}}] + 1, {% else %} @n[{{j}}].begin, {% end %} {% end %} } return @index end {% end %} stop {% end %} end end def each_product {% for type in T %} {% raise "Can't product for not Range" unless type < Range %} {% raise "Can't product for open Range" if type.type_vars[0].nilable? %} {% raise "Can't product for open Range" if type.type_vars[1].nilable? %} {% end %} ProductIterator(self, typeof({% begin %} { {% for i in 0...@type.size %} self[{{i}}].begin,{% end %} } {% end %}), typeof({% begin %} { {% for i in 0...@type.size %} self[{{i}}].end, {% end %} } {% end %})).new(self) end end describe Tuple do it "#product_each(&block)" do result = [] of {Int32, Int32, Int64} {1..2, [3, 4], {5i64, 6i64}}.each_product do |i, j, k| i.should be_a Int32 j.should be_a Int32 k.should be_a Int64 result << {i, j, k} end result.should eq [ {1, 3, 5}, {1, 3, 6}, {1, 4, 5}, {1, 4, 6}, {2, 3, 5}, {2, 3, 6}, {2, 4, 5}, {2, 4, 6}, ] end it "#product_each" do {1..2, 3...5}.each_product.to_a.should eq [ {1, 3}, {1, 4}, {2, 3}, {2, 4}, ] typeof({1i32..2u32, 3i64...5u64}.each_product).should be < Iterator({Int32, Int64}) end end