1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use num_traits::{PrimInt, Signed, cast::AsPrimitive};

fn mcd<T>(a: T, b: T) -> T
    where
        T: PrimInt + Signed,
{
    let (a, b) = (a.abs(), b.abs());
    let (a, b) = if a < b { (b, a) } else { (a, b) };
    if b.is_zero() {
        return a;
    }
    mcd(b, a % b)
}

fn mcm<T>(a: T, b: T) -> T
    where
        T: PrimInt + AsPrimitive<T> + Signed
{
    a * b / mcd(a.as_(), b.as_())
}


#[cfg(test)]
mod tests {
    use crate::math::{mcd, mcm};

    #[test]
    fn test_mcd() {
        let want = 5;
        let got = mcd(10, 5);

        assert_eq!(got, want);
    }

    #[test]
    fn test_mcd_neg() {
        let want = 5;
        let got = mcd(-10, 5);

        assert_eq!(got, want);
    }

    #[test]
    fn test_mcm() {
        let want = 10;
        let got = mcm(10, 5);

        assert_eq!(got, want);
    }
}