pub fn power_set<T: Clone>(elements: &[T]) -> Vec<Vec<T>> {
let n = elements.len();
let total = 1 << n;
let mut result = Vec::with_capacity(total);
for mask in 0..total {
let mut subset = Vec::new();
for (i, item) in elements.iter().enumerate() {
if (mask & (1 << i)) != 0 {
subset.push(item.clone());
}
}
result.push(subset);
}
result
}
pub struct PowerSet<'a, T> {
elements: &'a [T],
current: usize,
total: usize,
}
impl<'a, T> PowerSet<'a, T> {
fn new(elements: &'a [T]) -> Self {
PowerSet {
elements,
current: 0,
total: 1 << elements.len(),
}
}
}
impl<T: Clone> Iterator for PowerSet<'_, T> {
type Item = Vec<T>;
fn next(&mut self) -> Option<Self::Item> {
if self.current >= self.total {
return None;
}
let mut subset = Vec::new();
for (i, item) in self.elements.iter().enumerate() {
if (self.current & (1 << i)) != 0 {
subset.push(item.clone());
}
}
self.current += 1;
Some(subset)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.total - self.current;
(remaining, Some(remaining))
}
}
pub fn power_set_iter<T>(elements: &[T]) -> PowerSet<T> {
PowerSet::new(elements)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_power_set_empty() {
let empty: Vec<i32> = vec![];
let subsets = power_set(&empty);
assert_eq!(subsets.len(), 1);
assert_eq!(subsets[0], vec![]);
}
#[test]
fn test_power_set_single() {
let items = vec![42];
let subsets = power_set(&items);
assert_eq!(subsets.len(), 2);
assert!(subsets.contains(&vec![]));
assert!(subsets.contains(&vec![42]));
}
#[test]
fn test_power_set_multiple() {
let items = vec![1, 2, 3];
let subsets = power_set(&items);
assert_eq!(subsets.len(), 8);
assert!(subsets.contains(&vec![]));
assert!(subsets.contains(&vec![1]));
assert!(subsets.contains(&vec![2]));
assert!(subsets.contains(&vec![3]));
assert!(subsets.contains(&vec![1, 2]));
assert!(subsets.contains(&vec![1, 3]));
assert!(subsets.contains(&vec![2, 3]));
assert!(subsets.contains(&vec![1, 2, 3]));
}
#[test]
fn test_power_set_iter() {
let items = vec!['a', 'b'];
let subsets: Vec<_> = power_set_iter(&items).collect();
assert_eq!(subsets.len(), 4);
assert!(subsets.contains(&vec![]));
assert!(subsets.contains(&vec!['a']));
assert!(subsets.contains(&vec!['b']));
assert!(subsets.contains(&vec!['a', 'b']));
}
#[test]
fn test_size_hint() {
let items = vec![1, 2, 3];
let mut iter = power_set_iter(&items);
assert_eq!(iter.size_hint(), (8, Some(8)));
iter.next();
assert_eq!(iter.size_hint(), (7, Some(7)));
}
}