A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
12
Task/Modular-inverse/0DESCRIPTION
Normal file
12
Task/Modular-inverse/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
From [http://en.wikipedia.org/wiki/Modular_multiplicative_inverse Wikipedia]:
|
||||
|
||||
:In [[wp:modular arithmetic|modular arithmetic]], the '''modular multiplicative inverse''' of an [[integer]] ''a'' [[wp:modular arithmetic|modulo]] ''m'' is an integer ''x'' such that
|
||||
|
||||
::<math>a^{-1} \equiv x \pmod{m}.</math>
|
||||
|
||||
Or in other words, such that:
|
||||
:<math>\exists k \in\mathbf{Z},\qquad a\, x = 1 + k\,m</math>
|
||||
|
||||
It can be shown that such an inverse exists if and only if a and m are [[wp:coprime|coprime]], but we will ignore this for this task.
|
||||
|
||||
Either by implementing the algorithm, by using a dedicated library or by using a builtin function in your language, compute the modular inverse of 42 modulo 2017.
|
||||
42
Task/Modular-inverse/Ada/modular-inverse.ada
Normal file
42
Task/Modular-inverse/Ada/modular-inverse.ada
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
with Ada.Text_IO;
|
||||
|
||||
procedure Mod_Inv is
|
||||
|
||||
procedure X_GCD(A, B: in Natural; D, X, Y: out Integer) is
|
||||
-- the Extended Euclidean Algorithm
|
||||
-- finds (D, X, Y) with D = GCD(A, B) = A*X + B*Y
|
||||
R: Natural := A mod B;
|
||||
begin
|
||||
if R=0 then
|
||||
D := B;
|
||||
X := 0;
|
||||
Y := 1;
|
||||
else
|
||||
X_GCD(B, R, D, Y, X);
|
||||
Y := Y - (A/B)*X;
|
||||
end if;
|
||||
end X_GCD;
|
||||
|
||||
function Inverse(A, M: Integer) return Integer is
|
||||
-- computes the multiplicative inverse of A mod M, using X_GCD
|
||||
Result, GCD, Dummy: Integer;
|
||||
begin
|
||||
X_GCD(A, M, GCD, Result, Dummy);
|
||||
if GCD /= 1 then -- inverse does not exist!
|
||||
raise Constraint_Error with
|
||||
"GCD (" & Integer'Image(A) & "," & Integer'Image(M) & " ) =" &
|
||||
Integer'Image(GCD) & " /= 1";
|
||||
else -- make sure Result is in {0, ..., M-1}
|
||||
if Result < 0 then
|
||||
return Result+M;
|
||||
else
|
||||
return Result;
|
||||
end if;
|
||||
end if;
|
||||
end Inverse;
|
||||
|
||||
begin
|
||||
Ada.Text_IO.Put_Line(Natural'Image(Inverse(42, 2017)));
|
||||
-- Ada.Text_IO.Put_Line(Natural'Image(Inverse(154, 3311)));
|
||||
-- The above would raise CONSTRAINT_ERROR : GCD ( 154, 3311 ) = 77 /= 1
|
||||
end Mod_Inv;
|
||||
20
Task/Modular-inverse/C/modular-inverse.c
Normal file
20
Task/Modular-inverse/C/modular-inverse.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int mul_inv(int a, int b)
|
||||
{
|
||||
int b0 = b, t, q;
|
||||
int x0 = 0, x1 = 1;
|
||||
if (b == 1) return 1;
|
||||
while (a > 1) {
|
||||
q = a / b;
|
||||
t = b, b = a % b, a = t;
|
||||
t = x0, x0 = x1 - q * x0, x1 = t;
|
||||
}
|
||||
if (x1 < 0) x1 += b0;
|
||||
return x1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("%d\n", mul_inv(42, 2017));
|
||||
return 0;
|
||||
}
|
||||
23
Task/Modular-inverse/D/modular-inverse.d
Normal file
23
Task/Modular-inverse/D/modular-inverse.d
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
T modInverse(T)(T a, T b) pure nothrow {
|
||||
if (b == 1)
|
||||
return 1;
|
||||
T b0 = b,
|
||||
x0 = 0,
|
||||
x1 = 1;
|
||||
|
||||
while (a > 1) {
|
||||
immutable q = a / b;
|
||||
auto t = b;
|
||||
b = a % b;
|
||||
a = t;
|
||||
t = x0;
|
||||
x0 = x1 - q * x0;
|
||||
x1 = t;
|
||||
}
|
||||
return (x1 < 0) ? (x1 + b0) : x1;
|
||||
}
|
||||
|
||||
void main() {
|
||||
import std.stdio;
|
||||
writeln(modInverse(42, 2017));
|
||||
}
|
||||
13
Task/Modular-inverse/Go/modular-inverse.go
Normal file
13
Task/Modular-inverse/Go/modular-inverse.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := big.NewInt(42)
|
||||
m := big.NewInt(2017)
|
||||
k := new(big.Int).ModInverse(a, m)
|
||||
fmt.Println(k)
|
||||
}
|
||||
16
Task/Modular-inverse/Haskell/modular-inverse.hs
Normal file
16
Task/Modular-inverse/Haskell/modular-inverse.hs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- Extended Euclidean algorithm. Given non-negative a and b, return x, y and g
|
||||
-- such that ax + by = g, where g = gcd(a,b). Note that x or y may be negative.
|
||||
gcdExt a 0 = (1, 0, a)
|
||||
gcdExt a b = let (q, r) = a `quotRem` b
|
||||
(s, t, g) = gcdExt b r
|
||||
in (t, s - q * t, g)
|
||||
|
||||
-- Given a and m, return Just x such that ax = 1 mod m. If there is no such x
|
||||
-- return Nothing.
|
||||
modInv a m = let (i, _, g) = gcdExt a m
|
||||
in if g == 1 then Just (mkPos i) else Nothing
|
||||
where mkPos x = if x < 0 then x + m else x
|
||||
|
||||
main = do
|
||||
print $ 2 `modInv` 4
|
||||
print $ 42 `modInv` 2017
|
||||
16
Task/Modular-inverse/Icon/modular-inverse.icon
Normal file
16
Task/Modular-inverse/Icon/modular-inverse.icon
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
procedure main(args)
|
||||
a := integer(args[1]) | 42
|
||||
b := integer(args[2]) | 2017
|
||||
write(mul_inv(a,b))
|
||||
end
|
||||
|
||||
procedure mul_inv(a,b)
|
||||
if b == 1 then return 1
|
||||
(b0 := b, x0 := 0, x1 := 1)
|
||||
while a > 1 do {
|
||||
q := a/b
|
||||
(t := b, b := a%b, a := t)
|
||||
(t := x0, x0 := x1-q*x0, x1 := t)
|
||||
}
|
||||
return if (x1 > 0) then x1 else x1+b0
|
||||
end
|
||||
1
Task/Modular-inverse/J/modular-inverse-1.j
Normal file
1
Task/Modular-inverse/J/modular-inverse-1.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
modInv =: dyad def 'x y&|@^ <: 5 p: y'"0
|
||||
2
Task/Modular-inverse/J/modular-inverse-2.j
Normal file
2
Task/Modular-inverse/J/modular-inverse-2.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
42 modInv 2017
|
||||
1969
|
||||
1
Task/Modular-inverse/Java/modular-inverse.java
Normal file
1
Task/Modular-inverse/Java/modular-inverse.java
Normal file
|
|
@ -0,0 +1 @@
|
|||
System.out.println(BigInteger.valueOf(42).modInverse(BigInteger.valueOf(2017)));
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
modInv[a_, m_] :=
|
||||
Block[{x,k}, x /. FindInstance[a x == 1 + k m, {x, k}, Integers]]
|
||||
2
Task/Modular-inverse/Perl/modular-inverse.pl
Normal file
2
Task/Modular-inverse/Perl/modular-inverse.pl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
use Math::ModInt qw(mod);
|
||||
print mod(42, 2017)->inverse
|
||||
18
Task/Modular-inverse/Python/modular-inverse.py
Normal file
18
Task/Modular-inverse/Python/modular-inverse.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
>>> def extended_gcd(aa, bb):
|
||||
lastremainder, remainder = abs(aa), abs(bb)
|
||||
x, lastx, y, lasty = 0, 1, 1, 0
|
||||
while remainder:
|
||||
lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
|
||||
x, lastx = lastx - quotient*x, x
|
||||
y, lasty = lasty - quotient*y, y
|
||||
return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1)
|
||||
|
||||
>>> def modinv(a, m):
|
||||
g, x, y = extended_gcd(a, m)
|
||||
if g != 1:
|
||||
raise ValueError
|
||||
return x % m
|
||||
|
||||
>>> modinv(42, 2017)
|
||||
1969
|
||||
>>>
|
||||
13
Task/Modular-inverse/REXX/modular-inverse.rexx
Normal file
13
Task/Modular-inverse/REXX/modular-inverse.rexx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*REXX program calcuates the modular inverse of an integer X modulo Y.*/
|
||||
parse arg x y . /*get two integers from the C.L. */
|
||||
say 'modular inverse of ' x " by " y ' ───► ' modInv(x,y)
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────MODINV subroutine───────────────────*/
|
||||
modInv: parse arg a,b 1 ob; ox=0; $=1
|
||||
|
||||
if b \= 1 then do while a>1
|
||||
parse value a/b a//b b ox with q b a t
|
||||
ox=$-q*ox; $=trunc(t)
|
||||
end /*while a>1*/
|
||||
if $<0 then $=$+ob
|
||||
return $
|
||||
17
Task/Modular-inverse/Tcl/modular-inverse-1.tcl
Normal file
17
Task/Modular-inverse/Tcl/modular-inverse-1.tcl
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
proc gcdExt {a b} {
|
||||
if {$b == 0} {
|
||||
return [list 1 0 $a]
|
||||
}
|
||||
set q [expr {$a / $b}]
|
||||
set r [expr {$a % $b}]
|
||||
lassign [gcdExt $b $r] s t g
|
||||
return [list $t [expr {$s - $q*$t}] $g]
|
||||
}
|
||||
proc modInv {a m} {
|
||||
lassign [gcdExt $a $m] i -> g
|
||||
if {$g != 1} {
|
||||
return -code error "no inverse exists of $a %! $m"
|
||||
}
|
||||
while {$i < 0} {incr i $m}
|
||||
return $i
|
||||
}
|
||||
4
Task/Modular-inverse/Tcl/modular-inverse-2.tcl
Normal file
4
Task/Modular-inverse/Tcl/modular-inverse-2.tcl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
puts "42 %! 2017 = [modInv 42 2017]"
|
||||
catch {
|
||||
puts "2 %! 4 = [modInv 2 4]"
|
||||
} msg; puts $msg
|
||||
Loading…
Add table
Add a link
Reference in a new issue