From 667629ee916acc049885d2620965dc9e6df7f006 Mon Sep 17 00:00:00 2001 From: Spxg Date: Tue, 14 May 2024 14:19:52 +0800 Subject: [PATCH] Add problem 0029: Divide Two Integers --- src/lib.rs | 1 + .../bit_manipulation.rs | 57 +++++++++++++++++++ src/problem_0029_divide_two_integers/mod.rs | 28 +++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/problem_0029_divide_two_integers/bit_manipulation.rs create mode 100644 src/problem_0029_divide_two_integers/mod.rs diff --git a/src/lib.rs b/src/lib.rs index 82d667b..8adea0d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -146,6 +146,7 @@ pub mod problem_0024_swap_nodes_in_pairs; pub mod problem_0026_remove_duplicates_from_sorted_array; pub mod problem_0027_remove_element; pub mod problem_0028_find_the_index_of_the_first_occurrence_in_a_string; +pub mod problem_0029_divide_two_integers; pub mod problem_0031_next_permutation; pub mod problem_0033_search_in_rotated_sorted_array; pub mod problem_0034_find_first_and_last_position_of_element_in_sorted_array; diff --git a/src/problem_0029_divide_two_integers/bit_manipulation.rs b/src/problem_0029_divide_two_integers/bit_manipulation.rs new file mode 100644 index 0000000..8185726 --- /dev/null +++ b/src/problem_0029_divide_two_integers/bit_manipulation.rs @@ -0,0 +1,57 @@ +pub struct Solution; + +impl Solution { + pub fn divide(dividend: i32, divisor: i32) -> i32 { + let negative = (dividend < 0) ^ (divisor < 0); + let mut dividend = if dividend == i32::MIN { + u32::from_le_bytes(dividend.to_le_bytes()) + } else { + dividend.unsigned_abs() + }; + let mut divisor = divisor.unsigned_abs(); + let max_offset = divisor.leading_zeros(); + let bound = u32::from_le_bytes(i32::MIN.to_le_bytes()); + + let mut result = 0; + let mut count = 0; + + while dividend >= (divisor << 1) && count < max_offset { + count += 1; + divisor <<= 1; + } + + for offset in (0..=count).rev() { + if dividend >= divisor { + result += 1 << offset; + dividend -= divisor; + } + divisor >>= 1; + } + + if result >= bound { + if negative { + i32::MIN + } else { + i32::MAX + } + } else if negative { + -(result as i32) + } else { + result as i32 + } + } +} + +impl super::Solution for Solution { + fn divide(dividend: i32, divisor: i32) -> i32 { + Self::divide(dividend, divisor) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +} diff --git a/src/problem_0029_divide_two_integers/mod.rs b/src/problem_0029_divide_two_integers/mod.rs new file mode 100644 index 0000000..135f955 --- /dev/null +++ b/src/problem_0029_divide_two_integers/mod.rs @@ -0,0 +1,28 @@ +pub mod bit_manipulation; + +pub trait Solution { + fn divide(dividend: i32, divisor: i32) -> i32; +} + +#[cfg(test)] +mod tests { + use super::Solution; + + pub fn run() { + let test_cases = [ + ((10, 3), 3), + ((7, -3), -2), + ((0, 1), 0), + ((1, 1), 1), + ((1_100_540_749, -1_090_366_779), -1), + ((2_147_483_647, 1), 2_147_483_647), + ((-2_147_483_648, -1), 2_147_483_647), + ((-10, 3), -3), + ((-7, -3), 2), + ]; + + for ((dividend, divisor), expected) in test_cases { + assert_eq!(S::divide(dividend, divisor), expected); + } + } +}