Skip to content

Commit a486aea

Browse files
feat: add find_missing_number function to bit_manipulation (#974)
feat: add find_missing_number function to bit_manipulation
1 parent ed6f1a1 commit a486aea

File tree

3 files changed

+126
-1
lines changed

3 files changed

+126
-1
lines changed

DIRECTORY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# List of all files
22

3-
## Src
3+
## src
44
* Backtracking
55
* [All Combinations of Size K](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/all_combination_of_size_k.rs)
66
* [Graph Coloring](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/graph_coloring.rs)
@@ -21,6 +21,7 @@
2121
* [Counting Bits](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/counting_bits.rs)
2222
* [Highest Set Bit](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/highest_set_bit.rs)
2323
* [Is Power of Two](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/is_power_of_two.rs)
24+
* [Missing Number](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/find_missing_number.rs)
2425
* [N Bits Gray Code](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/n_bits_gray_code.rs)
2526
* [Previous Power of Two](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/find_previous_power_of_two.rs)
2627
* [Reverse Bits](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/reverse_bits.rs)
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/// Finds the missing number in a slice of consecutive integers.
2+
///
3+
/// This function uses XOR bitwise operation to find the missing number.
4+
/// It XORs all expected numbers in the range [min, max] with the actual
5+
/// numbers present in the array. Since XOR has the property that `a ^ a = 0`,
6+
/// all present numbers cancel out, leaving only the missing number.
7+
///
8+
/// # Arguments
9+
///
10+
/// * `nums` - A slice of integers forming a sequence with one missing number
11+
///
12+
/// # Returns
13+
///
14+
/// * `Ok(i32)` - The missing number in the sequence
15+
/// * `Err(String)` - An error message if the input is invalid
16+
///
17+
/// # Examples
18+
///
19+
/// ```
20+
/// # use the_algorithms_rust::bit_manipulation::find_missing_number;
21+
/// assert_eq!(find_missing_number(&[0, 1, 3, 4]).unwrap(), 2);
22+
/// assert_eq!(find_missing_number(&[4, 3, 1, 0]).unwrap(), 2);
23+
/// assert_eq!(find_missing_number(&[-4, -3, -1, 0]).unwrap(), -2);
24+
/// assert_eq!(find_missing_number(&[-2, 2, 1, 3, 0]).unwrap(), -1);
25+
/// assert_eq!(find_missing_number(&[1, 3, 4, 5, 6]).unwrap(), 2);
26+
/// ```
27+
pub fn find_missing_number(nums: &[i32]) -> Result<i32, String> {
28+
if nums.is_empty() {
29+
return Err("input array must not be empty".to_string());
30+
}
31+
32+
if nums.len() == 1 {
33+
return Err("array must have at least 2 elements to find a missing number".to_string());
34+
}
35+
36+
let low = *nums.iter().min().unwrap();
37+
let high = *nums.iter().max().unwrap();
38+
39+
let mut missing_number = high;
40+
41+
for i in low..high {
42+
let index = (i - low) as usize;
43+
missing_number ^= i ^ nums[index];
44+
}
45+
46+
Ok(missing_number)
47+
}
48+
49+
#[cfg(test)]
50+
mod tests {
51+
use super::*;
52+
53+
#[test]
54+
fn test_missing_in_middle() {
55+
assert_eq!(find_missing_number(&[0, 1, 3, 4]).unwrap(), 2);
56+
}
57+
58+
#[test]
59+
fn test_unordered_array() {
60+
assert_eq!(find_missing_number(&[4, 3, 1, 0]).unwrap(), 2);
61+
}
62+
63+
#[test]
64+
fn test_negative_numbers() {
65+
assert_eq!(find_missing_number(&[-4, -3, -1, 0]).unwrap(), -2);
66+
}
67+
68+
#[test]
69+
fn test_negative_and_positive() {
70+
assert_eq!(find_missing_number(&[-2, 2, 1, 3, 0]).unwrap(), -1);
71+
}
72+
73+
#[test]
74+
fn test_missing_at_start() {
75+
assert_eq!(find_missing_number(&[1, 3, 4, 5, 6]).unwrap(), 2);
76+
}
77+
78+
#[test]
79+
fn test_unordered_missing_middle() {
80+
assert_eq!(find_missing_number(&[6, 5, 4, 2, 1]).unwrap(), 3);
81+
}
82+
83+
#[test]
84+
fn test_another_unordered() {
85+
assert_eq!(find_missing_number(&[6, 1, 5, 3, 4]).unwrap(), 2);
86+
}
87+
88+
#[test]
89+
fn test_empty_array() {
90+
assert!(find_missing_number(&[]).is_err());
91+
assert_eq!(
92+
find_missing_number(&[]).unwrap_err(),
93+
"input array must not be empty"
94+
);
95+
}
96+
97+
#[test]
98+
fn test_single_element() {
99+
assert!(find_missing_number(&[5]).is_err());
100+
assert_eq!(
101+
find_missing_number(&[5]).unwrap_err(),
102+
"array must have at least 2 elements to find a missing number"
103+
);
104+
}
105+
106+
#[test]
107+
fn test_two_elements() {
108+
assert_eq!(find_missing_number(&[0, 2]).unwrap(), 1);
109+
assert_eq!(find_missing_number(&[2, 0]).unwrap(), 1);
110+
}
111+
112+
#[test]
113+
fn test_large_range() {
114+
assert_eq!(find_missing_number(&[100, 101, 103, 104]).unwrap(), 102);
115+
}
116+
117+
#[test]
118+
fn test_missing_at_boundaries() {
119+
// Missing is the second to last element
120+
assert_eq!(find_missing_number(&[1, 2, 3, 5]).unwrap(), 4);
121+
}
122+
}

src/bit_manipulation/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod binary_coded_decimal;
22
mod binary_count_trailing_zeros;
33
mod counting_bits;
4+
mod find_missing_number;
45
mod find_previous_power_of_two;
56
mod find_unique_number;
67
mod highest_set_bit;
@@ -14,6 +15,7 @@ mod twos_complement;
1415
pub use self::binary_coded_decimal::binary_coded_decimal;
1516
pub use self::binary_count_trailing_zeros::binary_count_trailing_zeros;
1617
pub use self::counting_bits::count_set_bits;
18+
pub use self::find_missing_number::find_missing_number;
1719
pub use self::find_previous_power_of_two::find_previous_power_of_two;
1820
pub use self::find_unique_number::find_unique_number;
1921
pub use self::highest_set_bit::find_highest_set_bit;

0 commit comments

Comments
 (0)