aoc_util/
math.rs

1use num_traits::{PrimInt, Signed, cast::AsPrimitive};
2
3pub fn mcd<T>(a: T, b: T) -> T
4    where
5        T: PrimInt + Signed,
6{
7    let (a, b) = (a.abs(), b.abs());
8    let (a, b) = if a < b { (b, a) } else { (a, b) };
9    if b.is_zero() {
10        return a;
11    }
12    mcd(b, a % b)
13}
14
15pub fn mcm<T>(a: T, b: T) -> T
16    where
17        T: PrimInt + AsPrimitive<T> + Signed
18{
19    a * b / mcd(a.as_(), b.as_())
20}
21
22
23#[cfg(test)]
24mod tests {
25    use crate::math::{mcd, mcm};
26
27    #[test]
28    fn test_mcd() {
29        let want = 5;
30        let got = mcd(10, 5);
31
32        assert_eq!(got, want);
33    }
34
35    #[test]
36    fn test_mcd_neg() {
37        let want = 5;
38        let got = mcd(-10, 5);
39
40        assert_eq!(got, want);
41    }
42
43    #[test]
44    fn test_mcm() {
45        let want = 10;
46        let got = mcm(10, 5);
47
48        assert_eq!(got, want);
49    }
50}