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

:warning: spec/math/mint_spec.cr

Depends on

Code

require "spec"
require "../../src/math/mint"
require "../../atcoder/src/Math"
private MOD1 = 1000000007i64
private MOD2 =  998244353i64

private macro check_binary_operator(type, op)
  %mod = {{type}}.mod
  0i64.step(to: %mod, by: %mod // 1000).each do |x|
    0i64.step(to: %mod, by: %mod // 999).each do |y|
      m = {{type}}.new(x) {{op.id}} {{type}}.new(y)
      expect = (x {{op.id}} y) % %mod
      m.should eq expect
    end
  end
end

private macro check_method(type, method)
  %mod = {{type}}.mod
  0i64.step(to: %mod, by: %mod // 1000000).each do |x|
    {{type}}.new(x).{{method}}.should eq x.{{method}}
  end
end

private macro check_method_mod(type, method)
  %mod = {{type}}.mod
  0i64.step(to: %mod, by: %mod // 1000000).each do |x|
    {{type}}.new(x).{{method}}.should eq x.{{method}} % %mod
  end
end

describe "Mint" do
  it ".[]" do
    Mint[0, 1, 2, 3, MOD1, MOD1 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint))
    Mint2[0, 1, 2, 3, MOD2, MOD2 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint2))
    Mint[0, 1, MOD1, MOD1 + 1, MOD1 * 2].map(&.value).should eq [0, 1, 0, 1, 0]
  end

  it ".mod" do
    Mint.mod.should eq MOD1
    ModInt(42).mod.should eq 42
  end

  it ".zero" do
    Mint.zero.should eq 0
  end

  it "#initialize" do
    Mint.new.should eq 0
    Mint.new(Int64::MIN).should eq Int64::MIN % MOD1
    Mint.new(0).should eq 0
    Mint.new(42).should eq 42
    Mint.new(42i64).should eq 42
    Mint.new(42i8).should eq 42
    Mint.new(MOD1).should eq 0
    Mint.new(MOD1 + 1).should eq 1
    Mint.new(MOD1 * MOD1).should eq 0
    Mint.new(Int64::MAX).should eq Int64::MAX % MOD1
  end

  it "#+" do
    (+Mint.new).should eq 0
    (+Mint.new(12)).should eq 12
  end

  it "#-" do
    (-Mint.new).should eq 0
    (-Mint.new(12)).should eq MOD1 - 12
  end

  it "#+(other)" do
    a, b = Mint.new(1), Mint.new(-1)
    (a + a).should eq 2
    (a + 3).should eq 4
    (a + 3i64).should eq 4
    (a + 3i8).should eq 4
    (a + MOD1).should eq 1
    (a + MOD1 * 2).should eq 1
    (b + b).should eq MOD1 - 2
    check_binary_operator(Mint, :+)
    check_binary_operator(Mint2, :+)
  end

  it "#-(other)" do
    a, b = Mint.new(3), Mint.new(-1)
    (a - Mint.new(4)).should eq MOD1 - 1
    (a - 3).should eq 0
    (a - 3i64).should eq 0
    (a - 3i8).should eq 0
    (a - 4).should eq MOD1 - 1
    (a - MOD1).should eq 3
    (Mint.zero - b).should eq 1
    check_binary_operator(Mint, :-)
    check_binary_operator(Mint2, :-)
  end

  it "#*(other)" do
    a, b = Mint.new(3), Mint.new(-1)
    (a * 3).should eq 9
    (a * a).should eq 9
    (a * MOD1).should eq 0
    (b * MOD1).should eq 0
    (b * b).should eq 1
    (b * Int64::MAX).should eq MOD1.pred * (Int64::MAX % MOD1) % MOD1
    check_binary_operator(Mint, :*)
    check_binary_operator(Mint2, :*)
  end

  it "#/(other)" do
    a = Mint.new(3)
    (a / 1).should eq 3
    (a / 2).should eq MOD1 // 2 + 2
    (a / 3).should eq 1

    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000) do |x|
        0i64.step(by: %mod, to: %mod // 999) do |y|
          next unless y.gcd(%mod) == 1
          z = {{type}}.new(x) / y
          (z * y).should eq x
        end
      end
    {% end %}

    expect_raises(DivisionByZeroError) { a / 0 }
    expect_raises(DivisionByZeroError) { a / 0i8 }
    expect_raises(DivisionByZeroError) { a / MOD1 }
    expect_raises(DivisionByZeroError) { a / Mint.zero }
  end

  it "#//(other)" do
    a = Mint.new(3)
    (a // 1).should eq 3
    (a // 2).should eq MOD1 // 2 + 2
    (a // 3).should eq 1

    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000) do |x|
        0i64.step(by: %mod, to: %mod // 999) do |y|
          next unless y.gcd(%mod) == 1
          z = {{type}}.new(x) // y
          (z * y).should eq x
        end
      end
    {% end %}

    expect_raises(DivisionByZeroError) { a // 0 }
    expect_raises(DivisionByZeroError) { a // 0i8 }
    expect_raises(DivisionByZeroError) { a // MOD1 }
    expect_raises(DivisionByZeroError) { a // Mint.zero }
  end

  it "#**(other)" do
    a = Mint.new(3)
    (a ** 0).should eq 1
    (a ** 1).should eq 3
    (a ** 2).should eq 9
    (a ** 20).should eq 486784380
    (a ** (10i64**18)).should eq 246336683
    (a.pred ** (10i64**18)).should eq 719476260

    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000) do |x|
        0i64.step(by: Int64::MAX, to: Int64::MAX // 1000) do |e|
          m = {{type}}.new(x) ** e
          expect = AtCoder::Math.pow_mod(x, e, %mod)
          m.should eq expect
        end
      end
    {% end %}
  end

  it "#inv" do
    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000000) do |x|
        next unless x.gcd(%mod) == 1
        ({{type}}.new(x).inv * x).should eq 1
      end
    {% end %}
  end

  it "#==(other)" do
    a = Mint.new(3)
    (a == a).should be_true
    (a == 3).should be_true
    (a == MOD1 + 3).should be_false
    (a == Mint.new(MOD1 + 3)).should be_true
  end

  it "#!=(other)" do
    a = Mint.new(3)
    (a != a).should be_false
    (a != MOD1 + 3).should be_true
    (a != Mint.new(MOD1 + 3)).should be_false
  end

  it "#succ" do
    Mint.new(0).succ.should eq 1
    Mint.new(3).succ.should eq 4
    Mint.new(MOD1).succ.should eq 1
    Mint.new(-1).succ.should eq 0
    check_method_mod(Mint, succ)
    check_method_mod(Mint2, succ)
  end

  it "#pred" do
    Mint.new(0).pred.should eq MOD1 - 1
    Mint.new(3).pred.should eq 2
    Mint.new(MOD1).pred.should eq MOD1 - 1
    Mint.new(-1).pred.should eq MOD1 - 2
    check_method_mod(Mint, pred)
    check_method_mod(Mint2, pred)
  end

  it "#abs" do
    Mint.new(0).abs.should eq 0
    Mint.new(3).abs.should eq 3
    Mint.new(MOD1).abs.should eq 0
    Mint.new(-1).abs.should eq MOD1 - 1
    check_method_mod(Mint, abs)
    check_method_mod(Mint2, abs)
  end

  it "#value" do
    Mint.new(0).value.should eq 0
    Mint.new(3).value.should eq 3
    Mint.new(MOD1).value.should eq 0
    Mint.new(-1).value.should eq MOD1 - 1
  end

  it "#to_s" do
    Mint.new(0).to_s.should eq "0"
    Mint.new(3).to_s.should eq "3"
    Mint.new(MOD1).to_s.should eq "0"
    Mint.new(-1).to_s.should eq MOD1.pred.to_s
    check_method(Mint, to_s)
    check_method(Mint2, to_s)
  end

  it "#inspect" do
    Mint.new(0).inspect.should eq "0"
    Mint.new(3).inspect.should eq "3"
    Mint.new(MOD1).inspect.should eq "0"
    Mint.new(-1).inspect.should eq (MOD1 - 1).inspect
    check_method(Mint, inspect)
    check_method(Mint2, inspect)
  end
end

describe Int do
  it "#to_m" do
    (-1).to_m(Mint).should eq MOD1 - 1
    (-1i8).to_m(Mint).should eq MOD1 - 1
    0.to_m(Mint).should eq 0
    1i64.to_m(Mint).should eq 1
    MOD1.to_m(Mint).should eq 0

    (-1).to_m(Mint2).should eq MOD2 - 1
  end
end

describe String do
  it "#to_m" do
    "-1".to_m(Mint).should eq MOD1 - 1
    "0".to_m(Mint).should eq 0
    "1".to_m(Mint).should eq 1
    MOD1.pred.to_s.to_m(Mint).should eq MOD1 - 1
    MOD1.to_s.to_m(Mint).should eq 0
    "-1".to_m(Mint2).should eq MOD2 - 1
  end
end
require "spec"

# require "../../src/math/mint"
struct ModInt(MOD)
  def self.mod
    MOD
  end

  def self.zero
    new
  end

  def self.raw(value : Int64)
    result = new
    result.value = value
    result
  end

  macro [](*nums)
    Array({{@type}}).build({{nums.size}}) do |buffer|
      {% for num, i in nums %}
        buffer[{{i}}] = {{@type}}.new({{num}})
      {% end %}
      {{nums.size}}
    end
  end

  getter value : Int64

  private macro check_mod
    {% if MOD.is_a?(NumberLiteral) %}
      {% raise "can't instantiate ModInt(MOD) with MOD = #{MOD} (MOD must be positive)" unless MOD >= 1 %}
      {% raise "can't instantiate ModInt(MOD) with MOD = #{MOD.kind} (MOD must be Int64)" unless MOD.kind == :i64 %}
    {% else %}
      {% raise "can't instantiate ModInt(MOD) with MOD = #{MOD.class_name.id} (MOD must be an integer)" %}
    {% end %}
  end

  def initialize
    check_mod
    @value = 0i64
  end

  def initialize(value)
    check_mod
    @value = value.to_i64 % MOD
  end

  def initialize(m : ModInt(MOD2)) forall MOD2
    {% raise "Can't create ModInt(#{MOD}) from ModInt(#{MOD2})" if MOD != MOD2 %}
    check_mod
    @value = m.value
  end

  protected def value=(value : Int64)
    @value = value
  end

  def self.scan(scanner, io : IO) : self
    new scanner.i64(io)
  end

  def ==(m : ModInt(MOD2)) forall MOD2
    {% raise "Can't compare ModInt(#{MOD}) and ModInt(#{MOD2})" if MOD != MOD2 %}
    value == m.value
  end

  def ==(m : Int)
    value == m
  end

  def + : self
    self
  end

  def - : self
    self.class.raw(value != 0 ? MOD &- value : 0i64)
  end

  def +(v)
    self + self.class.new(v)
  end

  def +(m : self)
    x = value &+ m.value
    x &-= MOD if x >= MOD
    self.class.raw(x)
  end

  def -(v)
    self - self.class.new(v)
  end

  def -(m : self)
    x = value &- m.value
    x &+= MOD if x < 0
    self.class.raw(x)
  end

  def *(v)
    self * self.class.new(v)
  end

  def *(m : self)
    self.class.new(value &* m.value)
  end

  def /(v)
    self / self.class.new(v)
  end

  def /(m : self)
    raise DivisionByZeroError.new if m.value == 0
    a, b, u, v = m.value, MOD, 1i64, 0i64
    while b != 0
      t = a // b
      a &-= t &* b
      a, b = b, a
      u &-= t &* v
      u, v = v, u
    end
    self.class.new(value &* u)
  end

  def //(v)
    self / v
  end

  def **(exponent : Int)
    t, res = self, self.class.raw(1i64)
    while exponent > 0
      res *= t if exponent & 1 == 1
      t *= t
      exponent >>= 1
    end
    res
  end

  {% for op in %w[< <= > >=] %}
    def {{op.id}}(other)
      raise NotImplementedError.new({{op}})
    end
  {% end %}

  def inv
    self.class.raw(1) // self
  end

  def succ
    self.class.raw(value != MOD &- 1 ? value &+ 1 : 0i64)
  end

  def pred
    self.class.raw(value != 0 ? value &- 1 : MOD &- 1)
  end

  def abs
    self
  end

  def abs2
    self * self
  end

  def to_i64 : Int64
    value
  end

  def to_s(io : IO) : Nil
    value.to_s(io)
  end

  def inspect(io : IO) : Nil
    value.inspect(io)
  end
end

struct Int
  def to_m(type : M.class) forall M
    M.new(self)
  end
end

class String
  def to_m(type : M.class) forall M
    M.new(self)
  end
end

alias Mint = ModInt(1000000007i64)
alias Mint2 = ModInt(998244353i64)

# require "../../atcoder/src/Math"
# ac-library.cr by hakatashi https://github.com/google/ac-library.cr
#
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

module AtCoder
  # Implements [ACL's Math library](https://atcoder.github.io/ac-library/master/document_en/math.html)
  module Math
    def self.extended_gcd(a, b)
      last_remainder, remainder = a.abs, b.abs
      x, last_x, y, last_y = 0_i64, 1_i64, 1_i64, 0_i64
      while remainder != 0
        new_last_remainder = remainder
        quotient, remainder = last_remainder.divmod(remainder)
        last_remainder = new_last_remainder
        x, last_x = last_x - quotient * x, x
        y, last_y = last_y - quotient * y, y
      end

      return last_remainder, last_x * (a < 0 ? -1 : 1)
    end

    # Implements atcoder::inv_mod(value, modulo).
    def self.inv_mod(value, modulo)
      gcd, inv = extended_gcd(value, modulo)
      if gcd != 1
        raise ArgumentError.new("#{value} and #{modulo} are not coprime")
      end
      inv % modulo
    end

    # Simplified AtCoder::Math.pow_mod with support of Int64
    def self.pow_mod(base, exponent, modulo)
      if exponent == 0
        return base.class.zero + 1
      end
      if base == 0
        return base
      end
      b = exponent > 0 ? base : inv_mod(base, modulo)
      e = exponent.abs
      ret = 1_i64
      while e > 0
        if e % 2 == 1
          ret = mul_mod(ret, b, modulo)
        end
        b = mul_mod(b, b, modulo)
        e //= 2
      end
      ret
    end

    # Caluculates a * b % mod without overflow detection
    @[AlwaysInline]
    def self.mul_mod(a : Int64, b : Int64, mod : Int64)
      if mod < Int32::MAX
        return a * b % mod
      end

      # 31-bit width
      a_high = (a >> 32).to_u64
      # 32-bit width
      a_low = (a & 0xFFFFFFFF).to_u64
      # 31-bit width
      b_high = (b >> 32).to_u64
      # 32-bit width
      b_low = (b & 0xFFFFFFFF).to_u64

      # 31-bit + 32-bit + 1-bit = 64-bit
      c = a_high * b_low + b_high * a_low
      c_high = c >> 32
      c_low = c & 0xFFFFFFFF

      # 31-bit + 31-bit
      res_high = a_high * b_high + c_high
      # 32-bit + 32-bit
      res_low = a_low * b_low
      res_low_high = res_low >> 32
      res_low_low = res_low & 0xFFFFFFFF

      # Overflow
      if res_low_high + c_low >= 0x100000000
        res_high += 1
      end

      res_low = (((res_low_high + c_low) & 0xFFFFFFFF) << 32) | res_low_low

      (((res_high.to_i128 << 64) | res_low) % mod).to_i64
    end

    @[AlwaysInline]
    def self.mul_mod(a, b, mod)
      typeof(mod).new(a.to_i64 * b % mod)
    end

    # Implements atcoder::crt(remainders, modulos).
    def self.crt(remainders, modulos)
      raise ArgumentError.new unless remainders.size == modulos.size

      total_modulo = 1_i64
      answer = 0_i64

      remainders.zip(modulos).each do |(remainder, modulo)|
        gcd, p = extended_gcd(total_modulo, modulo)
        if (remainder - answer) % gcd != 0
          return 0_i64, 0_i64
        end
        tmp = (remainder - answer) // gcd * p % (modulo // gcd)
        answer += total_modulo * tmp
        total_modulo *= modulo // gcd
      end

      return answer % total_modulo, total_modulo
    end

    # Implements atcoder::floor_sum(n, m, a, b).
    def self.floor_sum(n, m, a, b)
      n, m, a, b = n.to_i64, m.to_i64, a.to_i64, b.to_i64
      res = 0_i64

      if a < 0
        a2 = a % m
        res -= n * (n - 1) // 2 * ((a2 - a) // m)
        a = a2
      end

      if b < 0
        b2 = b % m
        res -= n * ((b2 - b) // m)
        b = b2
      end

      res + floor_sum_unsigned(n, m, a, b)
    end

    private def self.floor_sum_unsigned(n, m, a, b)
      res = 0_i64

      loop do
        if a >= m
          res += n * (n - 1) // 2 * (a // m)
          a = a % m
        end

        if b >= m
          res += n * (b // m)
          b = b % m
        end

        y_max = a * n + b
        break if y_max < m

        n = y_max // m
        b = y_max % m
        m, a = a, m
      end

      res
    end
  end
end

private MOD1 = 1000000007i64
private MOD2 =  998244353i64

private macro check_binary_operator(type, op)
  %mod = {{type}}.mod
  0i64.step(to: %mod, by: %mod // 1000).each do |x|
    0i64.step(to: %mod, by: %mod // 999).each do |y|
      m = {{type}}.new(x) {{op.id}} {{type}}.new(y)
      expect = (x {{op.id}} y) % %mod
      m.should eq expect
    end
  end
end

private macro check_method(type, method)
  %mod = {{type}}.mod
  0i64.step(to: %mod, by: %mod // 1000000).each do |x|
    {{type}}.new(x).{{method}}.should eq x.{{method}}
  end
end

private macro check_method_mod(type, method)
  %mod = {{type}}.mod
  0i64.step(to: %mod, by: %mod // 1000000).each do |x|
    {{type}}.new(x).{{method}}.should eq x.{{method}} % %mod
  end
end

describe "Mint" do
  it ".[]" do
    Mint[0, 1, 2, 3, MOD1, MOD1 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint))
    Mint2[0, 1, 2, 3, MOD2, MOD2 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint2))
    Mint[0, 1, MOD1, MOD1 + 1, MOD1 * 2].map(&.value).should eq [0, 1, 0, 1, 0]
  end

  it ".mod" do
    Mint.mod.should eq MOD1
    ModInt(42).mod.should eq 42
  end

  it ".zero" do
    Mint.zero.should eq 0
  end

  it "#initialize" do
    Mint.new.should eq 0
    Mint.new(Int64::MIN).should eq Int64::MIN % MOD1
    Mint.new(0).should eq 0
    Mint.new(42).should eq 42
    Mint.new(42i64).should eq 42
    Mint.new(42i8).should eq 42
    Mint.new(MOD1).should eq 0
    Mint.new(MOD1 + 1).should eq 1
    Mint.new(MOD1 * MOD1).should eq 0
    Mint.new(Int64::MAX).should eq Int64::MAX % MOD1
  end

  it "#+" do
    (+Mint.new).should eq 0
    (+Mint.new(12)).should eq 12
  end

  it "#-" do
    (-Mint.new).should eq 0
    (-Mint.new(12)).should eq MOD1 - 12
  end

  it "#+(other)" do
    a, b = Mint.new(1), Mint.new(-1)
    (a + a).should eq 2
    (a + 3).should eq 4
    (a + 3i64).should eq 4
    (a + 3i8).should eq 4
    (a + MOD1).should eq 1
    (a + MOD1 * 2).should eq 1
    (b + b).should eq MOD1 - 2
    check_binary_operator(Mint, :+)
    check_binary_operator(Mint2, :+)
  end

  it "#-(other)" do
    a, b = Mint.new(3), Mint.new(-1)
    (a - Mint.new(4)).should eq MOD1 - 1
    (a - 3).should eq 0
    (a - 3i64).should eq 0
    (a - 3i8).should eq 0
    (a - 4).should eq MOD1 - 1
    (a - MOD1).should eq 3
    (Mint.zero - b).should eq 1
    check_binary_operator(Mint, :-)
    check_binary_operator(Mint2, :-)
  end

  it "#*(other)" do
    a, b = Mint.new(3), Mint.new(-1)
    (a * 3).should eq 9
    (a * a).should eq 9
    (a * MOD1).should eq 0
    (b * MOD1).should eq 0
    (b * b).should eq 1
    (b * Int64::MAX).should eq MOD1.pred * (Int64::MAX % MOD1) % MOD1
    check_binary_operator(Mint, :*)
    check_binary_operator(Mint2, :*)
  end

  it "#/(other)" do
    a = Mint.new(3)
    (a / 1).should eq 3
    (a / 2).should eq MOD1 // 2 + 2
    (a / 3).should eq 1

    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000) do |x|
        0i64.step(by: %mod, to: %mod // 999) do |y|
          next unless y.gcd(%mod) == 1
          z = {{type}}.new(x) / y
          (z * y).should eq x
        end
      end
    {% end %}

    expect_raises(DivisionByZeroError) { a / 0 }
    expect_raises(DivisionByZeroError) { a / 0i8 }
    expect_raises(DivisionByZeroError) { a / MOD1 }
    expect_raises(DivisionByZeroError) { a / Mint.zero }
  end

  it "#//(other)" do
    a = Mint.new(3)
    (a // 1).should eq 3
    (a // 2).should eq MOD1 // 2 + 2
    (a // 3).should eq 1

    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000) do |x|
        0i64.step(by: %mod, to: %mod // 999) do |y|
          next unless y.gcd(%mod) == 1
          z = {{type}}.new(x) // y
          (z * y).should eq x
        end
      end
    {% end %}

    expect_raises(DivisionByZeroError) { a // 0 }
    expect_raises(DivisionByZeroError) { a // 0i8 }
    expect_raises(DivisionByZeroError) { a // MOD1 }
    expect_raises(DivisionByZeroError) { a // Mint.zero }
  end

  it "#**(other)" do
    a = Mint.new(3)
    (a ** 0).should eq 1
    (a ** 1).should eq 3
    (a ** 2).should eq 9
    (a ** 20).should eq 486784380
    (a ** (10i64**18)).should eq 246336683
    (a.pred ** (10i64**18)).should eq 719476260

    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000) do |x|
        0i64.step(by: Int64::MAX, to: Int64::MAX // 1000) do |e|
          m = {{type}}.new(x) ** e
          expect = AtCoder::Math.pow_mod(x, e, %mod)
          m.should eq expect
        end
      end
    {% end %}
  end

  it "#inv" do
    {% for type in [Mint, Mint2] %}
      %mod = {{type}}.mod
      0i64.step(by: %mod, to: %mod // 1000000) do |x|
        next unless x.gcd(%mod) == 1
        ({{type}}.new(x).inv * x).should eq 1
      end
    {% end %}
  end

  it "#==(other)" do
    a = Mint.new(3)
    (a == a).should be_true
    (a == 3).should be_true
    (a == MOD1 + 3).should be_false
    (a == Mint.new(MOD1 + 3)).should be_true
  end

  it "#!=(other)" do
    a = Mint.new(3)
    (a != a).should be_false
    (a != MOD1 + 3).should be_true
    (a != Mint.new(MOD1 + 3)).should be_false
  end

  it "#succ" do
    Mint.new(0).succ.should eq 1
    Mint.new(3).succ.should eq 4
    Mint.new(MOD1).succ.should eq 1
    Mint.new(-1).succ.should eq 0
    check_method_mod(Mint, succ)
    check_method_mod(Mint2, succ)
  end

  it "#pred" do
    Mint.new(0).pred.should eq MOD1 - 1
    Mint.new(3).pred.should eq 2
    Mint.new(MOD1).pred.should eq MOD1 - 1
    Mint.new(-1).pred.should eq MOD1 - 2
    check_method_mod(Mint, pred)
    check_method_mod(Mint2, pred)
  end

  it "#abs" do
    Mint.new(0).abs.should eq 0
    Mint.new(3).abs.should eq 3
    Mint.new(MOD1).abs.should eq 0
    Mint.new(-1).abs.should eq MOD1 - 1
    check_method_mod(Mint, abs)
    check_method_mod(Mint2, abs)
  end

  it "#value" do
    Mint.new(0).value.should eq 0
    Mint.new(3).value.should eq 3
    Mint.new(MOD1).value.should eq 0
    Mint.new(-1).value.should eq MOD1 - 1
  end

  it "#to_s" do
    Mint.new(0).to_s.should eq "0"
    Mint.new(3).to_s.should eq "3"
    Mint.new(MOD1).to_s.should eq "0"
    Mint.new(-1).to_s.should eq MOD1.pred.to_s
    check_method(Mint, to_s)
    check_method(Mint2, to_s)
  end

  it "#inspect" do
    Mint.new(0).inspect.should eq "0"
    Mint.new(3).inspect.should eq "3"
    Mint.new(MOD1).inspect.should eq "0"
    Mint.new(-1).inspect.should eq (MOD1 - 1).inspect
    check_method(Mint, inspect)
    check_method(Mint2, inspect)
  end
end

describe Int do
  it "#to_m" do
    (-1).to_m(Mint).should eq MOD1 - 1
    (-1i8).to_m(Mint).should eq MOD1 - 1
    0.to_m(Mint).should eq 0
    1i64.to_m(Mint).should eq 1
    MOD1.to_m(Mint).should eq 0

    (-1).to_m(Mint2).should eq MOD2 - 1
  end
end

describe String do
  it "#to_m" do
    "-1".to_m(Mint).should eq MOD1 - 1
    "0".to_m(Mint).should eq 0
    "1".to_m(Mint).should eq 1
    MOD1.pred.to_s.to_m(Mint).should eq MOD1 - 1
    MOD1.to_s.to_m(Mint).should eq 0
    "-1".to_m(Mint2).should eq MOD2 - 1
  end
end
Back to top page