扩展欧几里得算法

  1. fn update_step(a: &mut i32, old_a: &mut i32, quotient: i32) {
  2. let temp = *a;
  3. *a = *old_a - quotient * temp;
  4. *old_a = temp;
  5. }
  6. pub fn extended_euclidean_algorithm(a: i32, b: i32) -> (i32, i32, i32) {
  7. let (mut old_r, mut rem) = (a, b);
  8. let (mut old_s, mut coeff_s) = (1, 0);
  9. let (mut old_t, mut coeff_t) = (0, 1);
  10. while rem != 0 {
  11. let quotient = old_r / rem;
  12. update_step(&mut rem, &mut old_r, quotient);
  13. update_step(&mut coeff_s, &mut old_s, quotient);
  14. update_step(&mut coeff_t, &mut old_t, quotient);
  15. }
  16. (old_r, old_s, old_t)
  17. }
  18. #[cfg(test)]
  19. mod tests {
  20. use super::*;
  21. #[test]
  22. fn basic() {
  23. assert_eq!(extended_euclidean_algorithm(101, 13), (1, 4, -31));
  24. assert_eq!(extended_euclidean_algorithm(123, 19), (1, -2, 13));
  25. assert_eq!(extended_euclidean_algorithm(25, 36), (1, 13, -9));
  26. assert_eq!(extended_euclidean_algorithm(69, 54), (3, -7, 9));
  27. assert_eq!(extended_euclidean_algorithm(55, 79), (1, 23, -16));
  28. assert_eq!(extended_euclidean_algorithm(33, 44), (11, -1, 1));
  29. assert_eq!(extended_euclidean_algorithm(50, 70), (10, 3, -2));
  30. }
  31. }