Watch
1
0
Fork
You've already forked advent-of-code
0

2021 Day 8

This commit is contained in:
Jeremy Kaplan 2021-12-07 23:42:54 -08:00
commit 2d203e541e
3 changed files with 336 additions and 0 deletions

View file

@ -0,0 +1,108 @@
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
}

View file

@ -0,0 +1,40 @@
package stringset_test
import (
"testing"
"github.com/jdkaplan/advent-of-code/aoc/stringset"
)
func TestMinus(t *testing.T) {
a := stringset.Runes("dab")
b := stringset.Runes("ab")
u := a.Minus(b)
if n := len(u); n != 1 {
t.Fatalf("Expected one value, got %d", n)
}
if v := u.Only(); v != "d" {
t.Errorf(`Expected value to be "d", got %s`, v)
}
}
func TestIntersect(t *testing.T) {
t.Run("pairwise", func(t *testing.T) {
u := stringset.Runes("dab").Intersect(stringset.Runes("ab"))
expected := stringset.Runes("ab")
if !u.Equal(expected) {
t.Errorf(`Expected value to be %s, got %s`, expected, u)
}
})
t.Run("multiple", func(t *testing.T) {
u := stringset.Intersect(
stringset.Runes("dab"),
stringset.Runes("ab"),
)
expected := stringset.Runes("ab")
if !u.Equal(expected) {
t.Errorf(`Expected value to be %s, got %s`, expected, u)
}
})
}