From e355d6fa97e30fbf1d26a09046043f8c84f5e6f6 Mon Sep 17 00:00:00 2001 From: erius Date: Tue, 9 Jul 2024 11:02:09 +0300 Subject: [PATCH] Improved p29 solution --- src/p29_divide_two_integers.rs | 51 ++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/p29_divide_two_integers.rs b/src/p29_divide_two_integers.rs index 91d8a95..78d8b94 100644 --- a/src/p29_divide_two_integers.rs +++ b/src/p29_divide_two_integers.rs @@ -1,11 +1,6 @@ pub struct Solution; impl Solution { - // terrible solutionE - // should use approximation using shifts pub fn divide(mut dividend: i32, mut divisor: i32) -> i32 { - if dividend == i32::MAX && divisor == i32::MIN { - return 0; - } if divisor == 1 { return dividend; } @@ -15,25 +10,34 @@ impl Solution { } return -dividend; } - let mut result = 0; - let is_neg = (dividend < 0) ^ (divisor < 0); - let mut one = false; - dividend = if dividend == i32::MIN { - one = true; - i32::MAX - } else { dividend.abs() }; - divisor = if divisor == i32::MIN { i32::MAX } else { divisor.abs() }; - while dividend >= divisor { - dividend -= divisor; - result += 1; + if divisor == dividend { + return 1; } - if one && dividend - divisor == -1 { - result += 1; + let (mut is_pos, mut quotient) = (true, 0); + if dividend >= 0 { + dividend = -dividend; + is_pos = !is_pos; } - if is_neg { - result = -result; + if divisor >= 0 { + divisor = -divisor; + is_pos = !is_pos; } - return result; + while dividend <= divisor { + let mut shift = 0; + loop { + let shifted = divisor << (shift + 1); + if shifted <= dividend || shifted > 0 { + break; + } + shift += 1; + } + quotient -= 1 << shift; + dividend -= divisor << shift; + } + if is_pos { + quotient = -quotient; + } + return quotient; } } @@ -60,4 +64,9 @@ mod tests { fn test4() { assert_eq!(Solution::divide(-2147483648, -1), 2147483647); } + + #[test] + fn test5() { + assert_eq!(Solution::divide(-2147483648, 3), -715827882); + } }