chore: add day 15
Some checks failed
Go Bump / bump (push) Successful in 6s
Go Test / build (push) Failing after 42s

This commit is contained in:
xuu 2023-12-15 09:57:44 -07:00
parent 186cfb3157
commit 77a54c5563
Signed by: xuu
GPG Key ID: 8B3B0604F164E04F
5 changed files with 173 additions and 0 deletions

1
day15/example.txt Normal file
View File

@ -0,0 +1 @@
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7

1
day15/input.txt Normal file

File diff suppressed because one or more lines are too long

123
day15/main.go Normal file
View File

@ -0,0 +1,123 @@
package main
import (
"bufio"
_ "embed"
"fmt"
"slices"
"strings"
aoc "go.sour.is/advent-of-code-2023"
)
var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
r := &result{}
var ops []string
for scan.Scan() {
text := scan.Text()
ops = strings.Split(text, ",")
r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
sum += hash(t)
return sum
}, 0, ops...)
}
var boxen boxes
boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
return b.Op(op)
}, boxen, ops...)
r.valuePT2 = boxen.Sum()
log(boxen)
return r, nil
}
func hash(s string) int {
var sum int
for _, a := range s {
sum += int(a)
sum *= 17
sum %= 256
}
return sum
}
type lens struct {
label string
value int
}
type box []lens
type boxes [256]box
func (lis boxes) String() string {
var buf strings.Builder
buf.WriteString("Boxes:\n")
for i, b := range lis {
if len(b) > 0 {
fmt.Fprintf(&buf, "Box %d: %v\n",i, b)
}
}
return buf.String()
}
func (lis box) String() string {
var buf strings.Builder
if len(lis) > 0 {
buf.WriteString(lis[0].String())
}
for _, l := range lis[1:] {
buf.WriteString(l.String())
}
return buf.String()
}
func (l lens) String() string {
return fmt.Sprintf("[%s %d]", l.label, l.value)
}
func (lis boxes) Op(op string) boxes {
if a, _, ok := strings.Cut(op, "-"); ok {
i := hash(a)
pos := slices.IndexFunc(lis[i], func(l lens) bool { return l.label == a })
if pos >= 0 {
lis[i] = append(lis[i][:pos], lis[i][pos+1:]...)
}
} else if a, b, ok := strings.Cut(op, "="); ok {
i := hash(a)
pos := slices.IndexFunc(lis[i], func(l lens) bool { return l.label == a })
v := aoc.Atoi(b)
if pos == -1 {
lis[i] = append(lis[i], lens{a, v})
} else {
lis[i][pos].value = v
}
}
return lis
}
func (lis boxes) Sum() int {
sum := 0
for b := range lis {
for s := range lis[b] {
sum += (b+1) * (s+1) * lis[b][s].value
}
}
return sum
}

41
day15/main_test.go Normal file
View File

@ -0,0 +1,41 @@
package main
import (
"bufio"
"bytes"
"testing"
_ "embed"
"github.com/matryer/is"
)
//go:embed example.txt
var example []byte
//go:embed input.txt
var input []byte
func TestExample(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 1320)
is.Equal(result.valuePT2, 145)
}
func TestSolution(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(input))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 503154)
is.Equal(result.valuePT2, 251353)
}

View File

@ -265,4 +265,11 @@ func Transpose[T any](matrix [][]T) [][]T {
}
}
return m
}
func Reduce[T, U any](fn func(int, T, U) U, u U, list ...T) U {
for i, t := range list {
u = fn(i, t, u)
}
return u
}