chore: add day 15
This commit is contained in:
parent
186cfb3157
commit
77a54c5563
1
day15/example.txt
Normal file
1
day15/example.txt
Normal 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
1
day15/input.txt
Normal file
File diff suppressed because one or more lines are too long
123
day15/main.go
Normal file
123
day15/main.go
Normal 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
41
day15/main_test.go
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user