1use std::ops::{Range, RangeFrom, RangeTo};
2
3pub trait Bisect {
4 type Input;
5 type Output;
6 fn bisect(&self, pred: impl FnMut(&Self::Input) -> bool) -> Self::Output;
7}
8
9macro_rules! impl_bisect_uint {
10 ( $($ty:ty)* ) => { $(
11 impl Bisect for Range<$ty> {
12 type Input = $ty;
13 type Output = $ty;
14 fn bisect(&self, mut pred: impl FnMut(&$ty) -> bool) -> $ty {
15 let Range { start: mut ok, end: mut bad } = *self;
16 if !pred(&ok) {
17 return ok;
18 }
19 while bad - ok > 1 {
20 let mid = ok + (bad - ok) / 2;
21 *(if pred(&mid) { &mut ok } else { &mut bad }) = mid;
22 }
23 bad
24 }
25 }
26 impl Bisect for RangeFrom<$ty> {
27 type Input = $ty;
28 type Output = $ty;
29 fn bisect(&self, mut pred: impl FnMut(&$ty) -> bool) -> $ty {
30 let RangeFrom { start: ok } = *self;
31 if !pred(&ok) {
32 return ok;
33 }
34 let mut w = 1;
35 while pred(&(ok + w)) {
36 w *= 2;
37 }
38 (ok + w / 2..ok + w).bisect(pred)
39 }
40 }
41 impl Bisect for RangeTo<$ty> {
42 type Input = $ty;
43 type Output = $ty;
44 fn bisect(&self, mut pred: impl FnMut(&$ty) -> bool) -> $ty {
45 let RangeTo { end: bad } = *self;
46 if pred(&bad) {
47 return bad;
48 }
49 let mut w = 1;
50 while !pred(&(bad - w)) {
51 w *= 2;
52 }
53 (bad - w..bad - w / 2).bisect(pred)
54 }
55 }
56 )* }
57}
58
59impl_bisect_uint! { u8 u16 u32 u64 u128 usize }
60
61macro_rules! impl_bisect_int {
62 ( $( ($ity:ty, $uty:ty, $i2u:ident, $u2i:ident), )* ) => { $(
63 impl Bisect for Range<$ity> {
64 type Input = $ity;
65 type Output = $ity;
66 fn bisect(&self, mut pred: impl FnMut(&$ity) -> bool) -> $ity {
67 let Range { start, end } = *self;
68 let start = $i2u(start);
69 let end = $i2u(end);
70 $u2i((start..end).bisect(|&u| pred(&$u2i(u))))
71 }
72 }
73 impl Bisect for RangeFrom<$ity> {
74 type Input = $ity;
75 type Output = $ity;
76 fn bisect(&self, mut pred: impl FnMut(&$ity) -> bool) -> $ity {
77 let RangeFrom { start } = *self;
78 let start = $i2u(start);
79 $u2i((start..).bisect(|&u| pred(&$u2i(u))))
80 }
81 }
82 impl Bisect for RangeTo<$ity> {
83 type Input = $ity;
84 type Output = $ity;
85 fn bisect(&self, mut pred: impl FnMut(&$ity) -> bool) -> $ity {
86 let RangeTo { end } = *self;
87 let end = $i2u(end);
88 $u2i((..end).bisect(|&u| pred(&$u2i(u))))
89 }
90 }
91 fn $i2u(i: $ity) -> $uty { !(!(0 as $uty) >> 1) ^ i as $uty }
92 fn $u2i(u: $uty) -> $ity { (!(!0 >> 1) ^ u) as $ity }
93 )* }
94}
95
96impl_bisect_int! {
97 (i8, u8, i2u8, u2i8),
98 (i16, u16, i2u16, u2i16),
99 (i32, u32, i2u32, u2i32),
100 (i64, u64, i2u64, u2i64),
101 (i128, u128, i2u128, u2i128),
102 (isize, usize, i2usize, u2isize),
103}
104
105macro_rules! impl_bisect_float {
106 (
107 $(
108 (
109 $fty:ty, $ity:ty, $uty:ty, $w:literal,
110 $f2u:ident, $u2f:ident, $mask:ident
111 ),
112 )*
113 ) => { $(
114 impl Bisect for Range<$fty> {
115 type Input = $fty;
116 type Output = $fty;
117 fn bisect(&self, mut pred: impl FnMut(&$fty) -> bool) -> $fty {
118 let Range { start, end } = *self;
119 let start = $f2u(start);
120 let end = $f2u(end);
121 $u2f((start..end).bisect(|&u| pred(&$u2f(u))))
122 }
123 }
124 impl Bisect for RangeFrom<$fty> {
125 type Input = $fty;
126 type Output = $fty;
127 fn bisect(&self, mut pred: impl FnMut(&$fty) -> bool) -> $fty {
128 let RangeFrom { start } = *self;
129 let start = $f2u(start);
130 $u2f((start..).bisect(|&u| pred(&$u2f(u))))
131 }
132 }
133 impl Bisect for RangeTo<$fty> {
134 type Input = $fty;
135 type Output = $fty;
136 fn bisect(&self, mut pred: impl FnMut(&$fty) -> bool) -> $fty {
137 let RangeTo { end } = *self;
138 let end = $f2u(end);
139 $u2f((..end).bisect(|&u| pred(&$u2f(u))))
140 }
141 }
142 fn $mask(u: $uty) -> $uty {
143 ((u as $ity >> ($w - 1)) as $uty >> 1) | 1 << ($w - 1)
144 }
145 fn $f2u(f: $fty) -> $uty { f.to_bits() ^ $mask(f.to_bits()) }
146 fn $u2f(u: $uty) -> $fty { <$fty>::from_bits(u ^ $mask(!u)) }
147 )* };
148}
149
150impl_bisect_float! {
151 (f32, i32, u32, 32, f2u32, u2f32, mask32),
152 (f64, i64, u64, 64, f2u64, u2f64, mask64),
153}
154
155impl<T> Bisect for [T] {
156 type Input = T;
157 type Output = usize;
158 fn bisect(&self, mut pred: impl FnMut(&T) -> bool) -> usize {
159 if self.is_empty() || !pred(&self[0]) {
160 return 0;
161 }
162 let mut ok = 0;
163 let mut bad = self.len();
164 while bad - ok > 1 {
165 let mid = ok + (bad - ok) / 2;
166 *(if pred(&self[mid]) { &mut ok } else { &mut bad }) = mid;
167 }
168 bad
169 }
170}
171
172#[test]
173fn sanity_check() {
174 {
175 let pred = |&x: &i64| x < 100;
176 assert_eq!((0_i64..200).bisect(pred), 100);
177 assert_eq!((0_i64..).bisect(pred), 100);
178 assert_eq!((..200_i64).bisect(pred), 100);
179 }
180
181 {
182 let pred = |&x: &i64| x.abs() < 100;
183 assert_eq!((0_i64..200).bisect(pred), 100);
184 assert_eq!((0_i64..).bisect(pred), 100);
185 assert_eq!((..0_i64).bisect(|x| !pred(x)), -99);
186 }
187
188 {
189 let pred = |&x: &i64| x < 5;
190 let a = vec![0, 1, 4, 5, 5, 9];
191 assert_eq!(a.bisect(pred), 3);
192 assert_eq!(a[4..].bisect(pred), 0);
193 }
194
195 {
196 let pred = |&x: &f64| 2.0_f64.powf(x) < 3.0;
197 assert!(((1.0_f64..2.0).bisect(pred) - 3.0_f64.log2()) <= 5.0e-324);
198 }
201 {
202 assert_eq!([0, 1, 4, 5, 9].bisect(|&x: &i32| x < 5), 3);
203 assert_eq!((0..100).bisect(|&x: &i32| x * x < 200), 15);
204 assert_eq!((0..).bisect(|&x: &i32| x * x < 200), 15);
205 }
206 {
207 let pred = |&x: &i32| x * x < 200;
208 assert_eq!((0..100).bisect(pred), 15);
209 assert_eq!((0..).bisect(pred), 15);
210 }
211}