2023 Day 16 Complete!
This commit is contained in:
124
2023/day16/main.go
Normal file
124
2023/day16/main.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
fmt.Println()
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
var (
|
||||
N = h.Coordinate{X: 0, Y: -1}
|
||||
E = h.Coordinate{X: 1, Y: 0}
|
||||
S = h.Coordinate{X: 0, Y: 1}
|
||||
W = h.Coordinate{X: -1, Y: 0}
|
||||
)
|
||||
|
||||
// movement describes how a beam moving in a direction should react
|
||||
// to a byte
|
||||
var movement = map[h.Coordinate]map[byte][]h.Coordinate{
|
||||
N: {
|
||||
'|': {N},
|
||||
'-': {W, E},
|
||||
'\\': {W},
|
||||
'/': {E},
|
||||
'.': {N},
|
||||
},
|
||||
E: {
|
||||
'|': {N, S},
|
||||
'-': {E},
|
||||
'\\': {S},
|
||||
'/': {N},
|
||||
'.': {E},
|
||||
},
|
||||
S: {
|
||||
'|': {S},
|
||||
'-': {W, E},
|
||||
'\\': {E},
|
||||
'/': {W},
|
||||
'.': {S},
|
||||
},
|
||||
W: {
|
||||
'|': {N, S},
|
||||
'-': {W},
|
||||
'\\': {N},
|
||||
'/': {S},
|
||||
'.': {W},
|
||||
},
|
||||
}
|
||||
|
||||
var tileHistory map[h.Coordinate][]h.Coordinate
|
||||
|
||||
func part1(input []string) {
|
||||
mm := h.StringSliceToCoordByteMap(input)
|
||||
tileHistory = make(map[h.Coordinate][]h.Coordinate)
|
||||
proc(&mm, E, h.Coordinate{X: 0, Y: 0})
|
||||
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println(len(tileHistory))
|
||||
}
|
||||
|
||||
func part2(input []string) {
|
||||
mm := h.StringSliceToCoordByteMap(input)
|
||||
|
||||
maxTiles := h.MIN_INT
|
||||
// starts are a map of positions -> directions to test as a starting point
|
||||
starts := make(map[*h.Coordinate]h.Coordinate)
|
||||
for y := mm.TLY; y <= mm.BRY; y++ {
|
||||
for x := mm.TLX; x <= mm.BRX; x++ {
|
||||
if y != mm.TLY && x != mm.TLX && y != mm.BRY && x != mm.BRX {
|
||||
continue
|
||||
}
|
||||
if y == mm.TLY {
|
||||
// South facing beams
|
||||
starts[&h.Coordinate{Y: y, X: x}] = S
|
||||
} else if y == mm.BRY {
|
||||
// North facing beams
|
||||
starts[&h.Coordinate{Y: y, X: x}] = N
|
||||
}
|
||||
if x == mm.TLX {
|
||||
// East facing beams
|
||||
starts[&h.Coordinate{Y: y, X: x}] = E
|
||||
}
|
||||
if x == mm.BRX {
|
||||
// West facing beams
|
||||
starts[&h.Coordinate{Y: y, X: x}] = W
|
||||
}
|
||||
}
|
||||
}
|
||||
for pos, dir := range starts {
|
||||
tileHistory = make(map[h.Coordinate][]h.Coordinate)
|
||||
proc(&mm, dir, *pos)
|
||||
if len(tileHistory) > maxTiles {
|
||||
maxTiles = len(tileHistory)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println(maxTiles)
|
||||
}
|
||||
|
||||
func proc(mm *h.CoordByteMap, dir, pos h.Coordinate) {
|
||||
if !mm.ContainsCoord(pos) {
|
||||
return
|
||||
}
|
||||
if visits, ok := tileHistory[pos]; ok {
|
||||
for _, v := range visits {
|
||||
if v == dir {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
curr := mm.Get(pos)
|
||||
tileHistory[pos] = append(tileHistory[pos], dir)
|
||||
next := movement[dir][curr]
|
||||
for _, n := range next {
|
||||
proc(mm, n, pos.Add(n))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user