September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,11 +0,0 @@
package Mod_Inv is
procedure X_GCD(A, B: in Natural; D, X, Y: out Integer);
-- the Extended Euclidean Algorithm
-- finds (D, X, Y) with D = GCD(A, B) = A*X + B*Y
function Inverse(A, M: Integer) return Integer;
-- computes the multiplicative inverse Inv_A of A mod M, using X_GCD
-- raises Constraint_Error if Inv_A does not exist
end Mod_Inv;

View file

@ -1,36 +0,0 @@
package body 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;
end Mod_Inv;

View file

@ -1,9 +0,0 @@
with Ada.Text_IO; with Mod_Inv; use Mod_Inv, Ada.text_IO;
procedure Mod_Inv_Test is
begin
-- Put_Line(Natural'Image(Inverse(154, 3311)));
-- The above would raise CONSTRAINT_ERROR : GCD ( 154, 3311 ) = 77 /= 1
Put_Line(Natural'Image(Inverse(42, 2017)));
end Mod_Inv_Test;

View file

@ -0,0 +1,18 @@
with Ada.Text_IO;use Ada.Text_IO;
procedure modular_inverse is
-- inv_mod calculates the inverse of a mod n. We should have n>0 and, at the end, the contract is a*Result=1 mod n
-- If this is false then we raise an exception (don't forget the -gnata option when you compile
function inv_mod (a : Integer; n : Positive) return Integer with post=> (a * inv_mod'Result) mod n = 1 is
-- To calculate the inverse we do as if we would calculate the GCD with the Euclid extended algorithm
-- (but we just keep the coefficient on a)
function inverse (a, b, u, v : Integer) return Integer is (if b=0 then u else inverse (b, a mod b, v, u-(v*a)/b));
begin
return inverse (a, n, 1, 0);
end inv_mod;
begin
-- This will output -48 (which is correct)
Put_Line (inv_mod (42,2017)'img);
-- The further line will raise an exception since the GCD will not be 1
Put_Line (inv_mod (42,77)'img);
exception when others => Put_Line ("The inverse doesn't exist.");
end bitmap;

View file

@ -0,0 +1,9 @@
// version 1.0.6
import java.math.BigInteger
fun main(args: Array<String>) {
val a = BigInteger.valueOf(42)
val m = BigInteger.valueOf(2017)
println(a.modInverse(m))
}

View file

@ -0,0 +1,5 @@
fcn gcdExt(a,b){
if(b==0) return(1,0,a);
q,r:=a.divr(b); s,t,g:=gcdExt(b,r); return(t,s-q*t,g);
}
fcn modInv(a,m){i,_,g:=gcdExt(a,m); if(g==1) {if(i<0)i+m} else Void}