From 27c4a8063178db79f3979b4f58a5d005977e74d7 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Thu, 13 Apr 2017 20:51:47 -0700 Subject: [PATCH] Add gcd() and lcm() methods to Int --- types/src/number/math.rs | 66 ++++++++++++++++++++++++++++++++++++++++ types/src/number/mod.rs | 1 + 2 files changed, 67 insertions(+) create mode 100644 types/src/number/math.rs diff --git a/types/src/number/math.rs b/types/src/number/math.rs new file mode 100644 index 0000000..bf9aef2 --- /dev/null +++ b/types/src/number/math.rs @@ -0,0 +1,66 @@ +/* types/src/number/math.rs + * Eryn Wells + */ + +use number::Int; + +pub trait GCD { + /// Find the greatest common divisor of `self` and another number. + fn gcd(self, other: Self) -> Self; +} + +pub trait LCM { + /// Find the least common multiple of `self` and another number. + fn lcm(self, other: Self) -> Self; +} + +impl GCD for Int { + fn gcd(self, other: Int) -> Int { + let (mut a, mut b) = if self > other { + (self, other) + } else { + (other, self) + }; + + while b != 0 { + let r = a % b; + a = b; + b = r; + } + + a + } +} + +impl LCM for Int { + fn lcm(self, other: Int) -> Int { + if self == 0 && other == 0 { + 0 + } + else { + self * other / self.gcd(other) + } + } +} + +#[cfg(test)] +mod tests { + use super::{LCM, GCD}; + + #[test] + fn gcd_works() { + assert_eq!(0, 0.gcd(0)); + assert_eq!(10, 10.gcd(0)); + assert_eq!(10, 0.gcd(10)); + assert_eq!(10, 10.gcd(20)); + assert_eq!(44, 2024.gcd(748)); + } + + #[test] + fn lcm_works() { + assert_eq!(0, 0.lcm(0)); + assert_eq!(0, 10.lcm(0)); + assert_eq!(0, 10.lcm(0)); + assert_eq!(42, 21.lcm(6)); + } +} diff --git a/types/src/number/mod.rs b/types/src/number/mod.rs index 0233c47..b768631 100644 --- a/types/src/number/mod.rs +++ b/types/src/number/mod.rs @@ -9,6 +9,7 @@ pub mod real; pub mod complex; mod add; +mod math; pub use self::real::Real; pub use self::complex::Complex;