Compare commits
4 Commits
d09a8af5db
...
ed4abd2d7e
Author | SHA1 | Date |
---|---|---|
|
ed4abd2d7e | |
|
ee9c2c1ca0 | |
|
8436426d3a | |
|
cb973d60cc |
|
@ -0,0 +1,10 @@
|
||||||
|
.|...\....
|
||||||
|
|.-.\.....
|
||||||
|
.....|-...
|
||||||
|
........|.
|
||||||
|
..........
|
||||||
|
.........\
|
||||||
|
..../.\\..
|
||||||
|
.-.-/..|..
|
||||||
|
.|....-|.\
|
||||||
|
..//.|....
|
|
@ -0,0 +1,306 @@
|
||||||
|
package day16
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Run() int {
|
||||||
|
fmt.Println("hello from day 16")
|
||||||
|
log.Println("starting")
|
||||||
|
filename := "day16/input"
|
||||||
|
field := ReadField(filename)
|
||||||
|
startPoints := StartPoints(&field)
|
||||||
|
|
||||||
|
var startPointsWaitGroup sync.WaitGroup
|
||||||
|
startPointsWaitGroup.Add(len(startPoints))
|
||||||
|
|
||||||
|
results := make(chan int)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
startPointsWaitGroup.Wait()
|
||||||
|
close(results)
|
||||||
|
}()
|
||||||
|
|
||||||
|
for _, start := range startPoints {
|
||||||
|
go func(start MovementPoint) {
|
||||||
|
cleanField := ReadField(filename)
|
||||||
|
cleanField.StartTraversal(start)
|
||||||
|
thisResult := cleanField.CountEnergized()
|
||||||
|
results <- thisResult
|
||||||
|
startPointsWaitGroup.Done()
|
||||||
|
}(start)
|
||||||
|
}
|
||||||
|
|
||||||
|
max := math.MinInt
|
||||||
|
for energized := range results {
|
||||||
|
if energized > max {
|
||||||
|
max = energized
|
||||||
|
log.Println("found new max: ", max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Println(field.String())
|
||||||
|
// field.StartTraversal()
|
||||||
|
|
||||||
|
// fmt.Println(field.ShowEnergyzed())
|
||||||
|
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartPoints(f *Field) []MovementPoint {
|
||||||
|
result := make([]MovementPoint, 0)
|
||||||
|
|
||||||
|
for rowNum, row := range f.cells {
|
||||||
|
result = append(result,
|
||||||
|
MovementPoint{Row: rowNum, Col: 0, Direction: Rightward},
|
||||||
|
MovementPoint{Row: rowNum, Col: len(row) - 1, Direction: Leftward})
|
||||||
|
}
|
||||||
|
|
||||||
|
for colNum, _ := range f.cells[0] {
|
||||||
|
result = append(result,
|
||||||
|
MovementPoint{Row: 0, Col: colNum, Direction: Downward},
|
||||||
|
MovementPoint{Row: len(f.cells) - 1, Col: colNum, Direction: Upward})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// have shared field
|
||||||
|
// running traversal recursive function per ray
|
||||||
|
// exit if going out of field or visiting cell that already had light in this direction
|
||||||
|
// (i.e encountering loop)
|
||||||
|
|
||||||
|
type CellType rune
|
||||||
|
|
||||||
|
const (
|
||||||
|
Empty CellType = '.'
|
||||||
|
SplitterNS = '|'
|
||||||
|
SplitterEW = '-'
|
||||||
|
MirrorBackslash = '\\'
|
||||||
|
MirrorSlash = '/'
|
||||||
|
)
|
||||||
|
|
||||||
|
type Direction int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Upward Direction = iota
|
||||||
|
Downward
|
||||||
|
Leftward
|
||||||
|
Rightward
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cell struct {
|
||||||
|
CellType CellType
|
||||||
|
KnownBeams map[Direction]any
|
||||||
|
}
|
||||||
|
|
||||||
|
type Field struct {
|
||||||
|
cells [][]*Cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Field) isValid(mp MovementPoint) bool {
|
||||||
|
if mp.Row < 0 || mp.Col < 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if mp.Row >= len(f.cells) || len(f.cells) == 0 || mp.Col >= len(f.cells[0]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadField(filename string) Field {
|
||||||
|
result := Field{}
|
||||||
|
bytes, err := os.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprint("cannot read file: ", filename))
|
||||||
|
}
|
||||||
|
text := string(bytes)
|
||||||
|
text = strings.TrimSpace(text)
|
||||||
|
for _, line := range strings.Split(text, "\n") {
|
||||||
|
rowCells := make([]*Cell, 0)
|
||||||
|
for _, symb := range line {
|
||||||
|
rowCells = append(rowCells, &Cell{
|
||||||
|
CellType: CellType(symb),
|
||||||
|
KnownBeams: make(map[Direction]any),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
result.cells = append(result.cells, rowCells)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Field) String() string {
|
||||||
|
result := "\n"
|
||||||
|
for _, row := range f.cells {
|
||||||
|
for _, cell := range row {
|
||||||
|
result += string(cell.CellType)
|
||||||
|
}
|
||||||
|
result += "\n"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Field) ShowEnergyzed() string {
|
||||||
|
result := "\n"
|
||||||
|
for _, row := range f.cells {
|
||||||
|
for _, cell := range row {
|
||||||
|
if len(cell.KnownBeams) > 0 {
|
||||||
|
result += "#"
|
||||||
|
} else {
|
||||||
|
result += string(cell.CellType)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
result += "\n"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type MovementPoint struct {
|
||||||
|
Row, Col int
|
||||||
|
Direction Direction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Field) StartTraversal(startPoint MovementPoint) {
|
||||||
|
reportedVisits := make(chan MovementPoint)
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
go f.RecordVisits(reportedVisits)
|
||||||
|
wg.Add(1)
|
||||||
|
go f.TraverseFrom(startPoint, reportedVisits, &wg)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
close(reportedVisits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Field) CountEnergized() (result int) {
|
||||||
|
for _, row := range f.cells {
|
||||||
|
for _, cell := range row {
|
||||||
|
if len(cell.KnownBeams) > 0 {
|
||||||
|
result += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Field) RecordVisits(reportedPoints <-chan MovementPoint) {
|
||||||
|
for point := range reportedPoints {
|
||||||
|
cell := f.cells[point.Row][point.Col]
|
||||||
|
// log.Printf("recording visit %+v to %+v at row %d col %d\n", point, cell, point.Row, point.Col)
|
||||||
|
cell.KnownBeams[point.Direction] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// starting at point, mark as visited
|
||||||
|
// move (concurrently if required) into next points
|
||||||
|
// ends - when out of the field, or if encountering a cycle
|
||||||
|
func (f *Field) TraverseFrom(current MovementPoint, reportVisits chan<- MovementPoint, wg *sync.WaitGroup) {
|
||||||
|
// log.Printf("> starting traverse through %+v", current)
|
||||||
|
if !f.isValid(current) {
|
||||||
|
log.Println("invalid current ", current, " should be impossible")
|
||||||
|
wg.Done()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cell := f.cells[current.Row][current.Col]
|
||||||
|
_, knownDirection := cell.KnownBeams[current.Direction]
|
||||||
|
if knownDirection {
|
||||||
|
// log.Printf("found cycle at %+v in %+v", current, cell)
|
||||||
|
wg.Done()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reportVisits <- current
|
||||||
|
|
||||||
|
nextPoints := NextPoints(f, current)
|
||||||
|
// log.Printf("for current %+v next are: %+v\n", current, nextPoints)
|
||||||
|
switch len(nextPoints) {
|
||||||
|
case 0:
|
||||||
|
wg.Done()
|
||||||
|
return
|
||||||
|
case 1:
|
||||||
|
f.TraverseFrom(nextPoints[0], reportVisits, wg)
|
||||||
|
return
|
||||||
|
case 2:
|
||||||
|
wg.Add(1)
|
||||||
|
go f.TraverseFrom(nextPoints[0], reportVisits, wg)
|
||||||
|
f.TraverseFrom(nextPoints[1], reportVisits, wg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func NextPoints(f *Field, current MovementPoint) []MovementPoint {
|
||||||
|
cell := f.cells[current.Row][current.Col]
|
||||||
|
nextDirections := cell.CellType.NextDirections(current.Direction)
|
||||||
|
nextCells := make([]MovementPoint, 0)
|
||||||
|
for _, direction := range nextDirections {
|
||||||
|
nextMovementPoint := current.ApplyDirection(direction)
|
||||||
|
if f.isValid(nextMovementPoint) {
|
||||||
|
nextCells = append(nextCells, nextMovementPoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nextCells
|
||||||
|
}
|
||||||
|
|
||||||
|
// value receiver, can safely modify incoming mp
|
||||||
|
// doesn't know about Field dimentions
|
||||||
|
func (mp MovementPoint) ApplyDirection(d Direction) MovementPoint {
|
||||||
|
switch d {
|
||||||
|
case Upward:
|
||||||
|
mp.Row -= 1
|
||||||
|
case Downward:
|
||||||
|
mp.Row += 1
|
||||||
|
case Leftward:
|
||||||
|
mp.Col -= 1
|
||||||
|
case Rightward:
|
||||||
|
mp.Col += 1
|
||||||
|
}
|
||||||
|
mp.Direction = d
|
||||||
|
return mp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ct CellType) NextDirections(currentDirection Direction) (nextDirections []Direction) {
|
||||||
|
switch ct {
|
||||||
|
case Empty:
|
||||||
|
nextDirections = []Direction{currentDirection}
|
||||||
|
case SplitterNS:
|
||||||
|
if currentDirection == Rightward || currentDirection == Leftward {
|
||||||
|
nextDirections = []Direction{Upward, Downward}
|
||||||
|
} else {
|
||||||
|
nextDirections = []Direction{currentDirection}
|
||||||
|
}
|
||||||
|
case SplitterEW:
|
||||||
|
if currentDirection == Downward || currentDirection == Upward {
|
||||||
|
nextDirections = []Direction{Leftward, Rightward}
|
||||||
|
} else {
|
||||||
|
nextDirections = []Direction{currentDirection}
|
||||||
|
}
|
||||||
|
case MirrorBackslash:
|
||||||
|
// mirror symbol is \
|
||||||
|
directionMappings := map[Direction]Direction{
|
||||||
|
Leftward: Upward,
|
||||||
|
Rightward: Downward,
|
||||||
|
Upward: Leftward,
|
||||||
|
Downward: Rightward,
|
||||||
|
}
|
||||||
|
nextDirections = []Direction{directionMappings[currentDirection]}
|
||||||
|
case MirrorSlash:
|
||||||
|
// mirrow symbol is /
|
||||||
|
directionMappings := map[Direction]Direction{
|
||||||
|
Leftward: Downward,
|
||||||
|
Rightward: Upward,
|
||||||
|
Upward: Rightward,
|
||||||
|
Downward: Leftward,
|
||||||
|
}
|
||||||
|
nextDirections = []Direction{directionMappings[currentDirection]}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
\-....|\......|...............................\......-../......./...\........|......|.........................
|
||||||
|
.........-.....-............|.................-......|.\\......-...................-..|...\...................
|
||||||
|
......./.|.............-.....-......................................./................\........\..............
|
||||||
|
....|.-.........\..........|.......--.........../....|\....-.........|................./..-.................|.
|
||||||
|
...-......./...../....\...................-......../\.../...............\.............-.......................
|
||||||
|
...|............\.-......./...........|......-....................-..-.../....../......\...\.../..............
|
||||||
|
..|..|..\.....................\..........|...\.|......................\......|....|....|.\.-......-...|....-..
|
||||||
|
......../........................-......-.............\\.-............................/|........|../..........
|
||||||
|
-..........................|.......-.../..............|...................\................|........-...../...
|
||||||
|
.|............\.//.....-..........-....\......./...........................|........................|.........
|
||||||
|
.............................................-................................\..-.\................/........\
|
||||||
|
........|........................-....\..........-.........-..../....\../....\.\........\.....\.|.............
|
||||||
|
.................\..|...........-...|......../................|.-..........-./...........|.--.................
|
||||||
|
.......................-................\............\..|.....\....\....|\.....\.....-...\.....-.|............
|
||||||
|
..........................\....|.../........../..........//........\\.........................................
|
||||||
|
........................\.|..\........./.........../...||.............../................../.........-........
|
||||||
|
/...........................|.....-..../../........./.\.....................|....../.|.....|..................
|
||||||
|
....................\.../-|..../..................../.....|..............\./.....-.........../.--......../|.|.
|
||||||
|
...-........\.....|......|....|.-............................-.....|./.......-.....-.....|-.....|.............
|
||||||
|
....../............................................./..|....-..................\.....-.................//.....
|
||||||
|
\.........................|....................................................../...../...\.........-..-.....
|
||||||
|
....-../..\\.......-......../...\.................................\....-.............\.........\.....-........
|
||||||
|
............/.........../...........\....................\......../.....\.................................|../
|
||||||
|
.......\.........-....|..-|..|..............\............/.................................\......./..........
|
||||||
|
................./..........................................\...........-|......................./.........\..
|
||||||
|
|.......................-..../-/.......-........\.........................................../..../.......-....
|
||||||
|
.\.............|.........|...--....-..|..-..............................................................|\.-|.
|
||||||
|
.\....\...-\.....|./..........................\..............-......................\.....|...................
|
||||||
|
.....|......./.|......................|.................................\........./..../..........\...........
|
||||||
|
/..-...................|.......|.....-..........|...........\...-............-......|.|...................../.
|
||||||
|
....................\..../.............|............|...............................-....|.-.........\....|...
|
||||||
|
...|\.\.......\......\.....|..|.......|...\........................|.................-..-...........-.........
|
||||||
|
............../\-.|.......-...\..........-............\.../...../..|......\................./............|....
|
||||||
|
..........|............\..../........-.............\./....../.........................../.-...................
|
||||||
|
.-.\/............................./......|....\........|....../............\......-....../.........\..........
|
||||||
|
........./......../../.................\...-.\.........\............./../.....-............\..................
|
||||||
|
\.\.......-..................-........-\.....|....\-............/...\............../................./........
|
||||||
|
.........|.................-......\....\......./....|/................-.....\...........|\......|.............
|
||||||
|
.......|........\...\......................-...--........../......-...........\|...............|..\......|....
|
||||||
|
........\.................\...../....|.|..................\.....................\...........\.....-.-.........
|
||||||
|
.....\/................/...-.-...............\...................................\....|.|.-|................/.
|
||||||
|
.......\............\............\-............/......\....../.........|......-......\..-....-...-.........\..
|
||||||
|
.............../......................................|....\.............../..|................../...-...|....
|
||||||
|
.........\.../../.........................../..-........./.-...\.......-..........|.-...../..../........../...
|
||||||
|
...|.......................|./..................-................\...|.....\.-................\./......\......
|
||||||
|
|..../........|...../...................-./.....-...........|.....................-.......-..-................
|
||||||
|
.../..-.......-...........|..-...............--..............||.../...........................................
|
||||||
|
....|../...\.................../..../-..-...|.-.............\......................-....\.......-.....-.......
|
||||||
|
.\.........-....-.....|........-..............................|.........................................\....|
|
||||||
|
..|......................./.........\.......................\...............-.....././...\..|....-....././....
|
||||||
|
...--.|.......................\..|......\|........-....||../....-........|.........\.......-..../..\....-.....
|
||||||
|
-.\.........\...................-../....|............-.............../.............\......-....\..............
|
||||||
|
............\....-.....\.|...............-.......-.|..............\...........................|..-.../........
|
||||||
|
................................................\.........-....................-.......\......................
|
||||||
|
.\.....\........................|....|......-...........-\...|/...................../.........................
|
||||||
|
///.-..\.........\......./....|..........................\.|/.....................-...........-\....|..|......
|
||||||
|
-...........|.....-/...............................|.....|....................................\......-......\/
|
||||||
|
................\/............................................/.......................-........./.............
|
||||||
|
........\.....-..\..............|....................|.....\........-../....../...........\-.........-........
|
||||||
|
...../......../.........|.\........../.............\.............../......-.........................-\.../.-..
|
||||||
|
.......................\..\......../|...|.....-..........................-.|.......\....................-.....
|
||||||
|
..\......-/........./....|..\.................|...-..../|.................................-...................
|
||||||
|
.............-..........-....../............................................../..........|....................
|
||||||
|
.././.../.........\..\....|....||...............|./....-...-...............|/.......................-.........
|
||||||
|
...............-...../.\.....\............\...............................-.-...........\.............-|......
|
||||||
|
....\..............-............/..\................................\-.....-...........................\......
|
||||||
|
.....-.....|.-.........../.........|...................../..................\..../.......\.-./.............../
|
||||||
|
..\-..-....|................\...../................................|....|.|........./...........|....|........
|
||||||
|
.............|..............................-.\........../....../......\.|.......-.......-....................
|
||||||
|
........................./.............|.|........|..-............-../........-../....|.......|............-..
|
||||||
|
......./.........\.\..\..../.-.-..|./........-.|.............../......./......|....-.-...../...........\......
|
||||||
|
................./.....-....|........-\..\....\...................../....................................../..
|
||||||
|
.|.......|./.../.......|.-..........-................-...........\.......-./......./..........................
|
||||||
|
.......-..............................\.....\..-\/.|.-....................../.............|..........-...-....
|
||||||
|
............/..-..........\..\/.\.../...........-................-..........\.|....|../-....................-.
|
||||||
|
.....\......|.......|................|..\.|......\..-|-..../...........................................\...\..
|
||||||
|
........../-.|........-..-........\......|...\.......\...|................................|......-............
|
||||||
|
..|.......\....../......................||......\........-....\......|............-............/.....\.../....
|
||||||
|
..................../...\.-............\......-........\...............-..\.....|.............................
|
||||||
|
..........|.-....|....|./-.....|................../.......\......-...........././...|-...........|....-.......
|
||||||
|
....../...\................./.....-...................|-................/.-...................|.........|.../.
|
||||||
|
...........................-.................|../..|....../..........-....................../.................
|
||||||
|
......../..\...../.\...\|...../.........\..........................-...\.......\...........\................./
|
||||||
|
......-......|........./.../..|.....................|.......|...-..............-.\.....-./...\.......-..|.\...
|
||||||
|
....|...-....................|....|....|..............\..|-......|...|...........................-............
|
||||||
|
.......................|........-......\-...........-../..................../................./...............
|
||||||
|
.......|....-\.\...|...\..............--...-.......-..|...\........|\.........................-......../....\.
|
||||||
|
...\..........................-.................-......................-......\........-......................
|
||||||
|
..|.....................|.-../-....\....-................|....................../...............|.|.........|.
|
||||||
|
.\/.........-.....\............................|.............|....................\...........................
|
||||||
|
....-....................\....-....-..\.......\....................././......|.......................\........
|
||||||
|
./.......-...............-..............-...-...........................-........|...............\-.......|..|
|
||||||
|
.....-................................/.|....-/...\..-.......-..........|.....-...|..........|................
|
||||||
|
.....-..........................|...-.......|...../.\...-.........-........-\............-....-...../.../.....
|
||||||
|
......./|\...........-...............\......./.........\...................\.....\............../.|.\........\
|
||||||
|
.\/.............|...........................\-|........|..-.....................|.......................|.....
|
||||||
|
/....|..................................|......................\..-\.....|..|......................|....|.....
|
||||||
|
..................................-....../-..............\.........................................-../....\..
|
||||||
|
.......................||......./....................../.../....\.................................\.../.......
|
||||||
|
...............-..........--........\............................../...-/............/..........-.............
|
||||||
|
......../...........|....................-................|..../.............../......./..................\.\.
|
||||||
|
....\.../|..\..........|...........-.......................................................................\..
|
||||||
|
......\...|/..\...............|......\.................../................../....\........../......-..........
|
||||||
|
..............-....\............/.....|../...\....|.|..........\..........|................/..........|.......
|
||||||
|
..../\.......................-................\......-............\./......................|....|..........|..
|
||||||
|
..............|................|\.......\..-.../................/............................|................
|
||||||
|
...................-..................................................-.......|.\.........|...................
|
||||||
|
.................\....|.....\/......-........................\..................|.............................
|
||||||
|
......................................|...........\...-.....|.....|.............../.....|..\.../..............
|
||||||
|
.........../............................/...............|.....................-....\..................-.......
|
6
main.go
6
main.go
|
@ -3,12 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"sunshine.industries/aoc2023/day15"
|
"sunshine.industries/aoc2023/day16"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.Print("> starting run:")
|
log.Print("> starting run:")
|
||||||
|
|
||||||
result := day15.Run()
|
result := day16.Run()
|
||||||
log.Printf("day15 result: %d\n****\n", result)
|
log.Printf("\n\nday16 result: %d\n****\n", result)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue