From e47a1f075f316180e6cfb164eccdb766492e64d6 Mon Sep 17 00:00:00 2001 From: Martin Ockajak Date: Tue, 9 Jul 2024 19:46:24 +0200 Subject: [PATCH] . --- src/extensions/collectible.rs | 81 ++++++++++++++--------- src/extensions/collections/binary_heap.rs | 9 +++ src/extensions/collections/btree_set.rs | 9 +++ src/extensions/collections/hash_set.rs | 9 +++ src/extensions/collections/linked_list.rs | 9 +++ src/extensions/collections/vec.rs | 9 +++ src/extensions/collections/vec_deque.rs | 9 +++ 7 files changed, 102 insertions(+), 33 deletions(-) diff --git a/src/extensions/collectible.rs b/src/extensions/collectible.rs index f9c26a3..7c4bf41 100644 --- a/src/extensions/collectible.rs +++ b/src/extensions/collectible.rs @@ -1,13 +1,13 @@ #![deny(missing_docs)] +use crate::extensions::iterable::Iterable; +use crate::extensions::util::unfold::unfold; use std::cmp::Reverse; use std::collections::{BinaryHeap, HashMap, HashSet}; use std::hash::Hash; use std::iter; use std::iter::{Product, Sum}; - -use crate::extensions::iterable::Iterable; -use crate::extensions::util::unfold::unfold; +use std::thread::panicking; /// Consuming collection operations. /// @@ -152,10 +152,8 @@ pub trait Collectible: IntoIterator { /// /// let a = vec![1, 2, 3]; /// - /// let x: Vec> = Vec::new(); - /// assert_eq!(a.clone().combinations(4), x); - /// assert_eq!(a.clone().combinations(1), vec![vec![1], vec![2], vec![3]]); - /// assert_eq!(a.clone().combinations(2), vec![vec![1, 2], vec![1, 3], vec![2, 3]]); + /// assert_eq!(a.combinations(1), vec![vec![1], vec![2], vec![3]]); + /// assert_eq!(a.combinations(2), vec![vec![1, 2], vec![1, 3], vec![2, 3]]); /// assert_eq!(a.combinations(3), vec![vec![1, 2, 3]]); /// ``` fn combinations(&self, k: usize) -> Vec @@ -827,31 +825,28 @@ pub trait Collectible: IntoIterator { (result_left, result_right) } - // /// Creates a collection containing all subsets of the original collection. - // /// - // /// The order or subset values is preserved for ordered collections. - // /// - // /// # Example - // /// - // /// ``` - // /// use cantrip::*; - // /// - // /// let a = vec![1, 2, 3]; - // /// - // /// assert_eq!(a.powerset(), vec![ - // /// vec![], - // /// vec![0], vec![1], vec![2], - // /// vec![0, 1], vec![0, 2], vec![1, 2], - // /// vec![1, 2, 3]] - // /// ); - // /// ``` - // fn powerset(self) -> Self::This - // where - // Item: Clone, - // Self: FromIterator + Sized, - // Self::This: FromIterator { - // self.combinations(2) - // } + /// Creates a collection containing all subsets of the original collection. + /// + /// The order or subset values is preserved for ordered collections. + /// + /// # Example + /// + /// ``` + /// use cantrip::*; + /// + /// let a = vec![1, 2, 3]; + /// + /// assert_eq!(a.powerset(), vec![ + /// vec![], + /// vec![1], vec![2], vec![3], + /// vec![1, 2], vec![1, 3], vec![2, 3], + /// vec![1, 2, 3]] + /// ); + /// ``` + fn powerset(self) -> Vec + where + Item: Clone, + Self: Sized; /// Iterates over the entire collection, multiplying all the elements /// @@ -1174,7 +1169,15 @@ where if k == 0 { return Vec::from_iter(iter::once(Collection::from_iter(iter::empty()))); } - let values = Vec::from_iter(iterator.cloned()); + let values = Vec::from_iter(iterator); + compute_combinations(&values, k) +} + +pub(crate) fn compute_combinations<'a, Item, Collection>(values: &[&Item], k: usize) -> Vec +where + Item: Clone + 'a, + Collection: FromIterator + Sized, +{ let size = values.len(); let mut combination_indices = Vec::from_iter(0..k); unfold(k > size, |done| { @@ -1215,3 +1218,15 @@ pub(crate) fn partition_map<'a, Item: 'a, A, B, Left: Default + Extend, Right } (result_left, result_right) } + +pub(crate) fn powerset<'a, Item, Collection>(iterator: impl Iterator) -> Vec +where + Item: Clone + 'a, + Collection: FromIterator + Sized, +{ + let values = Vec::from_iter(iterator); + let sizes = 1..=values.len(); + iter::once(Collection::from_iter(iter::empty())) + .chain(sizes.flat_map(|size| compute_combinations::(&values, size))) + .collect() +} diff --git a/src/extensions/collections/binary_heap.rs b/src/extensions/collections/binary_heap.rs index 9efa9a6..a883f19 100644 --- a/src/extensions/collections/binary_heap.rs +++ b/src/extensions/collections/binary_heap.rs @@ -127,6 +127,15 @@ impl Collectible for BinaryHeap { partition_map(self.iter(), function) } + #[inline] + fn powerset(self) -> Vec + where + Item: Clone, + Self: Sized + { + powerset(self.iter()) + } + #[inline] fn scan(&self, init: S, function: impl FnMut(&mut S, &Item) -> Option) -> Self::This where diff --git a/src/extensions/collections/btree_set.rs b/src/extensions/collections/btree_set.rs index da120c4..0055c42 100644 --- a/src/extensions/collections/btree_set.rs +++ b/src/extensions/collections/btree_set.rs @@ -127,6 +127,15 @@ impl Collectible for BTreeSet { partition_map(self.iter(), function) } + #[inline] + fn powerset(self) -> Vec + where + Item: Clone, + Self: Sized + { + powerset(self.iter()) + } + #[inline] fn scan(&self, init: S, function: impl FnMut(&mut S, &Item) -> Option) -> Self::This where diff --git a/src/extensions/collections/hash_set.rs b/src/extensions/collections/hash_set.rs index eea70c9..fb43983 100644 --- a/src/extensions/collections/hash_set.rs +++ b/src/extensions/collections/hash_set.rs @@ -128,6 +128,15 @@ impl Collectible for HashSet { partition_map(self.iter(), function) } + #[inline] + fn powerset(self) -> Vec + where + Item: Clone, + Self: Sized + { + powerset(self.iter()) + } + #[inline] fn scan(&self, init: S, function: impl FnMut(&mut S, &Item) -> Option) -> Self::This where diff --git a/src/extensions/collections/linked_list.rs b/src/extensions/collections/linked_list.rs index b4a3973..fd3a383 100644 --- a/src/extensions/collections/linked_list.rs +++ b/src/extensions/collections/linked_list.rs @@ -145,6 +145,15 @@ impl Collectible for LinkedList { partition_map(self.iter(), function) } + #[inline] + fn powerset(self) -> Vec + where + Item: Clone, + Self: Sized + { + powerset(self.iter()) + } + #[inline] fn scan(&self, init: S, function: impl FnMut(&mut S, &Item) -> Option) -> Self::This where diff --git a/src/extensions/collections/vec.rs b/src/extensions/collections/vec.rs index 469d407..f6e01a4 100644 --- a/src/extensions/collections/vec.rs +++ b/src/extensions/collections/vec.rs @@ -158,6 +158,15 @@ impl Collectible for Vec { partition_map(self.iter(), function) } + #[inline] + fn powerset(self) -> Vec + where + Item: Clone, + Self: Sized + { + powerset(self.iter()) + } + #[inline] fn scan(&self, initial_state: S, function: impl FnMut(&mut S, &Item) -> Option) -> Self::This where diff --git a/src/extensions/collections/vec_deque.rs b/src/extensions/collections/vec_deque.rs index 482dc4d..cf5500d 100644 --- a/src/extensions/collections/vec_deque.rs +++ b/src/extensions/collections/vec_deque.rs @@ -145,6 +145,15 @@ impl Collectible for VecDeque { partition_map(self.iter(), function) } + #[inline] + fn powerset(self) -> Vec + where + Item: Clone, + Self: Sized + { + powerset(self.iter()) + } + #[inline] fn scan(&self, init: S, function: impl FnMut(&mut S, &Item) -> Option) -> Self::This where