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
62
63
64
65
66
67
68
69
70
71
72
use std::cmp;
#[cfg(test)]
extern crate rand;
#[cfg(test)]
use self::rand::distributions::{Distribution, Uniform};
pub fn lower_bound<T>(arr: &[T], v: &T) -> usize
where
T: cmp::Ord,
{
let mut l = 0;
let mut r = arr.len();
while l < r {
let m = (l + r) / 2;
let vm = &arr[m];
match vm.cmp(v) {
cmp::Ordering::Less => {
l = m + 1;
}
cmp::Ordering::Greater => {
r = m;
}
cmp::Ordering::Equal => {
r = m;
}
}
}
assert_eq!(l, r);
l
}
#[test]
fn test_lower_bound() {
let distr = Uniform::from(0..20);
let mut rng = rand::thread_rng();
let mut arr = (0..1000)
.map(|_| distr.sample(&mut rng))
.collect::<Vec<_>>();
arr.sort();
let val = distr.sample(&mut rng);
let idx = lower_bound(&arr[..], &val);
let mut check = 0;
for (i, v) in arr.iter().enumerate() {
check = i;
if *v == val {
break;
}
}
assert_eq!(check, idx);
}
#[test]
fn test_lower_bound_end() {
let distr = Uniform::from(0..20);
let mut rng = rand::thread_rng();
let mut arr = (0..1000)
.map(|_| distr.sample(&mut rng))
.collect::<Vec<_>>();
arr.sort();
let val = 99;
let idx = lower_bound(&arr[..], &val);
assert_eq!(arr.len(), idx);
}