2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,14 +1,16 @@
|
|||
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
|
||||
In [[wp:modular arithmetic|modular arithmetic]], the '''modular multiplicative inverse''' of an [[integer]] <big> ''a'' </big> [[wp:modular arithmetic|modulo]] <big> ''m'' </big> is an integer <big> ''x'' </big> such that
|
||||
|
||||
::<math>a\,x \equiv 1 \pmod{m}.</math>
|
||||
|
||||
Or in other words, such that:
|
||||
:<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.
|
||||
::<math>\exists k \in\Z,\qquad a\, x = 1 + k\,m</math>
|
||||
|
||||
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.
|
||||
It can be shown that such an inverse exists if and only if <big> ''a'' </big> and <big> ''m'' </big> are [[wp:coprime|coprime]], but we will ignore this for this task.
|
||||
|
||||
|
||||
;Task:
|
||||
Either by implementing the algorithm, by using a dedicated library or by using a built-in function in
|
||||
your language, compute the modular inverse of 42 modulo 2017.
|
||||
|
|
|
|||
12
Task/Modular-inverse/C++/modular-inverse-2.cpp
Normal file
12
Task/Modular-inverse/C++/modular-inverse-2.cpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <iostream>
|
||||
|
||||
short ObtainMultiplicativeInverse(int a, int b, int s0 = 1, int s1 = 0)
|
||||
{
|
||||
return b==0? s0: ObtainMultiplicativeInverse(b, a%b, s1, s0 - s1*(a/b));
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::cout << ObtainMultiplicativeInverse(42, 2017) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
43
Task/Modular-inverse/Clojure/modular-inverse.clj
Normal file
43
Task/Modular-inverse/Clojure/modular-inverse.clj
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
(ns test-p.core
|
||||
(:require [clojure.math.numeric-tower :as math]))
|
||||
|
||||
(defn extended-gcd
|
||||
"The extended Euclidean algorithm--using Clojure code from RosettaCode for Extended Eucliean
|
||||
(see http://en.wikipedia.orwiki/Extended_Euclidean_algorithm)
|
||||
Returns a list containing the GCD and the Bézout coefficients
|
||||
corresponding to the inputs with the result: gcd followed by bezout coefficients "
|
||||
[a b]
|
||||
(cond (zero? a) [(math/abs b) 0 1]
|
||||
(zero? b) [(math/abs a) 1 0]
|
||||
:else (loop [s 0
|
||||
s0 1
|
||||
t 1
|
||||
t0 0
|
||||
r (math/abs b)
|
||||
r0 (math/abs a)]
|
||||
(if (zero? r)
|
||||
[r0 s0 t0]
|
||||
(let [q (quot r0 r)]
|
||||
(recur (- s0 (* q s)) s
|
||||
(- t0 (* q t)) t
|
||||
(- r0 (* q r)) r))))))
|
||||
|
||||
(defn mul_inv
|
||||
" Get inverse using extended gcd. Extended GCD returns
|
||||
gcd followed by bezout coefficients. We want the 1st coefficients
|
||||
(i.e. second of extend-gcd result). We compute mod base so result
|
||||
is between 0..(base-1) "
|
||||
[a b]
|
||||
(let [b (if (neg? b) (- b) b)
|
||||
a (if (neg? a) (- b (mod (- a) b)) a)
|
||||
egcd (extended-gcd a b)]
|
||||
(if (= (first egcd) 1)
|
||||
(mod (second egcd) b)
|
||||
(str "No inverse since gcd is: " (first egcd)))))
|
||||
|
||||
|
||||
(println (mul_inv 42 2017))
|
||||
(println (mul_inv 40 1))
|
||||
(println (mul_inv 52 -217))
|
||||
(println (mul_inv -486 217))
|
||||
(println (mul_inv 40 2018))
|
||||
21
Task/Modular-inverse/Elixir/modular-inverse.elixir
Normal file
21
Task/Modular-inverse/Elixir/modular-inverse.elixir
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
defmodule Modular do
|
||||
def extended_gcd(a, b) do
|
||||
{last_remainder, last_x} = extended_gcd(abs(a), abs(b), 1, 0, 0, 1)
|
||||
{last_remainder, last_x * (if a < 0, do: -1, else: 1)}
|
||||
end
|
||||
|
||||
defp extended_gcd(last_remainder, 0, last_x, _, _, _), do: {last_remainder, last_x}
|
||||
defp extended_gcd(last_remainder, remainder, last_x, x, last_y, y) do
|
||||
quotient = div(last_remainder, remainder)
|
||||
remainder2 = rem(last_remainder, remainder)
|
||||
extended_gcd(remainder, remainder2, x, last_x - quotient*x, y, last_y - quotient*y)
|
||||
end
|
||||
|
||||
def inverse(e, et) do
|
||||
{g, x} = extended_gcd(e, et)
|
||||
if g != 1, do: raise "The maths are broken!"
|
||||
rem(x+et, et)
|
||||
end
|
||||
end
|
||||
|
||||
IO.puts Modular.inverse(42,2017)
|
||||
8
Task/Modular-inverse/JavaScript/modular-inverse.js
Normal file
8
Task/Modular-inverse/JavaScript/modular-inverse.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
var modInverse = function(a, b) {
|
||||
a %= b;
|
||||
for (var x = 1; x < b; x++) {
|
||||
if ((a*x)%b == 1) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
/*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
|
||||
/*REXX program calculates and displays the modular inverse of an integer X modulo Y.*/
|
||||
parse arg x y . /*obtain two integers from the C.L. */
|
||||
if x=='' | x=="," then x= 42 /*Not specified? Then use the default.*/
|
||||
if y=='' | y=="," then y= 2017 /* " " " " " " */
|
||||
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; z=0 /*B & OB are obtained from the 2nd arg.*/
|
||||
$=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 b\=1 then do while a>1
|
||||
parse value a/b a//b b z with q b a t
|
||||
z=$ - q*z; $=trunc(t)
|
||||
end /*while*/
|
||||
if $<0 then $=$+ob
|
||||
return $
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ end
|
|||
def invmod(e, et)
|
||||
g, x = extended_gcd(e, et)
|
||||
if g != 1
|
||||
raise 'Teh maths are broken!'
|
||||
raise 'The maths are broken!'
|
||||
end
|
||||
x % et
|
||||
end
|
||||
|
|
|
|||
18
Task/Modular-inverse/Rust/modular-inverse.rust
Normal file
18
Task/Modular-inverse/Rust/modular-inverse.rust
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
fn mod_inv(a: isize, module: isize) -> isize {
|
||||
let mut mn = (module, a);
|
||||
let mut xy = (0, 1);
|
||||
|
||||
while mn.1 != 0 {
|
||||
xy = (xy.1, xy.0 - (mn.0 / mn.1) * xy.1);
|
||||
mn = (mn.1, mn.0 % mn.1);
|
||||
}
|
||||
|
||||
while xy.0 < 0 {
|
||||
xy.0 += module;
|
||||
}
|
||||
xy.0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", mod_inv(42, 2017))
|
||||
}
|
||||
1
Task/Modular-inverse/Scala/modular-inverse-2.scala
Normal file
1
Task/Modular-inverse/Scala/modular-inverse-2.scala
Normal file
|
|
@ -0,0 +1 @@
|
|||
def modInv(a: Int, m: Int, x:Int = 1, y:Int = 0) : Int = if (m == 0) x else modInv(m, a%m, y, x - y*(a/m))
|
||||
Loading…
Add table
Add a link
Reference in a new issue