-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
perfect_cube.rs
61 lines (54 loc) · 1.89 KB
/
perfect_cube.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Check if a number is a perfect cube using binary search.
pub fn perfect_cube_binary_search(n: i64) -> bool {
if n < 0 {
return perfect_cube_binary_search(-n);
}
// Initialize left and right boundaries for binary search.
let mut left = 0;
let mut right = n.abs(); // Use the absolute value to handle negative numbers
// Binary search loop to find the cube root.
while left <= right {
// Calculate the mid-point.
let mid = left + (right - left) / 2;
// Calculate the cube of the mid-point.
let cube = mid * mid * mid;
// Check if the cube equals the original number.
match cube.cmp(&n) {
std::cmp::Ordering::Equal => return true,
std::cmp::Ordering::Less => left = mid + 1,
std::cmp::Ordering::Greater => right = mid - 1,
}
}
// If no cube root is found, return false.
false
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! test_perfect_cube {
($($name:ident: $inputs:expr,)*) => {
$(
#[test]
fn $name() {
let (n, expected) = $inputs;
assert_eq!(perfect_cube_binary_search(n), expected);
assert_eq!(perfect_cube_binary_search(-n), expected);
}
)*
}
}
test_perfect_cube! {
num_0_a_perfect_cube: (0, true),
num_1_is_a_perfect_cube: (1, true),
num_27_is_a_perfect_cube: (27, true),
num_64_is_a_perfect_cube: (64, true),
num_8_is_a_perfect_cube: (8, true),
num_2_is_not_a_perfect_cube: (2, false),
num_3_is_not_a_perfect_cube: (3, false),
num_4_is_not_a_perfect_cube: (4, false),
num_5_is_not_a_perfect_cube: (5, false),
num_999_is_not_a_perfect_cube: (999, false),
num_1000_is_a_perfect_cube: (1000, true),
num_1001_is_not_a_perfect_cube: (1001, false),
}
}