2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -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]], &nbsp; the '''modular multiplicative inverse''' of an [[integer]] &nbsp; <big> ''a'' </big> &nbsp; [[wp:modular arithmetic|modulo]] &nbsp; <big> ''m'' </big> &nbsp; is an integer &nbsp; <big> ''x'' </big> &nbsp; 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 &nbsp; if and only if &nbsp; <big> ''a'' </big> &nbsp; and &nbsp; <big> ''m'' </big> &nbsp; are [[wp:coprime|coprime]], &nbsp; 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, &nbsp; compute the modular inverse of &nbsp; 42 modulo 2017.

View 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;
}

View 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))

View 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)

View 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;
}
}
}

View file

@ -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 $

View file

@ -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

View 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))
}

View 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))