package sets import ( "iter" "maps" ) type Set[T comparable] struct { data map[T]struct{} } func New[T comparable]() Set[T] { return Set[T]{ data: make(map[T]struct{}), } } func (s *Set[T]) Insert(item T) bool { _, exists := s.data[item] s.data[item] = struct{}{} return !exists } func Singleton[T comparable](item T) Set[T] { n := New[T]() _ = n.Insert(item) return n } func (s *Set[T]) Remove(item T) bool { _, exists := s.data[item] if exists { delete(s.data, item) } return exists } func (s Set[T]) Contains(item T) bool { _, exists := s.data[item] return exists } func (s Set[T]) Len() int { return len(s.data) } func (s Set[T]) IsEmpty() bool { return len(s.data) == 0 } func (s *Set[T]) Clear() { s.data = make(map[T]struct{}) } func (s Set[T]) All() iter.Seq[T] { return func(yield func(T) bool) { for item := range s.data { if !yield(item) { return } } } } func (s Set[T]) Clone() Set[T] { return Set[T]{ data: maps.Clone(s.data), } } func (s Set[T]) Union(other Set[T]) iter.Seq[T] { if s.Len() >= other.Len() { return chain(s.All(), other.Difference(s)) } else { return chain(other.All(), s.Difference(other)) } } func chain[T any](seqs ...iter.Seq[T]) iter.Seq[T] { return func(yield func(T) bool) { for _, seq := range seqs { for item := range seq { if !yield(item) { return } } } } } func (s Set[T]) Intersection(other Set[T]) iter.Seq[T] { return func(yield func(T) bool) { for item := range s.data { if other.Contains(item) { if !yield(item) { return } } } } } func (s Set[T]) Difference(other Set[T]) iter.Seq[T] { return func(yield func(T) bool) { for item := range s.data { if !other.Contains(item) { if !yield(item) { return } } } } } func (s Set[T]) SymmetricDifference(other Set[T]) iter.Seq[T] { return func(yield func(T) bool) { for item := range s.data { if !other.Contains(item) { if !yield(item) { return } } } for item := range other.data { if !s.Contains(item) { if !yield(item) { return } } } } } func (s Set[T]) IsSubset(other Set[T]) bool { for item := range s.data { if !other.Contains(item) { return false } } return true } func (s Set[T]) IsSuperset(other Set[T]) bool { return other.IsSubset(s) } func (s Set[T]) IsDisjoint(other Set[T]) bool { for item := range s.data { if other.Contains(item) { return false } } return true } func (s Set[T]) Equal(other Set[T]) bool { if s.Len() != other.Len() { return false } for item := range s.data { if !other.Contains(item) { return false } } return true } func Collect[T comparable](seq iter.Seq[T]) Set[T] { result := New[T]() for item := range seq { result.Insert(item) } return result }