day17, example attempt 2

This commit is contained in:
efim
2023-12-17 11:13:29 +00:00
parent 41e32d405b
commit 81b8ddc8b0
4 changed files with 248 additions and 13 deletions

View File

@@ -1,6 +1,7 @@
package day17
import (
"container/heap"
"fmt"
"log"
"math"
@@ -27,20 +28,21 @@ func Run() int {
}
end := Coord{field.Height - 1, field.Width - 1}
field.runSearch(startSegment, end)
// field.getNextPathsToCheck(startSegment, end)
foundMin := field.runSearch(startSegment, end)
pathsFoundToEnd := field.Paths[end]
fmt.Println("check visually:")
// pathsFoundToEnd := field.Paths[end]
// fmt.Println("check visually:")
// fmt.Println(field.Paths[end].stringPathSoFar)
minimal := math.MaxInt
for _, path := range pathsFoundToEnd {
fmt.Printf("%+v ; len is %d\n", path, path.totalLength)
if path.totalLength < minimal {
minimal = path.totalLength
}
}
// minimal := math.MaxInt
// for _, path := range pathsFoundToEnd {
// fmt.Printf("%+v ; len is %d\n", path, path.totalLength)
// if path.totalLength < minimal {
// minimal = path.totalLength
// }
// }
// fmt.Printf("i'm looking for %s\n", ExampleResult)
return minimal
return foundMin
}
// let's do dijkstra. it also needs a priority queue
@@ -140,6 +142,7 @@ type PathSegmentEnd struct {
lastDirection Direction
stringPathSoFar string
done bool
score int // lover better
}
func (p *PathSegmentEnd) IsExamplePathPrefix() bool {
@@ -202,6 +205,7 @@ func NewField(filename string) Field {
lastSteps: make(map[Direction]int),
done: true,
lastDirection: Downward, // fake, caution
score: 0,
}
initialPaths := make(map[Coord][]*PathSegmentEnd)
initialPaths[Coord{0, 0}] = []*PathSegmentEnd{&startSegment}
@@ -233,6 +237,8 @@ func (f *Field) continuePathInDirection(curPath PathSegmentEnd, d Direction, fin
lastSteps[d] = curPathStepsIntoThisDirection + 1
}
newScore := newCost + (f.Height - nextCoord.Row) + (f.Width - nextCoord.Col)
return PathSegmentEnd{
endsAt: nextCoord,
totalLength: newCost,
@@ -240,10 +246,38 @@ func (f *Field) continuePathInDirection(curPath PathSegmentEnd, d Direction, fin
lastSteps: lastSteps,
stringPathSoFar: curPath.stringPathSoFar + d.AsSymbol(),
done: nextCoord == finish,
score: newScore,
}
}
func (f *Field) runSearch(curPath PathSegmentEnd, finish Coord) {
func (f *Field) runSearch(startSegment PathSegmentEnd, finish Coord) int {
priorityQueue := make(PriorityQueue, 0)
heap.Init(&priorityQueue)
heap.Push(&priorityQueue, &Item{value: startSegment})
min := math.MaxInt
for len(priorityQueue) > 0 {
currentCheck := heap.Pop(&priorityQueue).(*Item).value
if currentCheck.endsAt == finish {
// log.Printf(">>>> found end %+v with len %d\n", currentCheck, currentCheck.totalLength)
if min > currentCheck.totalLength {
min = currentCheck.totalLength
log.Printf(">>>>>>>> found NEW MIN %+v with len %d\n", currentCheck, currentCheck.totalLength)
}
}
nextPaths := f.getNextPathsToCheck(currentCheck, finish)
for _, next := range nextPaths {
heap.Push(&priorityQueue, &Item{value: next})
}
}
return min
}
func (f *Field) getNextPathsToCheck(curPath PathSegmentEnd, finish Coord) (furtherPathsToCheck []PathSegmentEnd) {
// if len(curPath.stringPathSoFar) > f.Height+f.Width {
// if curPath.IsExamplePathPrefix() {
@@ -262,6 +296,7 @@ func (f *Field) runSearch(curPath PathSegmentEnd, finish Coord) {
// in the end for each vertice there will be map[direction][]PathSegmentEnd
current := curPath.endsAt
if current == finish {
// log.Printf(">> reached end with %+v\n", curPath)
if curPath.IsExamplePathPrefix() {
log.Printf(">> reached end with %+v\n", curPath)
}
@@ -294,6 +329,8 @@ checkingNeighbors:
filteredKnownPaths = append(filteredKnownPaths, &ponentialPath)
f.Paths[ponentialPath.endsAt] = filteredKnownPaths
f.runSearch(ponentialPath, finish)
furtherPathsToCheck = append(furtherPathsToCheck, ponentialPath)
// f.runSearch(ponentialPath, finish)
}
return
}