day16, example two
This commit is contained in:
parent
8436426d3a
commit
ee9c2c1ca0
|
@ -3,6 +3,7 @@ package day16
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -11,13 +12,63 @@ import (
|
||||||
func Run() int {
|
func Run() int {
|
||||||
fmt.Println("hello from day 16")
|
fmt.Println("hello from day 16")
|
||||||
log.Println("starting")
|
log.Println("starting")
|
||||||
field := ReadField("day16/input")
|
filename := "day16/example"
|
||||||
fmt.Println(field.String())
|
field := ReadField(filename)
|
||||||
field.StartTraversal()
|
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
|
// have shared field
|
||||||
|
@ -53,7 +104,7 @@ type Field struct {
|
||||||
cells [][]*Cell
|
cells [][]*Cell
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field)isValid(mp MovementPoint) bool {
|
func (f *Field) isValid(mp MovementPoint) bool {
|
||||||
if mp.Row < 0 || mp.Col < 0 {
|
if mp.Row < 0 || mp.Col < 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -84,7 +135,7 @@ func ReadField(filename string) Field {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field)String() string {
|
func (f *Field) String() string {
|
||||||
result := "\n"
|
result := "\n"
|
||||||
for _, row := range f.cells {
|
for _, row := range f.cells {
|
||||||
for _, cell := range row {
|
for _, cell := range row {
|
||||||
|
@ -95,7 +146,7 @@ func (f *Field)String() string {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field)ShowEnergyzed() string {
|
func (f *Field) ShowEnergyzed() string {
|
||||||
result := "\n"
|
result := "\n"
|
||||||
for _, row := range f.cells {
|
for _, row := range f.cells {
|
||||||
for _, cell := range row {
|
for _, cell := range row {
|
||||||
|
@ -117,14 +168,11 @@ type MovementPoint struct {
|
||||||
Direction Direction
|
Direction Direction
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field)StartTraversal() {
|
func (f *Field) StartTraversal(startPoint MovementPoint) {
|
||||||
reportedVisits := make(chan MovementPoint)
|
reportedVisits := make(chan MovementPoint)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
go f.RecordVisits(reportedVisits)
|
go f.RecordVisits(reportedVisits)
|
||||||
startPoint := MovementPoint {
|
|
||||||
Row: 0, Col: 0, Direction: Rightward,
|
|
||||||
}
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go f.TraverseFrom(startPoint, reportedVisits, &wg)
|
go f.TraverseFrom(startPoint, reportedVisits, &wg)
|
||||||
|
|
||||||
|
@ -132,7 +180,7 @@ func (f *Field)StartTraversal() {
|
||||||
close(reportedVisits)
|
close(reportedVisits)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field)CountEnergized() (result int) {
|
func (f *Field) CountEnergized() (result int) {
|
||||||
for _, row := range f.cells {
|
for _, row := range f.cells {
|
||||||
for _, cell := range row {
|
for _, cell := range row {
|
||||||
if len(cell.KnownBeams) > 0 {
|
if len(cell.KnownBeams) > 0 {
|
||||||
|
@ -143,7 +191,7 @@ func (f *Field)CountEnergized() (result int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field)RecordVisits(reportedPoints <-chan MovementPoint) {
|
func (f *Field) RecordVisits(reportedPoints <-chan MovementPoint) {
|
||||||
for point := range reportedPoints {
|
for point := range reportedPoints {
|
||||||
cell := f.cells[point.Row][point.Col]
|
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)
|
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
|
// starting at point, mark as visited
|
||||||
// move (concurrently if required) into next points
|
// move (concurrently if required) into next points
|
||||||
// ends - when out of the field, or if encountering a cycle
|
// 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)
|
log.Printf("> starting traverse through %+v", current)
|
||||||
if !f.isValid(current) {
|
if !f.isValid(current) {
|
||||||
log.Println("invalid current ", current, " should be impossible")
|
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
|
// value receiver, can safely modify incoming mp
|
||||||
// doesn't know about Field dimentions
|
// doesn't know about Field dimentions
|
||||||
func (mp MovementPoint)ApplyDirection(d Direction) MovementPoint {
|
func (mp MovementPoint) ApplyDirection(d Direction) MovementPoint {
|
||||||
switch d {
|
switch d {
|
||||||
case Upward:
|
case Upward:
|
||||||
mp.Row -= 1
|
mp.Row -= 1
|
||||||
|
|
Loading…
Reference in New Issue