September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
1
Task/Modular-inverse/00META.yaml
Normal file
1
Task/Modular-inverse/00META.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
--- {}
|
||||
|
|
@ -16,4 +16,4 @@ begin
|
|||
-- 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;
|
||||
end modular_inverse;
|
||||
|
|
|
|||
18
Task/Modular-inverse/Forth/modular-inverse-2.fth
Normal file
18
Task/Modular-inverse/Forth/modular-inverse-2.fth
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
: modinv ( a m - inv)
|
||||
dup 1- \ a m (m != 1)?
|
||||
if \ a m
|
||||
tuck 1 0 \ m0 a m 1 0
|
||||
begin \ m0 a m inv x0
|
||||
2>r over 1 > \ m0 a m (a > 1)? R: inv x0
|
||||
while \ m0 a m R: inv x0
|
||||
tuck /mod \ m0 m (a mod m) (a/m) R: inv x0
|
||||
r> tuck * \ m0 a' m' x0 (a/m)*x0 R: inv
|
||||
r> swap - \ m0 a' m' x0 (inv-q) R:
|
||||
repeat \ m0 a' m' inv' x0'
|
||||
2drop \ m0 R: inv x0
|
||||
2r> drop \ m0 inv R:
|
||||
dup 0< \ m0 inv (inv < 0)?
|
||||
if over + then \ m0 (inv + m0)
|
||||
then \ x inv'
|
||||
nip \ inv
|
||||
;
|
||||
|
|
@ -1,16 +1,25 @@
|
|||
-- 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.
|
||||
-- Given a and m, return Just x such that ax = 1 mod m.
|
||||
-- If there is no such x return Nothing.
|
||||
modInv :: Int -> Int -> Maybe Int
|
||||
modInv a m
|
||||
| 1 == g = Just (mkPos i)
|
||||
| otherwise = Nothing
|
||||
where
|
||||
(i, _, g) = gcdExt a m
|
||||
mkPos x
|
||||
| x < 0 = x + m
|
||||
| otherwise = x
|
||||
|
||||
-- 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 :: Int -> Int -> (Int, Int, Int)
|
||||
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)
|
||||
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
|
||||
main :: IO ()
|
||||
main = mapM_ print [2 `modInv` 4, 42 `modInv` 2017]
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
proc mulInv(a0, b0): int =
|
||||
proc modInv(a0, b0: int): int =
|
||||
var (a, b, x0) = (a0, b0, 0)
|
||||
result = 1
|
||||
if b == 1: return
|
||||
while a > 1:
|
||||
let q = a div b
|
||||
result = result - (a div b) * x0
|
||||
a = a mod b
|
||||
swap a, b
|
||||
result = result - q * x0
|
||||
swap x0, result
|
||||
if result < 0: result += b0
|
||||
|
||||
echo mulInv(42, 2017)
|
||||
echo modInv(42, 2017)
|
||||
|
|
|
|||
20
Task/Modular-inverse/Phix/modular-inverse.phix
Normal file
20
Task/Modular-inverse/Phix/modular-inverse.phix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
function mul_inv(integer a, n)
|
||||
if n<0 then n = -n end if
|
||||
if a<0 then a = n - mod(-a,n) end if
|
||||
integer t = 0, nt = 1,
|
||||
r = n, nr = a;
|
||||
while nr!=0 do
|
||||
integer q = floor(r/nr)
|
||||
{t, nt} = {nt, t-q*nt}
|
||||
{r, nr} = {nr, r-q*nr}
|
||||
end while
|
||||
if r>1 then return "a is not invertible" end if
|
||||
if t<0 then t += n end if
|
||||
return t
|
||||
end function
|
||||
|
||||
?mul_inv(42,2017)
|
||||
?mul_inv(40, 1)
|
||||
?mul_inv(52, -217) /* Pari semantics for negative modulus */
|
||||
?mul_inv(-486, 217)
|
||||
?mul_inv(40, 2018)
|
||||
91
Task/Modular-inverse/Python/modular-inverse-2.py
Normal file
91
Task/Modular-inverse/Python/modular-inverse-2.py
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
from functools import (reduce)
|
||||
from itertools import (chain)
|
||||
|
||||
|
||||
# modInv :: Int -> Int -> Maybe Int
|
||||
def modInv(a):
|
||||
return lambda m: (
|
||||
lambda ig=gcdExt(a)(m): (
|
||||
lambda i=ig[0]: (
|
||||
Just(i + m if 0 > i else i) if 1 == ig[2] else (
|
||||
Nothing()
|
||||
)
|
||||
)
|
||||
)()
|
||||
)()
|
||||
|
||||
|
||||
# gcdExt :: Int -> Int -> (Int, Int, Int)
|
||||
def gcdExt(x):
|
||||
def go(a, b):
|
||||
if 0 == b:
|
||||
return (1, 0, a)
|
||||
else:
|
||||
(q, r) = divmod(a, b)
|
||||
(s, t, g) = go(b, r)
|
||||
return (t, s - q * t, g)
|
||||
return lambda y: go(x, y)
|
||||
|
||||
|
||||
# TEST ---------------------------------------------------
|
||||
|
||||
# Numbers between 2010 and 2015 which do yield modular inverses for 42:
|
||||
|
||||
# main :: IO ()
|
||||
def main():
|
||||
print (
|
||||
mapMaybe(
|
||||
lambda y: bindMay(modInv(42)(y))(
|
||||
lambda mInv: Just((y, mInv))
|
||||
)
|
||||
)(
|
||||
enumFromTo(2010)(2025)
|
||||
)
|
||||
)
|
||||
|
||||
# -> [(2011, 814), (2015, 48), (2017, 1969), (2021, 1203)]
|
||||
|
||||
|
||||
# GENERIC ABSTRACTIONS ------------------------------------
|
||||
|
||||
|
||||
# enumFromTo :: Int -> Int -> [Int]
|
||||
def enumFromTo(m):
|
||||
return lambda n: list(range(m, 1 + n))
|
||||
|
||||
|
||||
# bindMay (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
|
||||
def bindMay(m):
|
||||
return lambda mf: (
|
||||
m if m.get('Nothing') else mf(m.get('Just'))
|
||||
)
|
||||
|
||||
|
||||
# Just :: a -> Maybe a
|
||||
def Just(x):
|
||||
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
|
||||
|
||||
|
||||
# mapMaybe :: (a -> Maybe b) -> [a] -> [b]
|
||||
def mapMaybe(mf):
|
||||
return lambda xs: reduce(
|
||||
lambda a, x: maybe(a)(lambda j: a + [j])(mf(x)),
|
||||
xs,
|
||||
[]
|
||||
)
|
||||
|
||||
|
||||
# maybe :: b -> (a -> b) -> Maybe a -> b
|
||||
def maybe(v):
|
||||
return lambda f: lambda m: v if m.get('Nothing') else (
|
||||
f(m.get('Just'))
|
||||
)
|
||||
|
||||
|
||||
# Nothing :: Maybe a
|
||||
def Nothing():
|
||||
return {'type': 'Maybe', 'Nothing': True}
|
||||
|
||||
|
||||
# MAIN ---
|
||||
main()
|
||||
12
Task/Modular-inverse/Ruby/modular-inverse-2.rb
Normal file
12
Task/Modular-inverse/Ruby/modular-inverse-2.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
def modinv(a, m) # compute a^-1 mod m if possible
|
||||
raise "NO INVERSE - #{a} and #{m} not coprime" unless a.gcd(m) == 1
|
||||
return m if m == 1
|
||||
m0, inv, x0 = m, 1, 0
|
||||
while a > 1
|
||||
inv -= (a / m) * x0
|
||||
a, m = m, a % m
|
||||
inv, x0 = x0, inv
|
||||
end
|
||||
inv += m0 if inv < 0
|
||||
inv
|
||||
end
|
||||
19
Task/Modular-inverse/Rust/modular-inverse-2.rust
Normal file
19
Task/Modular-inverse/Rust/modular-inverse-2.rust
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
fn modinv(a0: isize, m0: isize) -> isize {
|
||||
if m0 == 1 { return 1 }
|
||||
|
||||
let (mut a, mut m, mut x0, mut inv) = (a0, m0, 0, 1);
|
||||
|
||||
while a > 1 {
|
||||
inv -= (a / m) * x0;
|
||||
a = a % m;
|
||||
std::mem::swap(&mut a, &mut m);
|
||||
std::mem::swap(&mut x0, &mut inv);
|
||||
}
|
||||
|
||||
if inv < 0 { inv += m0 }
|
||||
inv
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", modinv(42, 2017))
|
||||
}
|
||||
31
Task/Modular-inverse/VBA/modular-inverse.vba
Normal file
31
Task/Modular-inverse/VBA/modular-inverse.vba
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
Private Function mul_inv(a As Long, n As Long) As Variant
|
||||
If n < 0 Then n = -n
|
||||
If a < 0 Then a = n - ((-a) Mod n)
|
||||
Dim t As Long: t = 0
|
||||
Dim nt As Long: nt = 1
|
||||
Dim r As Long: r = n
|
||||
Dim nr As Long: nr = a
|
||||
Dim q As Long
|
||||
Do While nr <> 0
|
||||
q = r \ nr
|
||||
tmp = t
|
||||
t = nt
|
||||
nt = tmp - q * nt
|
||||
tmp = r
|
||||
r = nr
|
||||
nr = tmp - q * nr
|
||||
Loop
|
||||
If r > 1 Then
|
||||
mul_inv = "a is not invertible"
|
||||
Else
|
||||
If t < 0 Then t = t + n
|
||||
mul_inv = t
|
||||
End If
|
||||
End Function
|
||||
Public Sub mi()
|
||||
Debug.Print mul_inv(42, 2017)
|
||||
Debug.Print mul_inv(40, 1)
|
||||
Debug.Print mul_inv(52, -217) '/* Pari semantics for negative modulus */
|
||||
Debug.Print mul_inv(-486, 217)
|
||||
Debug.Print mul_inv(40, 2018)
|
||||
End Sub
|
||||
Loading…
Add table
Add a link
Reference in a new issue