aoclib_rs/
binary_search.rs1use std::ops::{Add, Div};
2
3pub trait BinarySearchable<I, V>
5where
6 I: Copy + PartialOrd + Add<Output = I> + Div<usize, Output = I>,
7{
8 fn get_val(&mut self, index: &I) -> V;
11
12 fn found_result(&mut self, val: &V, lower_bound: &I, mid_point: &I, upper_bound: &I) -> bool;
16
17 fn set_next_bounds(
22 &mut self,
23 val: &V,
24 lower_bound: &mut I,
25 mid_point: &I,
26 upper_bound: &mut I,
27 ) -> bool;
28
29 fn binary_search(&mut self, mut lower_bound: I, mut upper_bound: I) -> Option<(I, V)> {
30 while upper_bound > lower_bound {
31 let mid_point = (lower_bound + upper_bound) / 2;
32 let val = self.get_val(&mid_point);
33 if self.found_result(&val, &lower_bound, &mid_point, &upper_bound) {
34 return Some((mid_point, val));
35 }
36 if self.set_next_bounds(&val, &mut lower_bound, &mid_point, &mut upper_bound) {
37 break;
38 }
39 }
40
41 None
42 }
43}
44
45pub struct BinarySearchableVec<V> {
46 v: Vec<V>,
47 t: V,
48}
49
50impl<V> BinarySearchableVec<V> {
51 pub fn new(value: Vec<V>, target: V) -> Self {
52 Self {
53 v: value,
54 t: target,
55 }
56 }
57}
58
59impl<V> BinarySearchable<usize, V> for BinarySearchableVec<V>
60where
61 V: Copy + PartialOrd + PartialEq,
62{
63 fn get_val(&mut self, index: &usize) -> V {
64 self.v[*index]
65 }
66
67 fn found_result(
68 &mut self,
69 val: &V,
70 _lower_bound: &usize,
71 _index: &usize,
72 _upper_bound: &usize,
73 ) -> bool {
74 *val == self.t
75 }
76
77 fn set_next_bounds(
78 &mut self,
79 val: &V,
80 lower_bound: &mut usize,
81 index: &usize,
82 upper_bound: &mut usize,
83 ) -> bool {
84 if *lower_bound == *index {
85 return true;
86 }
87
88 if *val > self.t {
89 *upper_bound = *index;
90 } else if *val < self.t {
91 *lower_bound = *index;
92 } else {
93 panic!("should be impossible");
94 }
95
96 false
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_normal() {
106 let v = vec![1, 2, 3, 4, 5];
107 let l = v.len();
108 let mut bs = BinarySearchableVec::new(v, 3);
109 assert_eq!(bs.binary_search(0, l), Some((2, 3)));
110 }
111
112 #[test]
113 fn test_upper() {
114 let v = vec![1, 2, 3, 4, 5];
115 let l = v.len();
116 let mut bs = BinarySearchableVec::new(v, 5);
117 assert_eq!(bs.binary_search(0, l), Some((4, 5)));
118 }
119
120 #[test]
121 fn test_lower() {
122 let v = vec![1, 2, 3, 4, 5];
123 let l = v.len();
124 let mut bs = BinarySearchableVec::new(v, 1);
125 assert_eq!(bs.binary_search(0, l), Some((0, 1)));
126 }
127
128 #[test]
129 fn test_even_mid_upper() {
130 let v = vec![1, 2, 3, 4];
131 let l = v.len();
132 let mut bs = BinarySearchableVec::new(v, 3);
133 assert_eq!(bs.binary_search(0, l), Some((2, 3)));
134 }
135
136 #[test]
137 fn test_even_mid_lower() {
138 let v = vec![1, 2, 3, 4];
139 let l = v.len();
140 let mut bs = BinarySearchableVec::new(v, 2);
141 assert_eq!(bs.binary_search(0, l), Some((1, 2)));
142 }
143}