1use std::{collections::BTreeSet, mem::swap};
2
3pub trait SliceCombinationsExt<T> {
4 fn for_each_product<F>(&self, r: usize, f: F)
5 where
6 F: FnMut(&[T]);
7 fn for_each_permutations<F>(&self, r: usize, f: F)
8 where
9 F: FnMut(&[T]);
10 fn for_each_combinations<F>(&self, r: usize, f: F)
11 where
12 F: FnMut(&[T]);
13 fn for_each_combinations_with_replacement<F>(&self, r: usize, f: F)
14 where
15 F: FnMut(&[T]);
16 fn next_permutation(&mut self) -> bool
17 where
18 T: Ord;
19 fn prev_permutation(&mut self) -> bool
20 where
21 T: Ord;
22 fn next_combination(&mut self, r: usize) -> bool
23 where
24 T: Ord;
25 fn prev_combination(&mut self, r: usize) -> bool
26 where
27 T: Ord;
28}
29
30impl<T> SliceCombinationsExt<T> for [T]
31where
32 T: Clone,
33{
34 fn for_each_product<F>(&self, r: usize, mut f: F)
52 where
53 F: FnMut(&[T]),
54 {
55 fn product_inner<T, F>(n: &[T], mut r: usize, buf: &mut Vec<T>, f: &mut F)
56 where
57 T: Clone,
58 F: FnMut(&[T]),
59 {
60 if r == 0 {
61 f(buf.as_slice());
62 } else {
63 r -= 1;
64 for a in n.iter().cloned() {
65 buf.push(a);
66 product_inner(n, r, buf, f);
67 buf.pop();
68 }
69 }
70 }
71
72 let mut v = Vec::with_capacity(r);
73 product_inner(self, r, &mut v, &mut f);
74 }
75
76 fn for_each_permutations<F>(&self, r: usize, mut f: F)
94 where
95 F: FnMut(&[T]),
96 {
97 fn permutations_inner<T, F>(
98 n: &[T],
99 mut r: usize,
100 rem: &mut BTreeSet<usize>,
101 buf: &mut Vec<T>,
102 f: &mut F,
103 ) where
104 T: Clone,
105 F: FnMut(&[T]),
106 {
107 if r == 0 {
108 f(buf.as_slice());
109 } else {
110 r -= 1;
111 for i in rem.iter().cloned().collect::<Vec<_>>() {
112 buf.push(n[i].clone());
113 rem.remove(&i);
114 permutations_inner(n, r, rem, buf, f);
115 rem.insert(i);
116 buf.pop();
117 }
118 }
119 }
120
121 if r <= self.len() {
122 let mut v = Vec::with_capacity(r);
123 let mut rem: BTreeSet<usize> = (0..self.len()).collect();
124 permutations_inner(self, r, &mut rem, &mut v, &mut f);
125 }
126 }
127
128 fn for_each_combinations<F>(&self, r: usize, mut f: F)
148 where
149 F: FnMut(&[T]),
150 {
151 fn combinations_inner<T, F>(
152 n: &[T],
153 mut r: usize,
154 start: usize,
155 buf: &mut Vec<T>,
156 f: &mut F,
157 ) where
158 T: Clone,
159 F: FnMut(&[T]),
160 {
161 if r == 0 {
162 f(buf.as_slice());
163 } else {
164 r -= 1;
165 for i in start..n.len() - r {
166 buf.push(n[i].clone());
167 combinations_inner(n, r, i + 1, buf, f);
168 buf.pop();
169 }
170 }
171 }
172
173 if r <= self.len() {
174 let mut v = Vec::with_capacity(r);
175 combinations_inner(self, r, 0, &mut v, &mut f);
176 }
177 }
178
179 fn for_each_combinations_with_replacement<F>(&self, r: usize, mut f: F)
197 where
198 F: FnMut(&[T]),
199 {
200 fn combinations_with_replacement_inner<T, F>(
201 n: &[T],
202 mut r: usize,
203 start: usize,
204 buf: &mut Vec<T>,
205 f: &mut F,
206 ) where
207 T: Clone,
208 F: FnMut(&[T]),
209 {
210 if r == 0 {
211 f(buf.as_slice());
212 } else {
213 r -= 1;
214 for i in start..n.len() {
215 buf.push(n[i].clone());
216 combinations_with_replacement_inner(n, r, i, buf, f);
217 buf.pop();
218 }
219 }
220 }
221
222 if r <= self.len() {
223 let mut v = Vec::with_capacity(r);
224 combinations_with_replacement_inner(self, r, 0, &mut v, &mut f);
225 }
226 }
227
228 fn next_permutation(&mut self) -> bool
231 where
232 T: Ord,
233 {
234 if self.len() < 2 {
235 return false;
236 }
237 let mut target = self.len() - 2;
238 while target > 0 && self[target] > self[target + 1] {
239 target -= 1;
240 }
241 if target == 0 && self[target] > self[target + 1] {
242 return false;
243 }
244 let mut next = self.len() - 1;
245 while next > target && self[next] < self[target] {
246 next -= 1;
247 }
248 self.swap(next, target);
249 self[target + 1..].reverse();
250 true
251 }
252
253 fn prev_permutation(&mut self) -> bool
256 where
257 T: Ord,
258 {
259 if self.len() < 2 {
260 return false;
261 }
262 let mut target = self.len() - 2;
263 while target > 0 && self[target] < self[target + 1] {
264 target -= 1;
265 }
266 if target == 0 && self[target] < self[target + 1] {
267 return false;
268 }
269 self[target + 1..].reverse();
270 let mut next = self.len() - 1;
271 while next > target && self[next - 1] < self[target] {
272 next -= 1;
273 }
274 self.swap(target, next);
275 true
276 }
277
278 fn next_combination(&mut self, r: usize) -> bool
281 where
282 T: Ord,
283 {
284 assert!(r <= self.len());
285 let (a, b) = self.split_at_mut(r);
286 next_combination_inner(a, b)
287 }
288
289 fn prev_combination(&mut self, r: usize) -> bool
292 where
293 T: Ord,
294 {
295 assert!(r <= self.len());
296 let (a, b) = self.split_at_mut(r);
297 next_combination_inner(b, a)
298 }
299}
300
301fn rotate_distinct<'a, T>(mut a: &'a mut [T], mut b: &'a mut [T]) {
302 while !a.is_empty() && !b.is_empty() {
303 if a.len() >= b.len() {
304 let (l, r) = a.split_at_mut(b.len());
305 l.swap_with_slice(b);
306 a = r;
307 } else {
308 let (l, r) = b.split_at_mut(a.len());
309 l.swap_with_slice(a);
310 a = l;
311 b = r;
312 }
313 }
314}
315
316fn next_combination_inner<T>(a: &mut [T], b: &mut [T]) -> bool
317where
318 T: Ord,
319{
320 if a.is_empty() || b.is_empty() {
321 return false;
322 }
323 let mut target = a.len() - 1;
324 let last_elem = b.last().unwrap();
325 while target > 0 && &a[target] >= last_elem {
326 target -= 1;
327 }
328 if target == 0 && &a[target] >= last_elem {
329 rotate_distinct(a, b);
330 return false;
331 }
332 let mut next = 0;
333 while a[target] >= b[next] {
334 next += 1;
335 }
336 swap(&mut a[target], &mut b[next]);
337 rotate_distinct(&mut a[target + 1..], &mut b[next + 1..]);
338 true
339}
340
341#[cfg(test)]
342mod tests {
343 use super::*;
344
345 #[test]
346 fn test_next_prev_permutation() {
347 for n in 1..=7 {
348 let mut p: Vec<_> = (0..n).collect();
349 let mut a = vec![];
350 p.for_each_permutations(n, |p| a.push(p.to_vec()));
351 let mut b = vec![];
352 loop {
353 b.push(p.to_vec());
354 if !p.next_permutation() {
355 break;
356 }
357 assert!(p.prev_permutation());
358 assert_eq!(b.last().as_ref().unwrap().as_slice(), &p);
359 assert!(p.next_permutation());
360 }
361 assert_eq!(a, b);
362 }
363 }
364
365 #[test]
366 fn test_next_prev_combination() {
367 for n in 1..=7 {
368 for r in 0..=n {
369 let mut p: Vec<_> = (0..n).collect();
370 let mut a = vec![];
371 p.for_each_combinations(r, |p| a.push(p.to_vec()));
372 let mut b = vec![];
373 loop {
374 b.push(p[..r].to_vec());
375 if !p.next_combination(r) {
376 break;
377 }
378 assert!(p.prev_combination(r));
379 assert_eq!(b.last().as_ref().unwrap().as_slice(), &p[..r]);
380 assert!(p.next_combination(r));
381 }
382 assert_eq!(a, b);
383 }
384 }
385 }
386}