diff --git a/DIRECTORY.md b/DIRECTORY.md index 3594d0f..7abafc1 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -24,6 +24,7 @@ * [Directedgraph](https://github.com/TheAlgorithms/Haskell/blob/master/src/Graph/DirectedGraph.hs) * [Haskellalgorithms](https://github.com/TheAlgorithms/Haskell/blob/master/src/HaskellAlgorithms.hs) * Maths + * [Euclidianalgorithm](https://github.com/TheAlgorithms/Haskell/blob/master/src/Maths/EuclidianAlgorithm.hs) * [Factorial](https://github.com/TheAlgorithms/Haskell/blob/master/src/Maths/Factorial.hs) * [Fibonacci](https://github.com/TheAlgorithms/Haskell/blob/master/src/Maths/Fibonacci.hs) * [Graphdist](https://github.com/TheAlgorithms/Haskell/blob/master/src/Maths/GraphDist.hs) diff --git a/src/Maths/EuclidianAlgorithm.hs b/src/Maths/EuclidianAlgorithm.hs new file mode 100644 index 0000000..a56201a --- /dev/null +++ b/src/Maths/EuclidianAlgorithm.hs @@ -0,0 +1,19 @@ +module Maths.EuclidianAlgorithm where + +-- Computes the Greatest Common Divisor (GCD) of two numbers using the Euclidian Algorithm +ea :: (Integral a) => a -> a -> a +ea x 0 = x +ea x y = gcd y (x `mod` y) + +-- Computes the modular multiplicative inverse of a modulo m using the Extended Euclidian Algorithm +-- https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Computing_multiplicative_inverses_in_modular_structures +eea :: (Integral a) => a -> a -> Maybe a +eea a m = let (r, t) = eea' 0 m 1 a + in if r > 1 then Nothing else if t < 0 then Just (t + m) else Just t + +-- The looping part of the algorithm, implemented recursively +eea' :: (Integral a) => a -> a -> a -> a -> (a, a) +eea' t0 r0 t1 r1 + | r1 /= 0 = let q = r0 `div` r1 + in eea' t1 r1 (t0 - q * t1) (r0 - q * r1) + | otherwise = (r0, t0) \ No newline at end of file