use crate::models::CustomSet;
use std::hash::Hash;
pub struct SetOperations;
impl SetOperations {
pub fn intersection<T: Eq + Hash + Clone>(a: &CustomSet<T>, b: &CustomSet<T>) -> CustomSet<T> {
a.intersection(b)
}
pub fn union<T: Eq + Hash + Clone>(a: &CustomSet<T>, b: &CustomSet<T>) -> CustomSet<T> {
a.union(b)
}
pub fn complement<T: Eq + Hash + Clone>(
a: &CustomSet<T>,
universal: &CustomSet<T>,
) -> CustomSet<T> {
a.complement(universal)
}
pub fn difference<T: Eq + Hash + Clone>(a: &CustomSet<T>, b: &CustomSet<T>) -> CustomSet<T> {
a.difference(b)
}
pub fn symmetric_difference<T: Eq + Hash + Clone>(
a: &CustomSet<T>,
b: &CustomSet<T>,
) -> CustomSet<T> {
a.symmetric_difference(b)
}
pub fn symmetric_difference_alt<T: Eq + Hash + Clone>(
a: &CustomSet<T>,
b: &CustomSet<T>,
) -> CustomSet<T> {
Self::union(&Self::difference(a, b), &Self::difference(b, a))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_intersection() {
let a = CustomSet::from(vec![2, 4, 6, 8, 10]);
let b = CustomSet::from(vec![4, 10, 14, 18]);
let result = SetOperations::intersection(&a, &b);
assert_eq!(result.cardinality(), 2);
assert!(result.contains(&4));
assert!(result.contains(&10));
}
#[test]
fn test_union() {
let a = CustomSet::from(vec![2, 5, 8]);
let b = CustomSet::from(vec![7, 5, 22]);
let result = SetOperations::union(&a, &b);
assert_eq!(result.cardinality(), 5);
}
#[test]
fn test_complement() {
let universal = CustomSet::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);
let a = CustomSet::from(vec![1, 3, 7, 9]);
let result = SetOperations::complement(&a, &universal);
assert_eq!(result.cardinality(), 5);
}
#[test]
fn test_difference() {
let a = CustomSet::from(vec![1, 2, 3, 4, 5]);
let b = CustomSet::from(vec![2, 4]);
let result = SetOperations::difference(&a, &b);
assert_eq!(result.cardinality(), 3);
}
#[test]
fn test_symmetric_difference() {
let a = CustomSet::from(vec![2, 4, 6]);
let b = CustomSet::from(vec![2, 3, 5]);
let result = SetOperations::symmetric_difference(&a, &b);
assert_eq!(result.cardinality(), 4);
assert!(!result.contains(&2));
}
#[test]
fn test_symmetric_difference_alt() {
let a = CustomSet::from(vec![2, 4, 6]);
let b = CustomSet::from(vec![2, 3, 5]);
let result1 = SetOperations::symmetric_difference(&a, &b);
let result2 = SetOperations::symmetric_difference_alt(&a, &b);
assert_eq!(result1, result2);
}
#[test]
fn test_empty_set_operations() {
let empty = CustomSet::<i32>::empty();
let non_empty = CustomSet::from(vec![1, 2, 3]);
assert!(SetOperations::union(&empty, &empty).is_empty());
assert!(SetOperations::intersection(&empty, &non_empty).is_empty());
assert_eq!(SetOperations::difference(&non_empty, &empty), non_empty);
assert!(SetOperations::difference(&empty, &non_empty).is_empty());
}
#[test]
fn test_set_with_itself() {
let a = CustomSet::from(vec![1, 2, 3]);
assert_eq!(SetOperations::union(&a, &a), a);
assert_eq!(SetOperations::intersection(&a, &a), a);
assert!(SetOperations::difference(&a, &a).is_empty());
assert!(SetOperations::symmetric_difference(&a, &a).is_empty());
}
}