competitive_library/math/
euclid.rs1pub fn ngcd(m: u64, n: u64) -> u64 {
3 if m == 0 { n } else { ngcd(n % m, m) }
4}
5pub fn lcm(m: u64, n: u64) -> u64 {
6 m * n / gcd(m, n)
7}
8use std::cmp::min;
9use std::mem::swap;
10pub fn gcd(mut m: u64, mut n: u64) -> u64 {
11 if m == 0 || n == 0 {
12 return n;
13 }
14 let (i, j) = (
15 m.trailing_zeros(),
18 n.trailing_zeros(),
19 );
20 m >>= i;
21 n >>= j;
22
23 loop {
24 if m > n {
25 swap(&mut m, &mut n);
26 }
27 n -= m;
28 if n == 0 {
29 return m << min(i, j);
30 }
31 n >>= n.trailing_zeros();
33 }
34}
35#[cfg(test)]
36mod tests {
37 use super::*;
38 #[test]
39 fn one() {
40 assert_eq!(gcd(1, 2), 1);
41 assert_eq!(gcd(2, 3), 1);
42 assert_eq!(gcd(3, 5), 1);
43 assert_eq!(gcd(5, 7), 1);
44 assert_eq!(gcd(7, 9), 1);
45 assert_eq!(gcd(9, 11), 1);
46 assert_eq!(gcd(11, 13), 1);
47 }
48 #[test]
49 fn t() {
50 assert_eq!(gcd(2, 2), 2);
51 assert_eq!(gcd(2, 4), 2);
52 assert_eq!(gcd(10, 15), 5);
53 assert_eq!(gcd(6, 4), 2);
54 assert_eq!(gcd(100, 30), 10);
55 assert_eq!(gcd(1_000_000_008, 1_000_000_007), 1);
56 }
57}