This documentation is automatically generated by online-judge-tools/verification-helper

:warning: spec/tuple/times_spec.cr

Depends on

Code

require "spec"
require "../../src/tuple/times"

describe Tuple do
  it "#times(&block)" do
    result = [] of {Int32, Int32, Int32}
    {1, 2, 3}.times do |i, j, k|
      result << {i, j, k}
    end
    result.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]

    result = [] of {Int32, Int32, Int64}
    {1, 2, 3i64}.times do |i, j, k|
      result << {i, j, k}
    end
    result.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]
  end

  it "#times" do
    {1, 2, 3}.times.to_a.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]

    {1, 2u8, 3i64}.times.to_a.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]
    {1, 2u8, 3i64}.times.each do |i, j, k|
      i.should be_a Int32
      j.should be_a UInt8
      k.should be_a Int64
    end
  end
end
require "spec"

# require "../../src/tuple/times"
struct Tuple
  def times(&block) : Nil
    {% begin %}
      {% for i in 0...@type.size %}
        self[{{i}}].times 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 TimesIterator(T)
    include Iterator(T)

    def initialize(@n : T)
      tuple = {% begin %} { {% for type in T %} {{type}}.zero, {% end %} } {% end %}
      @index = tuple.as(T)
      @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}}] < @n[{{size - i}}] - 1
            @index = {
              {% for j in 0...size %}
                {% if j < size - i %}
                  @index[{{j}}],
                {% elsif j == size - i %}
                  @index[{{j}}] + 1,
                {% else %}
                  {{type[j]}}.zero,
                {% end %}
              {% end %}
            }
            return @index
          end
        {% end %}
        stop
      {% end %}
    end
  end

  def times
    TimesIterator(self).new(self)
  end
end

describe Tuple do
  it "#times(&block)" do
    result = [] of {Int32, Int32, Int32}
    {1, 2, 3}.times do |i, j, k|
      result << {i, j, k}
    end
    result.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]

    result = [] of {Int32, Int32, Int64}
    {1, 2, 3i64}.times do |i, j, k|
      result << {i, j, k}
    end
    result.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]
  end

  it "#times" do
    {1, 2, 3}.times.to_a.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]

    {1, 2u8, 3i64}.times.to_a.should eq [
      {0, 0, 0}, {0, 0, 1}, {0, 0, 2},
      {0, 1, 0}, {0, 1, 1}, {0, 1, 2},
    ]
    {1, 2u8, 3i64}.times.each do |i, j, k|
      i.should be_a Int32
      j.should be_a UInt8
      k.should be_a Int64
    end
  end
end
Back to top page