From 8655265908a729b51f207aa7730ea4bfb1ba0681 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Fri, 15 Dec 2023 17:19:33 +0000 Subject: [PATCH] day-15 --- day-15/go.mod | 10 ++++++++ day-15/go.sum | 18 +++++++++++++++ day-15/hasher.go | 30 ++++++++++++++++++++++++ day-15/makefile | 10 ++++++++ day-15/one.go | 18 +++++++++++++++ day-15/solution.go | 22 ++++++++++++++++++ day-15/two.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++ day-15/util.go | 35 ++++++++++++++++++++++++++++ 8 files changed, 200 insertions(+) create mode 100644 day-15/go.mod create mode 100644 day-15/go.sum create mode 100644 day-15/hasher.go create mode 100644 day-15/makefile create mode 100644 day-15/one.go create mode 100644 day-15/solution.go create mode 100644 day-15/two.go create mode 100644 day-15/util.go diff --git a/day-15/go.mod b/day-15/go.mod new file mode 100644 index 0000000..228e1e8 --- /dev/null +++ b/day-15/go.mod @@ -0,0 +1,10 @@ +module github.com/onyx-and-iris/aoc2023/day-15 + +go 1.21.5 + +require ( + github.com/elliotchance/orderedmap/v2 v2.2.0 + github.com/sirupsen/logrus v1.9.3 +) + +require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect diff --git a/day-15/go.sum b/day-15/go.sum new file mode 100644 index 0000000..70c7aac --- /dev/null +++ b/day-15/go.sum @@ -0,0 +1,18 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elliotchance/orderedmap/v2 v2.2.0 h1:7/2iwO98kYT4XkOjA9mBEIwvi4KpGB4cyHeOFOnj4Vk= +github.com/elliotchance/orderedmap/v2 v2.2.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/day-15/hasher.go b/day-15/hasher.go new file mode 100644 index 0000000..aa4603e --- /dev/null +++ b/day-15/hasher.go @@ -0,0 +1,30 @@ +package main + +// hasher defines the methods required to hash a string +type hasher struct { + next int +} + +// newHasher returns a hasher type +func newHasher() hasher { + return hasher{} +} + +// run processes each step of the hasher for each char in a string +func (h hasher) run(in string) int { + hash := 0 + for _, r := range in { + h.next = hash + int(r) + hash = h.multiply().modulus() + } + return hash +} + +func (h hasher) multiply() hasher { + h.next *= 17 + return h +} + +func (h hasher) modulus() int { + return h.next % 256 +} diff --git a/day-15/makefile b/day-15/makefile new file mode 100644 index 0000000..5a0aa8d --- /dev/null +++ b/day-15/makefile @@ -0,0 +1,10 @@ +TEST="test.txt" +INPUT="input.txt" + +test: + cat $(TEST) | go run . + +run: + cat $(INPUT) | go run . + +all: test diff --git a/day-15/one.go b/day-15/one.go new file mode 100644 index 0000000..b9b6399 --- /dev/null +++ b/day-15/one.go @@ -0,0 +1,18 @@ +package main + +import "strings" + +var lenses = []string{} + +// one returns the sum of all hashed values +func one(lines []string) int { + lenses = strings.Split(lines[0], ",") + hash := newHasher() + + sum := 0 + for _, lense := range lenses { + sum += hash.run(lense) + } + + return sum +} diff --git a/day-15/solution.go b/day-15/solution.go new file mode 100644 index 0000000..f26e29e --- /dev/null +++ b/day-15/solution.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + + log "github.com/sirupsen/logrus" +) + +func init() { + log.SetLevel(log.DebugLevel) +} + +func main() { + lines := readlines() + + ans := one(lines) + fmt.Printf("solution one: %d\n", ans) + + ans = two(lines) + fmt.Printf("solution two: %d\n", ans) + +} diff --git a/day-15/two.go b/day-15/two.go new file mode 100644 index 0000000..4788904 --- /dev/null +++ b/day-15/two.go @@ -0,0 +1,57 @@ +package main + +import ( + "strings" + + "github.com/elliotchance/orderedmap/v2" +) + +var boxes = map[int]*orderedmap.OrderedMap[string, int]{} + +// add places a lense into an ordered box +func add(id int, label string, focalLength int) { + boxes[id].Set(label, focalLength) +} + +// remove takes a lense out of an ordered box +func remove(id int, label string) { + boxes[id].Delete(strings.TrimRight(label, "-")) +} + +// two returns the sum of all lense configurations +func two(lines []string) int { + hash := newHasher() + + for _, lense := range lenses { + label, focalLength := func() (string, int) { + x := strings.Split(lense, "=") + if len(x) == 2 { + return x[0], mustConv(x[1]) + } + return strings.TrimRight(x[0], "-"), 0 + }() + boxId := hash.run(label) + + _, ok := boxes[boxId] + if !ok { + m := orderedmap.NewOrderedMap[string, int]() + boxes[boxId] = m + } + + if strings.Contains(lense, "=") { + add(boxId, label, focalLength) + } else { + remove(boxId, label) + } + } + + sum := 0 + for id, box := range boxes { + for index, lense := range box.Keys() { + focalLength, _ := box.Get(lense) + sum += (id + 1) * (index + 1) * focalLength + } + } + + return sum +} diff --git a/day-15/util.go b/day-15/util.go new file mode 100644 index 0000000..05f6417 --- /dev/null +++ b/day-15/util.go @@ -0,0 +1,35 @@ +package main + +import ( + "bufio" + "log" + "os" + "strconv" +) + +// readlines reads lines from stdin. +// it returns them as an array of strings +func readlines() []string { + lines := []string{} + + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + + return lines +} + +// mustConv converts string to int +// it will panic if an error occurs +func mustConv(s string) int { + n, err := strconv.Atoi(s) + if err != nil { + panic(err) + } + return n +}