Watch
1
0
Fork
You've already forked advent-of-code
0
advent-of-code/2021/aoc/stringset/stringset.go
2021-12-07 23:42:54 -08:00

108 lines
1.6 KiB
Go

package stringset
import (
"fmt"
"sort"
"strings"
)
type StringSet map[string]struct{}
func Slice(vals []string) StringSet {
set := make(StringSet)
for _, v := range vals {
set[v] = struct{}{}
}
return set
}
func Runes(v string) StringSet {
return Slice(strings.Split(v, ""))
}
func (s StringSet) String() string {
var elts []string
for e := range s {
elts = append(elts, e)
}
sort.Strings(elts)
return fmt.Sprintf("{%s}", strings.Join(elts, ", "))
}
func (s StringSet) Only() string {
if len(s) > 1 {
panic(fmt.Sprintf("too many elements: %s", s))
}
for v := range s {
return v
}
panic("empty set")
}
func (s StringSet) Has(elt string) bool {
_, ok := s[elt]
return ok
}
func (s StringSet) add(elt string) {
s[elt] = struct{}{}
}
func (s StringSet) Union(t StringSet) StringSet {
set := make(StringSet)
for a := range s {
set.add(a)
}
for b := range t {
set.add(b)
}
return set
}
func (s StringSet) Intersect(t StringSet) StringSet {
set := make(StringSet)
for a := range s {
if t.Has(a) {
set.add(a)
}
}
return set
}
func (s StringSet) Minus(t StringSet) StringSet {
set := make(StringSet)
for a := range s {
if !t.Has(a) {
set.add(a)
}
}
return set
}
func (s StringSet) Equal(t StringSet) bool {
if len(s) != len(t) {
return false
}
for a := range s {
if !t.Has(a) {
return false
}
}
return true
}
func Union(sets ...StringSet) StringSet {
t := make(StringSet)
for _, s := range sets {
t = t.Union(s)
}
return t
}
func Intersect(sets ...StringSet) StringSet {
t := Union(sets...)
for _, s := range sets {
t = t.Intersect(s)
}
return t
}