diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 9115b4f4..27937258 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -38,3 +38,7 @@ path = "structures/fenwick_tree.rs" [[bin]] name = "persistent_tree" path = "structures/persistent_tree.rs" + +[[bin]] +name = "binary_search" +path = "misc/binary_search.rs" diff --git a/rust/misc/binary_search.rs b/rust/misc/binary_search.rs new file mode 100644 index 00000000..f72281e1 --- /dev/null +++ b/rust/misc/binary_search.rs @@ -0,0 +1,35 @@ +// invariant: f[lo] == false, f[hi] == true +pub fn binary_search_first_true(f: F, from_inclusive: i32, to_inclusive: i32) -> i32 +where + F: Fn(i32) -> bool, +{ + let mut lo = from_inclusive - 1; + let mut hi = to_inclusive + 1; + while hi - lo > 1 { + let mid = (lo + hi) / 2; + if !f(mid) { + lo = mid; + } else { + hi = mid; + } + } + hi +} + +#[cfg(test)] +mod tests { + use rstest::rstest; + use crate::binary_search_first_true; + + #[rstest] + #[case(100, 0)] + #[case(100, 1)] + #[case(100, 50)] + #[case(100, 100)] + fn basic_test( + #[case] n: i32, + #[case] pos: i32, + ) { + assert_eq!(binary_search_first_true(|i| { i >= pos }, 0, n), pos); + } +}