Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -5,7 +5,7 @@ From [http://en.wikipedia.org/wiki/Modular_multiplicative_inverse Wikipedia]:
::<math>a\,x \equiv 1 \pmod{m}.</math>
Or in other words, such that:
:<math>\exists k \in\mathbf{Z},\qquad a\, x = 1 + k\,m</math>
:<math>\exists k \in\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.

View file

@ -0,0 +1,35 @@
BEGIN
PROC modular inverse = (INT a, m) INT :
BEGIN
PROC extended gcd = (INT x, y) []INT :
CO
Algol 68 allows us to return three INTs in several ways. A [3]INT
is used here but it could just as well be a STRUCT.
CO
BEGIN
INT v := 1, a := 1, u := 0, b := 0, g := x, w := y;
WHILE w>0
DO
INT q := g % w, t := a - q * u;
a := u; u := t;
t := b - q * v;
b := v; v := t;
t := g - q * w;
g := w; w := t
OD;
a PLUSAB (a < 0 | u | 0);
(a, b, g)
END;
[] INT egcd = extended gcd (a, m);
(egcd[3] > 1 | 0 | egcd[1] MOD m)
END;
printf (($"42 ^ -1 (mod 2017) = ", g(0)$, modular inverse (42, 2017)))
CO
Note that if ϕ(m) is known, then a^-1 = a^(ϕ(m)-1) mod m which
allows an alternative implementation in terms of modular
exponentiation but, in general, this requires the factorization of
m. If m is prime the factorization is trivial and ϕ(m) = m-1.
2017 is prime which may, or may not, be ironic within the context
of the Rosetta Code conditions.
CO
END

View file

@ -0,0 +1,43 @@
@echo off
setlocal enabledelayedexpansion
%== Calls the "function" ==%
call :ModInv 42 2017 result
echo !result!
call :ModInv 40 1 result
echo !result!
call :ModInv 52 -217 result
echo !result!
call :ModInv -486 217 result
echo !result!
call :ModInv 40 2018 result
echo !result!
pause>nul
exit /b 0
%== The "function" ==%
:ModInv
set a=%1
set b=%2
if !b! lss 0 (set /a b=-b)
if !a! lss 0 (set /a a=b - ^(-a %% b^))
set t=0&set nt=1&set r=!b!&set /a nr=a%%b
:while_loop
if !nr! neq 0 (
set /a q=r/nr
set /a tmp=nt
set /a nt=t - ^(q*nt^)
set /a t=tmp
set /a tmp=nr
set /a nr=r - ^(q*nr^)
set /a r=tmp
goto while_loop
)
if !r! gtr 1 (set %3=-1&goto :EOF)
if !t! lss 0 set /a t+=b
set %3=!t!
goto :EOF

View file

@ -0,0 +1,16 @@
( ( mod-inv
= a b b0 x0 x1 q
. !arg:(?a.?b)
& ( !b:1
| (!b.0.1):(?b0.?x0.?x1)
& whl
' ( !a:>1
& div$(!a.!b):?q
& (!b.mod$(!a.!b)):(?a.?b)
& (!x1+-1*!q*!x0.!x0):(?x0.?x1)
)
& (!x:>0|!x1+!b0)
)
)
& out$(mod-inv$(42.2017))
};

View file

@ -0,0 +1,10 @@
: invmod { a m | v b c -- inv }
m to v
1 to c
0 to b
begin a
while v a / >r
c b s>d c s>d r@ 1 m*/ d- d>s to c to b
a v s>d a s>d r> 1 m*/ d- d>s to a to v
repeat b m mod dup to b 0<
if m b + else b then ;

View file

@ -0,0 +1,16 @@
<?php
function invmod($a,$n){
if ($n < 0) $n = -$n;
if ($a < 0) $a = $n - (-$a % $n);
$t = 0; $nt = 1; $r = $n; $nr = $a % $n;
while ($nr != 0) {
$quot= intval($r/$nr);
$tmp = $nt; $nt = $t - $quot*$nt; $t = $tmp;
$tmp = $nr; $nr = $r - $quot*$nr; $r = $tmp;
}
if ($r > 1) return -1;
if ($t < 0) $t += $n;
return $t;
}
printf("%d\n", invmod(42, 2017));
?>

View file

@ -0,0 +1,24 @@
// increments e step times until bal is greater than t
// repeats until bal = 1 (mod = 1) and returns count
// bal will not be greater than t + e
function modInv(e, t : integer) : integer;
var
d : integer;
bal, count, step : integer;
begin
d := 0;
if e < t then
begin
count := 1;
bal := e;
repeat
step := ((t-bal) DIV e)+1;
bal := bal + step * e;
count := count + step;
bal := bal - t;
until bal = 1;
d := count;
end;
modInv := d;
end;

View file

@ -0,0 +1,23 @@
function invmod($a,$n){
if ([int]$n -lt 0) {$n = -$n}
if ([int]$a -lt 0) {$a = $n - ((-$a) % $n)}
$t = 0
$nt = 1
$r = $n
$nr = $a % $n
while ($nr -ne 0) {
$q = [Math]::truncate($r/$nr)
$tmp = $nt
$nt = $t - $q*$nt
$t = $tmp
$tmp = $nr
$nr = $r - $q*$nr
$r = $tmp
}
if ($r -gt 1) {return -1}
if ($t -lt 0) {$t += $n}
return $t
}
invmod 42 2017

View file

@ -1,13 +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 $
/*REXX program calculates the modular inverse of an integer X modulo Y. */
parse arg x y . /*obtain two integers from the C.L. */
say 'modular inverse of ' x " by " y ' ' modInv(x,y)
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
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 $

View file

@ -0,0 +1,15 @@
def gcdExt(u: Int, v: Int): (Int, Int, Int) = {
@tailrec
def aux(a: Int, b: Int, x: Int, y: Int, x1: Int, x2: Int, y1: Int, y2: Int): (Int, Int, Int) = {
if(b == 0) (x, y, a) else {
val (q, r) = (a / b, a % b)
aux(b, r, x2 - q * x1, y2 - q * y1, x, x1, y, y1)
}
}
aux(u, v, 1, 0, 0, 1, 1, 0)
}
def modInv(a: Int, m: Int): Option[Int] = {
val (i, j, g) = gcdExt(a, m)
if (g == 1) Option(if (i < 0) i + m else i) else Option.empty
}