Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
35
Task/Modular-inverse/ALGOL-68/modular-inverse.alg
Normal file
35
Task/Modular-inverse/ALGOL-68/modular-inverse.alg
Normal 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
|
||||
43
Task/Modular-inverse/Batch-File/modular-inverse.bat
Normal file
43
Task/Modular-inverse/Batch-File/modular-inverse.bat
Normal 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
|
||||
16
Task/Modular-inverse/Bracmat/modular-inverse.bracmat
Normal file
16
Task/Modular-inverse/Bracmat/modular-inverse.bracmat
Normal 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))
|
||||
};
|
||||
10
Task/Modular-inverse/Forth/modular-inverse.fth
Normal file
10
Task/Modular-inverse/Forth/modular-inverse.fth
Normal 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 ;
|
||||
16
Task/Modular-inverse/PHP/modular-inverse.php
Normal file
16
Task/Modular-inverse/PHP/modular-inverse.php
Normal 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));
|
||||
?>
|
||||
24
Task/Modular-inverse/Pascal/modular-inverse.pascal
Normal file
24
Task/Modular-inverse/Pascal/modular-inverse.pascal
Normal 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;
|
||||
23
Task/Modular-inverse/PowerShell/modular-inverse.psh
Normal file
23
Task/Modular-inverse/PowerShell/modular-inverse.psh
Normal 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
|
||||
|
|
@ -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 $
|
||||
|
|
|
|||
15
Task/Modular-inverse/Scala/modular-inverse.scala
Normal file
15
Task/Modular-inverse/Scala/modular-inverse.scala
Normal 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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue