1use std::collections::BTreeSet;
2
3pub struct Combinations<T> {
20 elements: Vec<T>,
21 positions: Vec<usize>,
22 all_sizes: bool,
23 done: bool,
24}
25
26fn iterable_to_sorted_set<T: Ord + Clone>(elements: impl IntoIterator<Item = T>) -> Vec<T> {
29 elements
30 .into_iter()
31 .collect::<BTreeSet<T>>()
32 .into_iter()
33 .collect::<Vec<T>>()
34}
35
36impl<T: Ord + Clone> Combinations<T> {
37 pub fn all(elements: impl IntoIterator<Item = T>) -> Self {
57 Combinations {
58 elements: iterable_to_sorted_set(elements),
59 positions: Vec::new(),
60 all_sizes: true,
61 done: false,
62 }
63 }
64
65 pub fn of_size(elements: impl IntoIterator<Item = T>, size: usize) -> Self {
87 Combinations {
88 elements: iterable_to_sorted_set(elements),
89 positions: (0..size).collect(),
90 all_sizes: false,
91 done: false,
92 }
93 }
94
95 fn move_to_next_set_size(&mut self) -> bool {
98 if self.positions.len() >= self.elements.len() {
99 return false;
100 }
101 self.positions
102 .iter_mut()
103 .enumerate()
104 .for_each(|(index, pos)| *pos = index);
105 self.positions.push(self.positions.len());
106 true
107 }
108
109 fn move_to_next_position(&mut self) -> bool {
113 if self.elements.len() == 0 {
114 return false;
115 }
116 let length = self.positions.len();
117 for index in (0..self.positions.len()).rev() {
118 let cur_position = *self.positions.get(index).unwrap();
119 if cur_position >= self.elements.len() - 1 {
120 continue;
121 }
122 if index == length - 1 || cur_position < self.positions.get(index + 1).unwrap() - 1 {
123 let mut next_position = cur_position + 1;
124 *self.positions.get_mut(index).unwrap() = next_position;
125 for i in index + 1..length {
126 next_position += 1;
127 *self.positions.get_mut(i).unwrap() = next_position;
128 }
129 return true;
130 }
131 }
132 false
133 }
134
135 fn get_current_combination(&mut self) -> Option<Vec<T>> {
137 if self.done || self.positions.len() > self.elements.len() {
138 return None;
139 }
140 Some(
141 self.positions
142 .iter()
143 .map(|p| self.elements.get(*p).unwrap().clone())
144 .collect::<Vec<T>>(),
145 )
146 }
147}
148
149impl<T: Ord + Clone> Iterator for Combinations<T> {
150 type Item = Vec<T>;
151
152 fn next(&mut self) -> Option<Self::Item> {
154 if self.done {
155 return None;
156 }
157 let combo = self.get_current_combination();
158 if self.move_to_next_position() == false {
159 if self.all_sizes == false || self.move_to_next_set_size() == false {
160 self.done = true;
161 }
162 }
163 combo
164 }
165}
166
167pub struct CombinationsWithReplacement<T> {
193 elements: Vec<T>,
194 positions: Vec<usize>,
195 all_sizes: bool,
196 done: bool,
197}
198
199impl<T: Ord + Clone> CombinationsWithReplacement<T> {
200 pub fn all(elements: impl IntoIterator<Item = T>) -> Self {
222 CombinationsWithReplacement {
223 elements: iterable_to_sorted_set(elements),
224 positions: Vec::new(),
225 all_sizes: true,
226 done: false,
227 }
228 }
229
230 pub fn of_size(elements: impl IntoIterator<Item = T>, size: usize) -> Self {
255 CombinationsWithReplacement {
256 elements: iterable_to_sorted_set(elements),
257 positions: vec![0; size],
258 all_sizes: false,
259 done: false,
260 }
261 }
262
263 fn move_to_next_set_size(&mut self) -> bool {
266 if self.positions.len() >= self.elements.len() {
267 return false;
268 }
269 self.positions.iter_mut().for_each(|pos| *pos = 0);
270 self.positions.push(0);
271 true
272 }
273
274 fn move_to_next_position(&mut self) -> bool {
278 if self.elements.len() == 0 {
279 return false;
280 }
281 let length = self.positions.len();
282 for index in (0..self.positions.len()).rev() {
283 let cur_position = *self.positions.get(index).unwrap();
284 if cur_position >= self.elements.len() - 1 {
285 continue;
289 }
290 let next_position = cur_position + 1;
291 for i in index..length {
295 *self.positions.get_mut(i).unwrap() = next_position;
296 }
297 return true;
298 }
299 false
300 }
301
302 fn get_current_combination(&mut self) -> Option<Vec<T>> {
304 if self.done || self.positions.len() > self.elements.len() {
305 return None;
306 }
307 Some(
308 self.positions
309 .iter()
310 .map(|p| self.elements.get(*p).unwrap().clone())
311 .collect::<Vec<T>>(),
312 )
313 }
314}
315
316impl<T: Ord + Clone> Iterator for CombinationsWithReplacement<T> {
317 type Item = Vec<T>;
318
319 fn next(&mut self) -> Option<Self::Item> {
321 if self.done {
322 return None;
323 }
324 let combo = self.get_current_combination();
325 if self.move_to_next_position() == false {
326 if self.all_sizes == false || self.move_to_next_set_size() == false {
327 self.done = true;
328 }
329 }
330 combo
331 }
332}
333
334#[cfg(test)]
335mod tests {
336 use super::*;
337
338 #[test]
339 fn test_combinations_iterable_to_sorted_set() {
340 assert_eq!(vec![1, 2, 3, 4], iterable_to_sorted_set(vec![1, 2, 3, 4]));
341 assert_eq!(vec![1, 2, 3, 4], iterable_to_sorted_set(1..5));
342 assert_eq!(
343 vec![1, 2, 3, 4].iter().collect::<Vec<&usize>>(),
344 iterable_to_sorted_set(vec![2, 3, 1, 4].iter())
345 );
346 assert_eq!(
347 vec![&1, &2, &3, &4],
348 iterable_to_sorted_set(&vec![2, 1, 3, 1, 4, 2, 2, 3])
349 );
350 }
351
352 #[test]
353 fn test_combinations_all() {
354 let combos = Combinations::all(vec![2, 4, 3, 1, 2, 2, 1].into_iter());
355 assert_eq!(combos.elements, vec![1, 2, 3, 4]);
356 assert_eq!(combos.positions, Vec::new());
357 assert_eq!(combos.all_sizes, true);
358 assert_eq!(combos.done, false);
359 }
360
361 #[test]
362 fn test_combinations_w_rep_all() {
363 let combos = CombinationsWithReplacement::all(vec![2, 4, 3, 1, 2, 2, 1].into_iter());
364 assert_eq!(combos.elements, vec![1, 2, 3, 4]);
365 assert_eq!(combos.positions, Vec::new());
366 assert_eq!(combos.all_sizes, true);
367 assert_eq!(combos.done, false);
368 }
369
370 #[test]
371 fn test_combinations_of_size() {
372 let combos = Combinations::of_size(vec![2, 4, 3, 1, 2, 2, 1].into_iter(), 3);
373 assert_eq!(combos.elements, vec![1, 2, 3, 4]);
374 assert_eq!(combos.positions, vec![0, 1, 2]);
375 assert_eq!(combos.all_sizes, false);
376 assert_eq!(combos.done, false);
377 }
378
379 #[test]
380 fn test_combinations_w_rep_of_size() {
381 let combos = CombinationsWithReplacement::of_size(vec![2, 4, 3, 1, 2, 2, 1].into_iter(), 3);
382 assert_eq!(combos.elements, vec![1, 2, 3, 4]);
383 assert_eq!(combos.positions, vec![0; 3]);
384 assert_eq!(combos.all_sizes, false);
385 assert_eq!(combos.done, false);
386 }
387
388 #[test]
389 fn test_combinations_move_to_next_set_size() {
390 let mut combos = Combinations::all(Vec::<i64>::new());
391 assert_eq!(combos.positions, Vec::new());
392 assert_eq!(combos.move_to_next_set_size(), false);
393 let mut combos = Combinations::all(vec![1]);
394 assert_eq!(combos.positions, Vec::new());
395 assert_eq!(combos.move_to_next_set_size(), true);
396 assert_eq!(combos.positions, vec![0]);
397 assert_eq!(combos.move_to_next_set_size(), false);
398 let mut combos = Combinations::all(vec![1, 2, 3, 4]);
399 assert_eq!(combos.positions, Vec::new());
400 assert_eq!(combos.move_to_next_set_size(), true);
401 assert_eq!(combos.positions, vec![0]);
402 combos.positions[0] = 4;
403 assert_eq!(combos.move_to_next_set_size(), true);
404 assert_eq!(combos.positions, vec![0, 1]);
405 combos.positions[0] = 5;
406 combos.positions[1] = 2;
407 assert_eq!(combos.move_to_next_set_size(), true);
408 assert_eq!(combos.positions, vec![0, 1, 2]);
409 combos.positions[0] = 3;
410 combos.positions[1] = 7;
411 combos.positions[2] = 1;
412 assert_eq!(combos.move_to_next_set_size(), true);
413 assert_eq!(combos.positions, vec![0, 1, 2, 3]);
414 combos.positions[0] = 0;
415 combos.positions[1] = 0;
416 combos.positions[2] = 0;
417 combos.positions[2] = 0;
418 assert_eq!(combos.move_to_next_set_size(), false);
419 }
420
421 #[test]
422 fn test_combinations_w_rep_move_to_next_set_size() {
423 let mut combos = CombinationsWithReplacement::all(Vec::<i64>::new());
424 assert_eq!(combos.positions, Vec::new());
425 assert_eq!(combos.move_to_next_set_size(), false);
426 let mut combos = CombinationsWithReplacement::all(vec![1]);
427 assert_eq!(combos.positions, Vec::new());
428 assert_eq!(combos.move_to_next_set_size(), true);
429 assert_eq!(combos.positions, vec![0]);
430 assert_eq!(combos.move_to_next_set_size(), false);
431 let mut combos = CombinationsWithReplacement::all(vec![1, 2, 3, 4]);
432 assert_eq!(combos.positions, Vec::new());
433 assert_eq!(combos.move_to_next_set_size(), true);
434 assert_eq!(combos.positions, vec![0]);
435 combos.positions[0] = 4;
436 assert_eq!(combos.move_to_next_set_size(), true);
437 assert_eq!(combos.positions, vec![0; 2]);
438 combos.positions[0] = 5;
439 combos.positions[1] = 2;
440 assert_eq!(combos.move_to_next_set_size(), true);
441 assert_eq!(combos.positions, vec![0; 3]);
442 combos.positions[0] = 3;
443 combos.positions[1] = 7;
444 combos.positions[2] = 1;
445 assert_eq!(combos.move_to_next_set_size(), true);
446 assert_eq!(combos.positions, vec![0; 4]);
447 combos.positions[0] = 0;
448 combos.positions[1] = 0;
449 combos.positions[2] = 0;
450 combos.positions[2] = 0;
451 assert_eq!(combos.move_to_next_set_size(), false);
452 }
453
454 #[test]
455 fn test_combinations_move_to_next_position() {
456 let mut combos = Combinations::of_size(Vec::<i64>::new(), 1);
457 assert_eq!(combos.positions, vec![0]);
458 assert_eq!(combos.move_to_next_position(), false);
459 let mut combos = Combinations::of_size(vec![1], 1);
460 assert_eq!(combos.positions, vec![0]);
461 assert_eq!(combos.move_to_next_position(), false);
462 let mut combos = Combinations::of_size(BTreeSet::from([1, 2, 3, 4]), 2);
463 assert_eq!(combos.positions, vec![0, 1]);
464 assert_eq!(combos.move_to_next_position(), true);
465 assert_eq!(combos.positions, vec![0, 2]);
466 assert_eq!(combos.move_to_next_position(), true);
467 assert_eq!(combos.positions, vec![0, 3]);
468 assert_eq!(combos.move_to_next_position(), true);
469 assert_eq!(combos.positions, vec![1, 2]);
470 assert_eq!(combos.move_to_next_position(), true);
471 assert_eq!(combos.positions, vec![1, 3]);
472 assert_eq!(combos.move_to_next_position(), true);
473 assert_eq!(combos.positions, vec![2, 3]);
474 assert_eq!(combos.move_to_next_position(), false);
475 let mut combos = Combinations::of_size("abcd".chars(), 3);
476 assert_eq!(combos.positions, vec![0, 1, 2]);
477 assert_eq!(combos.move_to_next_position(), true);
478 assert_eq!(combos.positions, vec![0, 1, 3]);
479 assert_eq!(combos.move_to_next_position(), true);
480 assert_eq!(combos.positions, vec![0, 2, 3]);
481 assert_eq!(combos.move_to_next_position(), true);
482 assert_eq!(combos.positions, vec![1, 2, 3]);
483 assert_eq!(combos.move_to_next_position(), false);
484 }
485
486 #[test]
487 fn test_combinations_w_rep_move_to_next_position() {
488 let mut combos = CombinationsWithReplacement::of_size(Vec::<i64>::new(), 1);
489 assert_eq!(combos.positions, vec![0]);
490 assert_eq!(combos.move_to_next_position(), false);
491 let mut combos = CombinationsWithReplacement::of_size(vec![1], 1);
492 assert_eq!(combos.positions, vec![0]);
493 assert_eq!(combos.move_to_next_position(), false);
494 let mut combos = CombinationsWithReplacement::of_size(BTreeSet::from([1, 2, 3, 4]), 2);
495 assert_eq!(combos.positions, vec![0, 0]);
496 assert_eq!(combos.move_to_next_position(), true);
497 assert_eq!(combos.positions, vec![0, 1]);
498 assert_eq!(combos.move_to_next_position(), true);
499 assert_eq!(combos.positions, vec![0, 2]);
500 assert_eq!(combos.move_to_next_position(), true);
501 assert_eq!(combos.positions, vec![0, 3]);
502 assert_eq!(combos.move_to_next_position(), true);
503 assert_eq!(combos.positions, vec![1, 1]);
504 assert_eq!(combos.move_to_next_position(), true);
505 assert_eq!(combos.positions, vec![1, 2]);
506 assert_eq!(combos.move_to_next_position(), true);
507 assert_eq!(combos.positions, vec![1, 3]);
508 assert_eq!(combos.move_to_next_position(), true);
509 assert_eq!(combos.positions, vec![2, 2]);
510 assert_eq!(combos.move_to_next_position(), true);
511 assert_eq!(combos.positions, vec![2, 3]);
512 assert_eq!(combos.move_to_next_position(), true);
513 assert_eq!(combos.positions, vec![3, 3]);
514 assert_eq!(combos.move_to_next_position(), false);
515 let mut combos = CombinationsWithReplacement::of_size("abcd".chars(), 3);
516 assert_eq!(combos.positions, vec![0, 0, 0]);
517 assert_eq!(combos.move_to_next_position(), true);
518 assert_eq!(combos.positions, vec![0, 0, 1]);
519 assert_eq!(combos.move_to_next_position(), true);
520 assert_eq!(combos.positions, vec![0, 0, 2]);
521 assert_eq!(combos.move_to_next_position(), true);
522 assert_eq!(combos.positions, vec![0, 0, 3]);
523 assert_eq!(combos.move_to_next_position(), true);
524 assert_eq!(combos.positions, vec![0, 1, 1]);
525 assert_eq!(combos.move_to_next_position(), true);
526 assert_eq!(combos.positions, vec![0, 1, 2]);
527 assert_eq!(combos.move_to_next_position(), true);
528 assert_eq!(combos.positions, vec![0, 1, 3]);
529 assert_eq!(combos.move_to_next_position(), true);
530 assert_eq!(combos.positions, vec![0, 2, 2]);
531 assert_eq!(combos.move_to_next_position(), true);
532 assert_eq!(combos.positions, vec![0, 2, 3]);
533 assert_eq!(combos.move_to_next_position(), true);
534 assert_eq!(combos.positions, vec![0, 3, 3]);
535 assert_eq!(combos.move_to_next_position(), true);
536 assert_eq!(combos.positions, vec![1, 1, 1]);
537 assert_eq!(combos.move_to_next_position(), true);
538 assert_eq!(combos.positions, vec![1, 1, 2]);
539 assert_eq!(combos.move_to_next_position(), true);
540 assert_eq!(combos.positions, vec![1, 1, 3]);
541 assert_eq!(combos.move_to_next_position(), true);
542 assert_eq!(combos.positions, vec![1, 2, 2]);
543 assert_eq!(combos.move_to_next_position(), true);
544 assert_eq!(combos.positions, vec![1, 2, 3]);
545 assert_eq!(combos.move_to_next_position(), true);
546 assert_eq!(combos.positions, vec![1, 3, 3]);
547 assert_eq!(combos.move_to_next_position(), true);
548 assert_eq!(combos.positions, vec![2, 2, 2]);
549 assert_eq!(combos.move_to_next_position(), true);
550 assert_eq!(combos.positions, vec![2, 2, 3]);
551 assert_eq!(combos.move_to_next_position(), true);
552 assert_eq!(combos.positions, vec![2, 3, 3]);
553 assert_eq!(combos.move_to_next_position(), true);
554 assert_eq!(combos.positions, vec![3, 3, 3]);
555 assert_eq!(combos.move_to_next_position(), false);
556 }
557
558 #[test]
559 fn test_combinations_get_current_combination() {
560 let mut combos = Combinations::of_size(vec![1, 1, 2, 3, 5, 8], 3);
561 assert_eq!(combos.get_current_combination(), Some(vec![1, 2, 3]));
562 assert_eq!(combos.move_to_next_position(), true);
563 assert_eq!(combos.get_current_combination(), Some(vec![1, 2, 5]));
564 assert_eq!(combos.move_to_next_position(), true);
565 assert_eq!(combos.get_current_combination(), Some(vec![1, 2, 8]));
566 assert_eq!(combos.move_to_next_position(), true);
567 assert_eq!(combos.get_current_combination(), Some(vec![1, 3, 5]));
568 assert_eq!(combos.move_to_next_position(), true);
569 assert_eq!(combos.get_current_combination(), Some(vec![1, 3, 8]));
570 assert_eq!(combos.move_to_next_position(), true);
571 assert_eq!(combos.get_current_combination(), Some(vec![1, 5, 8]));
572 assert_eq!(combos.move_to_next_position(), true);
573 assert_eq!(combos.get_current_combination(), Some(vec![2, 3, 5]));
574 assert_eq!(combos.move_to_next_position(), true);
575 assert_eq!(combos.get_current_combination(), Some(vec![2, 3, 8]));
576 assert_eq!(combos.move_to_next_position(), true);
577 assert_eq!(combos.get_current_combination(), Some(vec![2, 5, 8]));
578 assert_eq!(combos.move_to_next_position(), true);
579 assert_eq!(combos.get_current_combination(), Some(vec![3, 5, 8]));
580 assert_eq!(combos.move_to_next_position(), false);
581 combos.done = true;
582 assert_eq!(combos.get_current_combination(), None);
583 }
584
585 #[test]
586 fn test_combinations_w_rep_get_current_combination() {
587 let mut combos = CombinationsWithReplacement::of_size(vec![1, 1, 2, 3, 5, 8], 3);
588 assert_eq!(combos.get_current_combination(), Some(vec![1, 1, 1]));
589 assert_eq!(combos.move_to_next_position(), true);
590 assert_eq!(combos.get_current_combination(), Some(vec![1, 1, 2]));
591 assert_eq!(combos.move_to_next_position(), true);
592 assert_eq!(combos.get_current_combination(), Some(vec![1, 1, 3]));
593 assert_eq!(combos.move_to_next_position(), true);
594 assert_eq!(combos.get_current_combination(), Some(vec![1, 1, 5]));
595 assert_eq!(combos.move_to_next_position(), true);
596 assert_eq!(combos.get_current_combination(), Some(vec![1, 1, 8]));
597 assert_eq!(combos.move_to_next_position(), true);
598 assert_eq!(combos.get_current_combination(), Some(vec![1, 2, 2]));
599 assert_eq!(combos.move_to_next_position(), true);
600 assert_eq!(combos.get_current_combination(), Some(vec![1, 2, 3]));
601 assert_eq!(combos.move_to_next_position(), true);
602 assert_eq!(combos.get_current_combination(), Some(vec![1, 2, 5]));
603 assert_eq!(combos.move_to_next_position(), true);
604 assert_eq!(combos.get_current_combination(), Some(vec![1, 2, 8]));
605 assert_eq!(combos.move_to_next_position(), true);
606 assert_eq!(combos.get_current_combination(), Some(vec![1, 3, 3]));
607 assert_eq!(combos.move_to_next_position(), true);
608 assert_eq!(combos.get_current_combination(), Some(vec![1, 3, 5]));
609 assert_eq!(combos.move_to_next_position(), true);
610 assert_eq!(combos.get_current_combination(), Some(vec![1, 3, 8]));
611 assert_eq!(combos.move_to_next_position(), true);
612 assert_eq!(combos.get_current_combination(), Some(vec![1, 5, 5]));
613 assert_eq!(combos.move_to_next_position(), true);
614 assert_eq!(combos.get_current_combination(), Some(vec![1, 5, 8]));
615 assert_eq!(combos.move_to_next_position(), true);
616 assert_eq!(combos.get_current_combination(), Some(vec![1, 8, 8]));
617 assert_eq!(combos.move_to_next_position(), true);
618 assert_eq!(combos.get_current_combination(), Some(vec![2, 2, 2]));
619 assert_eq!(combos.move_to_next_position(), true);
620 assert_eq!(combos.get_current_combination(), Some(vec![2, 2, 3]));
621 assert_eq!(combos.move_to_next_position(), true);
622 assert_eq!(combos.get_current_combination(), Some(vec![2, 2, 5]));
623 assert_eq!(combos.move_to_next_position(), true);
624 assert_eq!(combos.get_current_combination(), Some(vec![2, 2, 8]));
625 assert_eq!(combos.move_to_next_position(), true);
626 assert_eq!(combos.get_current_combination(), Some(vec![2, 3, 3]));
627 assert_eq!(combos.move_to_next_position(), true);
628 assert_eq!(combos.get_current_combination(), Some(vec![2, 3, 5]));
629 assert_eq!(combos.move_to_next_position(), true);
630 assert_eq!(combos.get_current_combination(), Some(vec![2, 3, 8]));
631 assert_eq!(combos.move_to_next_position(), true);
632 assert_eq!(combos.get_current_combination(), Some(vec![2, 5, 5]));
633 assert_eq!(combos.move_to_next_position(), true);
634 assert_eq!(combos.get_current_combination(), Some(vec![2, 5, 8]));
635 assert_eq!(combos.move_to_next_position(), true);
636 assert_eq!(combos.get_current_combination(), Some(vec![2, 8, 8]));
637 assert_eq!(combos.move_to_next_position(), true);
638 assert_eq!(combos.get_current_combination(), Some(vec![3, 3, 3]));
639 assert_eq!(combos.move_to_next_position(), true);
640 assert_eq!(combos.get_current_combination(), Some(vec![3, 3, 5]));
641 assert_eq!(combos.move_to_next_position(), true);
642 assert_eq!(combos.get_current_combination(), Some(vec![3, 3, 8]));
643 assert_eq!(combos.move_to_next_position(), true);
644 assert_eq!(combos.get_current_combination(), Some(vec![3, 5, 5]));
645 assert_eq!(combos.move_to_next_position(), true);
646 assert_eq!(combos.get_current_combination(), Some(vec![3, 5, 8]));
647 assert_eq!(combos.move_to_next_position(), true);
648 assert_eq!(combos.get_current_combination(), Some(vec![3, 8, 8]));
649 assert_eq!(combos.move_to_next_position(), true);
650 assert_eq!(combos.get_current_combination(), Some(vec![5, 5, 5]));
651 assert_eq!(combos.move_to_next_position(), true);
652 assert_eq!(combos.get_current_combination(), Some(vec![5, 5, 8]));
653 assert_eq!(combos.move_to_next_position(), true);
654 assert_eq!(combos.get_current_combination(), Some(vec![5, 8, 8]));
655 assert_eq!(combos.move_to_next_position(), true);
656 assert_eq!(combos.get_current_combination(), Some(vec![8, 8, 8]));
657 assert_eq!(combos.move_to_next_position(), false);
658 combos.done = true;
659 assert_eq!(combos.get_current_combination(), None);
660 }
661}