1use super::EqSignature;
2use algebraeon_macros::{signature_meta_trait, skip_meta};
3use std::{borrow::Borrow, cmp::Ordering};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum MergedSource {
7 First,
8 Second,
9}
10
11struct VecMerger<'s, X, O: OrdSignature, K: Fn(&X) -> &O::Set> {
12 ordering: &'s O,
13 i: usize,
14 a: Vec<Option<X>>,
15 j: usize,
16 b: Vec<Option<X>>,
17 key: K,
18}
19
20impl<'s, X, O: OrdSignature + 's, K: Fn(&X) -> &O::Set> VecMerger<'s, X, O, K> {
21 fn new(ordering: &'s O, a: Vec<X>, b: Vec<X>, key: K) -> Self {
22 Self {
23 ordering,
24 i: 0,
25 a: a.into_iter().map(|x| Some(x)).collect(),
26 j: 0,
27 b: b.into_iter().map(|x| Some(x)).collect(),
28 key,
29 }
30 }
31}
32
33impl<'s, X, O: OrdSignature + 's, K: Fn(&X) -> &O::Set> Iterator for VecMerger<'s, X, O, K> {
34 type Item = (MergedSource, X);
35
36 fn next(&mut self) -> Option<Self::Item> {
37 match (self.i < self.a.len(), self.j < self.b.len()) {
38 (true, true) => {
39 match self.ordering.cmp(
40 (self.key)(self.a[self.i].as_ref().unwrap()).borrow(),
41 (self.key)(self.b[self.j].as_ref().unwrap()).borrow(),
42 ) {
43 Ordering::Less | Ordering::Equal => {
44 let a_item = self.a[self.i].take().unwrap();
45 self.i += 1;
46 Some((MergedSource::First, a_item))
47 }
48 Ordering::Greater => {
49 let b_item = self.b[self.j].take().unwrap();
50 self.j += 1;
51 Some((MergedSource::Second, b_item))
52 }
53 }
54 }
55 (true, false) => {
56 let a_item = self.a[self.i].take().unwrap();
57 self.i += 1;
58 Some((MergedSource::First, a_item))
59 }
60 (false, true) => {
61 let b_item = self.b[self.j].take().unwrap();
62 self.j += 1;
63 Some((MergedSource::Second, b_item))
64 }
65 (false, false) => None,
66 }
67 }
68}
69
70use super::MetaType;
71
72#[signature_meta_trait]
73pub trait PartialOrdSignature: EqSignature {
74 fn partial_cmp(&self, a: &Self::Set, b: &Self::Set) -> Option<Ordering>;
75}
76
77#[signature_meta_trait]
78pub trait OrdSignature: PartialOrdSignature {
79 fn cmp(&self, a: &Self::Set, b: &Self::Set) -> Ordering;
80
81 fn max(&self, a: &Self::Set, b: &Self::Set) -> Self::Set {
82 let c = self.cmp(a, b);
83 match c {
84 Ordering::Less | Ordering::Equal => b.clone(),
85 Ordering::Greater => a.clone(),
86 }
87 }
88
89 fn min(&self, a: &Self::Set, b: &Self::Set) -> Self::Set {
90 let c = self.cmp(a, b);
91 match c {
92 Ordering::Less | Ordering::Equal => a.clone(),
93 Ordering::Greater => b.clone(),
94 }
95 }
96
97 fn is_sorted(&self, a: &[impl Borrow<Self::Set>]) -> bool {
98 for i in 1..a.len() {
99 if self.cmp(a[i - 1].borrow(), a[i].borrow()) == Ordering::Greater {
100 return false;
101 }
102 }
103 true
104 }
105
106 fn is_sorted_by_key<X>(&self, a: &[X], key: impl Fn(&X) -> &Self::Set) -> bool {
107 self.is_sorted(&a.iter().map(key).collect::<Vec<_>>())
108 }
109
110 fn is_sorted_and_unique(&self, a: &[impl Borrow<Self::Set>]) -> bool {
111 for i in 1..a.len() {
112 if self.cmp(a[i - 1].borrow(), a[i].borrow()) != Ordering::Less {
113 return false;
114 }
115 }
116 true
117 }
118
119 fn is_sorted_and_unique_by_key<X>(&self, a: &[X], key: impl Fn(&X) -> &Self::Set) -> bool {
120 self.is_sorted_and_unique(&a.iter().map(key).collect::<Vec<_>>())
121 }
122
123 fn binary_search(&self, v: &[impl Borrow<Self::Set>], target: &Self::Set) -> bool {
124 self.binary_search_by_key(v, target, |x| x.borrow())
125 .is_some()
126 }
127
128 fn binary_search_by_key<'x, X>(
129 &self,
130 v: &'x [X],
131 target: &Self::Set,
132 key: impl Fn(&X) -> &Self::Set,
133 ) -> Option<&'x X> {
134 debug_assert!(self.is_sorted_by_key(v, &key));
135 if v.is_empty() {
136 return None;
137 }
138 let mut a = 0;
139 let mut b = v.len() - 1;
140
141 if self.equal(target, key(&v[a])) {
142 return Some(&v[a]);
143 }
144
145 if self.equal(target, key(&v[b])) {
146 return Some(&v[b]);
147 }
148
149 while b - a >= 2 {
150 println!("{:?} {:?}", a, b);
151
152 let m = (a + b) / 2;
153 let m_key = key(&v[m]);
154 match self.cmp(target, m_key) {
155 Ordering::Less => b = m,
156 Ordering::Equal => {
157 return Some(&v[m]);
158 }
159 Ordering::Greater => a = m,
160 }
161 }
162
163 None
164 }
165
166 #[skip_meta]
167 fn merge_sorted<'s, S: Borrow<Self::Set> + 's>(
168 &'s self,
169 a: Vec<S>,
170 b: Vec<S>,
171 ) -> impl Iterator<Item = (MergedSource, S)> {
172 self.merge_sorted_by_key(a, b, |x| (*x).borrow())
173 }
174
175 #[skip_meta]
176 fn merge_sorted_by_key<X>(
177 &self,
178 a: Vec<X>,
179 b: Vec<X>,
180 key: impl Fn(&X) -> &Self::Set,
181 ) -> impl Iterator<Item = (MergedSource, X)> {
182 debug_assert!(self.is_sorted_by_key(&a.iter().collect::<Vec<_>>(), |x| key(x)));
183 debug_assert!(self.is_sorted_by_key(&b.iter().collect::<Vec<_>>(), |x| key(x)));
184 VecMerger::new(self, a, b, key)
185 }
186
187 fn sort<S: Borrow<Self::Set>>(&self, a: Vec<S>) -> Vec<S> {
188 self.sort_by_key(a, &|x| x.borrow())
189 }
190
191 #[skip_meta]
192 fn sort_by_key<X>(&self, mut a: Vec<X>, key: &impl Fn(&X) -> &Self::Set) -> Vec<X> {
193 match a.len() {
194 0 | 1 => a,
195 2 => match self.cmp(key(&a[0]).borrow(), key(&a[1]).borrow()) {
196 Ordering::Less | Ordering::Equal => a,
197 Ordering::Greater => {
198 a.swap(0, 1);
199 a
200 }
201 },
202 n => {
203 let k = n / 2;
205
206 let a1 = a.split_off(k);
207 let a0 = a;
208
209 let a0_sorted = self.sort_by_key(a0, key);
210 let a1_sorted = self.sort_by_key(a1, key);
211
212 self.merge_sorted_by_key(a0_sorted, a1_sorted, key)
213 .map(|(_, s)| s)
214 .collect()
215 }
216 }
217 }
218
219 fn sort_by_cached_by<X: 'static>(&self, a: Vec<X>, key: impl Fn(&X) -> Self::Set) -> Vec<X>
220 where
221 Self::Set: 'static,
222 {
223 let mut a = a.into_iter().map(|x| (x, None)).collect::<Vec<_>>();
224 for i in 0..a.len() {
225 let (x, k) = a.get_mut(i).unwrap();
226 *k = Some(key(x));
227 }
228 self.sort_by_key(a, &|(_, k)| k.as_ref().unwrap())
229 .into_iter()
230 .map(|(x, _)| x)
231 .collect()
232 }
233}
234
235#[cfg(test)]
236mod tests {
237 use crate::structure::*;
238
239 use super::*;
240
241 #[derive(Debug, Clone, PartialEq, Eq)]
242 struct UsizeStructure {}
243
244 impl Signature for UsizeStructure {}
245
246 impl SetSignature for UsizeStructure {
247 type Set = usize;
248
249 fn is_element(&self, _x: &Self::Set) -> Result<(), String> {
250 Ok(())
251 }
252 }
253
254 impl EqSignature for UsizeStructure {
255 fn equal(&self, a: &Self::Set, b: &Self::Set) -> bool {
256 a == b
257 }
258 }
259
260 impl PartialOrdSignature for UsizeStructure {
261 fn partial_cmp(&self, a: &Self::Set, b: &Self::Set) -> Option<Ordering> {
262 Some(self.cmp(a, b))
263 }
264 }
265
266 impl OrdSignature for UsizeStructure {
267 fn cmp(&self, a: &Self::Set, b: &Self::Set) -> Ordering {
268 usize::cmp(a, b)
269 }
270 }
271
272 #[test]
273 fn ordering_structure() {
274 let s = UsizeStructure {};
275
276 assert_eq!(s.cmp(&2, &2), Ordering::Equal);
277 assert_eq!(s.cmp(&1, &2), Ordering::Less);
278 assert_eq!(s.cmp(&2, &1), Ordering::Greater);
279
280 assert!(s.is_sorted(&Vec::<usize>::new()));
281 assert!(s.is_sorted(&[7]));
282 assert!(s.is_sorted(&[1, 2]));
283 assert!(!s.is_sorted(&[2, 1]));
284 assert!(s.is_sorted(&[1, 2, 3]));
285 assert!(s.is_sorted(&[1, 1, 1]));
286 assert!(!s.is_sorted(&[1, 2, 1]));
287
288 assert_eq!(
289 s.merge_sorted(Vec::<usize>::new(), Vec::<usize>::new())
290 .collect::<Vec<_>>(),
291 vec![]
292 );
293 {
294 let a = vec![2, 4, 5, 7];
295 let b = vec![1, 3, 6, 7, 8];
296 let c = s.merge_sorted(a, b).collect::<Vec<_>>();
297 assert_eq!(
298 c,
299 vec![
300 (MergedSource::Second, 1),
301 (MergedSource::First, 2),
302 (MergedSource::Second, 3),
303 (MergedSource::First, 4),
304 (MergedSource::First, 5),
305 (MergedSource::Second, 6),
306 (MergedSource::First, 7),
307 (MergedSource::Second, 7),
308 (MergedSource::Second, 8)
309 ]
310 );
311 }
312
313 assert_eq!(s.sort(Vec::<usize>::new()), Vec::<usize>::new());
314 assert_eq!(s.sort(vec![7]), vec![7]);
315 assert_eq!(s.sort(vec![7, 7]), vec![7, 7]);
316 assert_eq!(s.sort(vec![1, 2]), vec![1, 2]);
317 assert_eq!(s.sort(vec![2, 1]), vec![1, 2]);
318 assert_eq!(s.sort(vec![7, 6, 5, 4, 3, 2, 1]), vec![1, 2, 3, 4, 5, 6, 7]);
319 assert_eq!(
320 s.sort(vec![3, 3, 2, 2, 2, 1, 1, 1, 1]),
321 vec![1, 1, 1, 1, 2, 2, 2, 3, 3]
322 );
323 assert_eq!(
324 s.sort_by_cached_by(vec![3, 3, 2, 2, 2, 1, 1, 1, 1], |x| 5 - x),
325 vec![3, 3, 2, 2, 2, 1, 1, 1, 1]
326 );
327
328 let v = vec![1, 2, 3, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11];
329 assert!(!s.binary_search(&v, &0));
330 assert!(s.binary_search(&v, &1));
331 assert!(s.binary_search(&v, &3));
332 assert!(s.binary_search(&v, &4));
333 assert!(s.binary_search(&v, &5));
334 assert!(!s.binary_search(&v, &6));
335 assert!(s.binary_search(&v, &7));
336 assert!(s.binary_search(&v, &11));
337 assert!(!s.binary_search(&v, &12));
338 }
339}