|
| 1 | +/* |
| 2 | +Finds the product of two numbers using Karatsuba Algorithm |
| 3 | + */ |
| 4 | +use std::cmp::max; |
| 5 | +const TEN: i128 = 10; |
| 6 | + |
| 7 | +pub fn multiply(num1: i128, num2: i128) -> i128 { |
| 8 | + _multiply(num1, num2) |
| 9 | +} |
| 10 | + |
| 11 | +fn _multiply(num1: i128, num2: i128) -> i128 { |
| 12 | + if num1 < 10 || num2 < 10 { |
| 13 | + return num1 * num2; |
| 14 | + } |
| 15 | + let mut num1_str = num1.to_string(); |
| 16 | + let mut num2_str = num2.to_string(); |
| 17 | + |
| 18 | + let n = max(num1_str.len(), num2_str.len()); |
| 19 | + num1_str = normalize(num1_str, n); |
| 20 | + num2_str = normalize(num2_str, n); |
| 21 | + |
| 22 | + let a = &num1_str[0..n / 2]; |
| 23 | + let b = &num1_str[n / 2..]; |
| 24 | + let c = &num2_str[0..n / 2]; |
| 25 | + let d = &num2_str[n / 2..]; |
| 26 | + |
| 27 | + let ac = _multiply(a.parse().unwrap(), c.parse().unwrap()); |
| 28 | + let bd = _multiply(b.parse().unwrap(), d.parse().unwrap()); |
| 29 | + let a_b: i128 = a.parse::<i128>().unwrap() + b.parse::<i128>().unwrap(); |
| 30 | + let c_d: i128 = c.parse::<i128>().unwrap() + d.parse::<i128>().unwrap(); |
| 31 | + let ad_bc = _multiply(a_b, c_d) - (ac + bd); |
| 32 | + |
| 33 | + let m = n / 2 + n % 2; |
| 34 | + (TEN.pow(2 * m as u32) * ac) + (TEN.pow(m as u32) * ad_bc) + (bd) |
| 35 | +} |
| 36 | + |
| 37 | +fn normalize(mut a: String, n: usize) -> String { |
| 38 | + for (counter, _) in (a.len()..n).enumerate() { |
| 39 | + a.insert(counter, '0'); |
| 40 | + } |
| 41 | + a |
| 42 | +} |
| 43 | +#[cfg(test)] |
| 44 | +mod test { |
| 45 | + use super::*; |
| 46 | + |
| 47 | + #[test] |
| 48 | + fn test_1() { |
| 49 | + let n1: i128 = 314159265; |
| 50 | + let n2: i128 = 314159265; |
| 51 | + let ans = multiply(n1, n2); |
| 52 | + assert_eq!(ans, n1 * n2); |
| 53 | + } |
| 54 | + |
| 55 | + #[test] |
| 56 | + fn test_2() { |
| 57 | + let n1: i128 = 3141592653589793232; |
| 58 | + let n2: i128 = 2718281828459045233; |
| 59 | + let ans = multiply(n1, n2); |
| 60 | + assert_eq!(ans, n1 * n2); |
| 61 | + } |
| 62 | + |
| 63 | + #[test] |
| 64 | + fn test_3() { |
| 65 | + let n1: i128 = 123456789; |
| 66 | + let n2: i128 = 101112131415; |
| 67 | + let ans = multiply(n1, n2); |
| 68 | + assert_eq!(ans, n1 * n2); |
| 69 | + } |
| 70 | +} |
0 commit comments