use crate::models::CustomSet;
use std::hash::Hash;
pub struct PowerSet<T: Eq + Hash + Clone> {
elements: Vec<T>,
current: usize,
total: usize,
}
impl<T: Eq + Hash + Clone> PowerSet<T> {
pub fn new(set: &CustomSet<T>) -> Self {
let elements: Vec<T> = set.iter().cloned().collect();
let total = 1 << elements.len();
Self {
elements,
current: 0,
total,
}
}
}
impl<T: Eq + Hash + Clone> Iterator for PowerSet<T> {
type Item = CustomSet<T>;
fn next(&mut self) -> Option<Self::Item> {
if self.current >= self.total {
return None;
}
let mut subset = Vec::new();
for j in 0..self.elements.len() {
if (self.current & (1 << j)) != 0 {
subset.push(self.elements[j].clone());
}
}
self.current += 1;
Some(CustomSet::new(subset))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.total - self.current;
(remaining, Some(remaining))
}
}
impl<T: Eq + Hash + Clone> ExactSizeIterator for PowerSet<T> {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_power_set_iterator() {
let set = CustomSet::from(vec![1, 2]);
let power_set: Vec<_> = set.power_set().collect();
assert_eq!(power_set.len(), 4); }
#[test]
fn test_power_set_empty() {
let empty = CustomSet::<i32>::empty();
let power_set: Vec<_> = empty.power_set().collect();
assert_eq!(power_set.len(), 1); }
#[test]
fn test_power_set_three_elements() {
let set = CustomSet::from(vec![1, 2, 3]);
let power_set: Vec<_> = set.power_set().collect();
assert_eq!(power_set.len(), 8); }
#[test]
fn test_power_set_contains_empty() {
let set = CustomSet::from(vec![1, 2]);
let power_set: Vec<_> = set.power_set().collect();
assert!(power_set.iter().any(|s| s.is_empty()));
}
#[test]
fn test_power_set_contains_original() {
let set = CustomSet::from(vec![1, 2]);
let power_set: Vec<_> = set.power_set().collect();
assert!(power_set.iter().any(|s| s.equals(&set)));
}
#[test]
fn test_power_set_size_hint() {
let set = CustomSet::from(vec![1, 2, 3]);
let mut power_set = set.power_set();
assert_eq!(power_set.size_hint(), (8, Some(8)));
power_set.next();
assert_eq!(power_set.size_hint(), (7, Some(7)));
}
}