Skip to content

Instantly share code, notes, and snippets.

@grondilu
Created December 3, 2012 01:17
Show Gist options
  • Save grondilu/4192002 to your computer and use it in GitHub Desktop.
Save grondilu/4192002 to your computer and use it in GitHub Desktop.
modular integer Perl6 module
class Modular does Real {
has ($.n, $.modulo);
multi method new($n, :$modulo where * > 1) {
self.new: :n($n % $modulo), :$modulo
}
method Bridge { $.n % $.modulo }
multi method gist { "{self.Bridge} 「mod $.modulo」" }
method succ { self.Bridge.succ % $.modulo }
multi method Inverse {
my ($c, $d, $uc, $vc, $ud, $vd) = ($.n, $.modulo, 1, 0, 0, 1);
my $q;
while $c != 0 {
($q, $c, $d) = ($d div $c, $d % $c, $c);
($uc, $vc, $ud, $vd) = ($ud - $q*$uc, $vd - $q*$vc, $uc, $vc);
}
return self.new: $ud < 0 ?? $ud + $.modulo !! $ud, :$.modulo;
}
}
multi prefix:<->(Modular $a) { Modular.new: -$a.Bridge, :modulo($a.modulo) }
multi infix:<->(Modular $a, Modular $b where $a.modulo ~~ $b.modulo) {
Modular.new: $a.Bridge - $b.Bridge, :modulo($a.modulo)
}
multi infix:<+>(Modular $a, Modular $b where $a.modulo ~~ $b.modulo) {
Modular.new: $a.Bridge + $b.Bridge, :modulo($a.modulo)
}
multi infix:<*>(Modular $a, Modular $b where $a.modulo ~~ $b.modulo) {
Modular.new: $a.Bridge * $b.Bridge, :modulo($a.modulo)
}
multi infix:</>(Modular $a, Modular $b where $a.modulo ~~ $b.modulo) {
Modular.new: $a.Bridge * $b.Inverse.Bridge, :modulo($a.modulo)
}
my $modulo = 10;
say Modular.new(5, :$modulo) + Modular.new(6, :$modulo);
# vim: ft=perl6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment