day16, example two

This commit is contained in:
efim 2023-12-16 07:33:01 +00:00
parent 8436426d3a
commit ee9c2c1ca0
1 changed files with 67 additions and 19 deletions

View File

@ -3,6 +3,7 @@ package day16
import (
"fmt"
"log"
"math"
"os"
"strings"
"sync"
@ -11,13 +12,63 @@ import (
func Run() int {
fmt.Println("hello from day 16")
log.Println("starting")
field := ReadField("day16/input")
fmt.Println(field.String())
field.StartTraversal()
filename := "day16/example"
field := ReadField(filename)
startPoints := StartPoints(&field)
fmt.Println(field.ShowEnergyzed())
var startPointsWaitGroup sync.WaitGroup
startPointsWaitGroup.Add(len(startPoints))
return field.CountEnergized()
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
@ -53,7 +104,7 @@ type Field struct {
cells [][]*Cell
}
func (f *Field)isValid(mp MovementPoint) bool {
func (f *Field) isValid(mp MovementPoint) bool {
if mp.Row < 0 || mp.Col < 0 {
return false
}
@ -84,7 +135,7 @@ func ReadField(filename string) Field {
return result
}
func (f *Field)String() string {
func (f *Field) String() string {
result := "\n"
for _, row := range f.cells {
for _, cell := range row {
@ -95,7 +146,7 @@ func (f *Field)String() string {
return result
}
func (f *Field)ShowEnergyzed() string {
func (f *Field) ShowEnergyzed() string {
result := "\n"
for _, row := range f.cells {
for _, cell := range row {
@ -117,14 +168,11 @@ type MovementPoint struct {
Direction Direction
}
func (f *Field)StartTraversal() {
func (f *Field) StartTraversal(startPoint MovementPoint) {
reportedVisits := make(chan MovementPoint)
var wg sync.WaitGroup
go f.RecordVisits(reportedVisits)
startPoint := MovementPoint {
Row: 0, Col: 0, Direction: Rightward,
}
wg.Add(1)
go f.TraverseFrom(startPoint, reportedVisits, &wg)
@ -132,7 +180,7 @@ func (f *Field)StartTraversal() {
close(reportedVisits)
}
func (f *Field)CountEnergized() (result int) {
func (f *Field) CountEnergized() (result int) {
for _, row := range f.cells {
for _, cell := range row {
if len(cell.KnownBeams) > 0 {
@ -143,7 +191,7 @@ func (f *Field)CountEnergized() (result int) {
return
}
func (f *Field)RecordVisits(reportedPoints <-chan MovementPoint) {
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)
@ -154,7 +202,7 @@ func (f *Field)RecordVisits(reportedPoints <-chan MovementPoint) {
// 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) {
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")
@ -204,7 +252,7 @@ func NextPoints(f *Field, current MovementPoint) []MovementPoint {
// value receiver, can safely modify incoming mp
// doesn't know about Field dimentions
func (mp MovementPoint)ApplyDirection(d Direction) MovementPoint {
func (mp MovementPoint) ApplyDirection(d Direction) MovementPoint {
switch d {
case Upward:
mp.Row -= 1