advent-of-code/day18/main.go

91 lines
1.5 KiB
Go
Raw Normal View History

2023-12-20 11:27:20 -07:00
package main
import (
"bufio"
_ "embed"
"fmt"
2023-12-27 13:18:49 -07:00
"strconv"
2023-12-20 11:27:20 -07:00
"strings"
aoc "go.sour.is/advent-of-code"
2023-12-27 13:18:49 -07:00
"golang.org/x/exp/maps"
2023-12-20 11:27:20 -07:00
)
// 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) {
2023-12-27 14:01:04 -07:00
var vecsPT1 []aoc.Vector
var vecsPT2 []aoc.Vector
2023-12-20 11:27:20 -07:00
for scan.Scan() {
text := scan.Text()
if len(text) == 0 {
continue
}
2023-12-27 13:46:42 -07:00
v, color := fromLine(text)
vecsPT1 = append(vecsPT1, v)
vecsPT2 = append(vecsPT2, fromColor(color))
2023-12-20 11:27:20 -07:00
}
2023-12-27 13:18:49 -07:00
return &result{
2023-12-27 13:46:42 -07:00
valuePT1: findArea(vecsPT1),
valuePT2: findArea(vecsPT2),
2023-12-27 13:18:49 -07:00
}, nil
}
2023-12-20 11:27:20 -07:00
2023-12-27 14:01:04 -07:00
var OFFSET = map[string]aoc.Point{
2023-12-27 13:46:42 -07:00
"R": {0, 1},
"D": {1, 0},
"L": {0, -1},
"U": {-1, 0},
2023-12-20 11:27:20 -07:00
}
2023-12-27 13:46:42 -07:00
var OFFSET_INDEXES = maps.Values(OFFSET)
2023-12-20 11:27:20 -07:00
2023-12-27 14:01:04 -07:00
func fromLine(text string) (aoc.Vector, string) {
v := aoc.Vector{}
2023-12-27 13:46:42 -07:00
s, text, _ := strings.Cut(text, " ")
2023-12-27 14:01:04 -07:00
v.Offset = OFFSET[s]
2023-12-20 11:27:20 -07:00
2023-12-27 13:46:42 -07:00
s, text, _ = strings.Cut(text, " ")
2023-12-27 14:01:04 -07:00
v.Scale = aoc.Atoi(s)
2023-12-20 11:27:20 -07:00
2023-12-27 13:46:42 -07:00
_, text, _ = strings.Cut(text, "(#")
s, _, _ = strings.Cut(text, ")")
return v, s
}
2023-12-27 14:01:04 -07:00
func fromColor(c string) aoc.Vector {
2023-12-27 13:46:42 -07:00
scale, _ := strconv.ParseInt(c[:5], 16, 64)
offset := OFFSET_INDEXES[c[5]-'0']
2023-12-27 14:01:04 -07:00
return aoc.Vector{
Offset: offset,
Scale: int(scale),
2023-12-20 11:27:20 -07:00
}
2023-12-27 13:18:49 -07:00
}
2023-12-20 11:27:20 -07:00
2023-12-27 14:01:04 -07:00
func findArea(vecs []aoc.Vector) int {
shoelace := []aoc.Point{{0,0}}
2023-12-27 13:46:42 -07:00
borderLength := 0
for _, vec := range vecs {
2023-12-27 14:01:04 -07:00
shoelace = append(shoelace, shoelace[len(shoelace)-1].Add(vec.Point()))
borderLength += vec.Scale
2023-12-20 11:27:20 -07:00
}
2023-12-27 14:01:04 -07:00
return aoc.NumPoints(shoelace, borderLength)
2023-12-20 11:27:20 -07:00
}
2023-12-27 13:46:42 -07:00