Skip to content

Commit

Permalink
Add problem 0029: Divide Two Integers
Browse files Browse the repository at this point in the history
  • Loading branch information
Spxg committed May 14, 2024
1 parent e4503fe commit 667629e
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
57 changes: 57 additions & 0 deletions src/problem_0029_divide_two_integers/bit_manipulation.rs
Original file line number Diff line number Diff line change
@@ -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::<super::Solution>();
}
}
28 changes: 28 additions & 0 deletions src/problem_0029_divide_two_integers/mod.rs
Original file line number Diff line number Diff line change
@@ -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<S: Solution>() {
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);
}
}
}

0 comments on commit 667629e

Please sign in to comment.