55 lines
1.3 KiB
Plaintext
55 lines
1.3 KiB
Plaintext
// Semi-abstract though we can define a 'pow' method in terms of the other operations.
|
|
class Ring {
|
|
+(other) {}
|
|
*(other) {}
|
|
one {}
|
|
|
|
pow(p) {
|
|
if (p.type != Num || !p.isInteger || p < 0) {
|
|
Fiber.abort("Argument must be non-negative integer.")
|
|
}
|
|
var pwr = one
|
|
while (p > 0) {
|
|
pwr = pwr * this
|
|
p = p - 1
|
|
}
|
|
return pwr
|
|
}
|
|
}
|
|
|
|
class ModInt is Ring {
|
|
construct new(value, modulo) {
|
|
_value = value
|
|
_modulo = modulo
|
|
}
|
|
|
|
value { _value }
|
|
modulo { _modulo }
|
|
|
|
+(other) {
|
|
if (other.type != ModInt || _modulo != other.modulo) {
|
|
Fiber.abort("Argument must be a ModInt with the same modulus.")
|
|
}
|
|
return ModInt.new((_value + other.value) % _modulo, _modulo)
|
|
}
|
|
|
|
*(other) {
|
|
if (other.type != ModInt || _modulo != other.modulo) {
|
|
Fiber.abort("Argument must be a ModInt with the same modulus.")
|
|
}
|
|
return ModInt.new((_value * other.value) % _modulo, _modulo)
|
|
}
|
|
|
|
one { ModInt.new(1, _modulo) }
|
|
|
|
toString { "Modint(%(_value), %(_modulo))" }
|
|
}
|
|
|
|
var f = Fn.new { |x|
|
|
if (!(x is Ring)) Fiber.abort("Argument must be a Ring.")
|
|
return x.pow(100) + x + x.one
|
|
}
|
|
|
|
var x = ModInt.new(10, 13)
|
|
System.print("x^100 + x + 1 for x = %(x) is %(f.call(x))")
|