day13,p1: utilize new A-Star pathfinder in GridToggle
This commit is contained in:
parent
9bfc7ee244
commit
6868307aed
62
day13/day.go
62
day13/day.go
@ -7,6 +7,11 @@ import (
|
|||||||
"tools"
|
"tools"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type mazeNode struct {
|
||||||
|
x, y, nodeType int // ß = wall, 1 = path, 2 = start, 3 = target
|
||||||
|
neighbours []mazeNode
|
||||||
|
}
|
||||||
|
|
||||||
const mazeHangover int = 10
|
const mazeHangover int = 10
|
||||||
|
|
||||||
var favNumber, targetX, targetY int
|
var favNumber, targetX, targetY int
|
||||||
@ -44,69 +49,34 @@ func buildMaze(maxX, maxY int) tools.GridToggle {
|
|||||||
return maze
|
return maze
|
||||||
}
|
}
|
||||||
|
|
||||||
func printMaze(maze, path tools.GridToggle) {
|
func printMaze(maze tools.GridToggle, path []tools.Coordinate) {
|
||||||
|
pathMap := make(map[tools.Coordinate]int)
|
||||||
|
for i, c := range path {
|
||||||
|
pathMap[c] = i
|
||||||
|
}
|
||||||
for y := 0; y <= maze.MaxY; y++ {
|
for y := 0; y <= maze.MaxY; y++ {
|
||||||
for x := 0; x <= maze.MaxX; x++ {
|
for x := 0; x <= maze.MaxX; x++ {
|
||||||
if (x == targetX && y == targetY) || (x == 1 && y == 1) {
|
if (x == targetX && y == targetY) || (x == 1 && y == 1) {
|
||||||
fmt.Print("X")
|
fmt.Print("X")
|
||||||
} else if path.State(x, y) {
|
} else if _, ok := pathMap[tools.Coordinate{X: x, Y: y}]; ok {
|
||||||
fmt.Print("O")
|
fmt.Print("O")
|
||||||
} else if maze.State(x, y) {
|
} else if !maze.State(x, y) {
|
||||||
fmt.Print("#")
|
|
||||||
} else {
|
|
||||||
fmt.Print(".")
|
fmt.Print(".")
|
||||||
|
} else {
|
||||||
|
fmt.Print("#")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func shortestPathToTarget(maze, visited tools.GridToggle, startX, startY int) tools.GridToggle {
|
|
||||||
minSteps := fullGrid.GetOnCount()
|
|
||||||
var newVisited tools.GridToggle
|
|
||||||
visited.Set(startX, startY, tools.On)
|
|
||||||
origVisited := visited.Copy()
|
|
||||||
|
|
||||||
if startX == targetX && startY == targetY {
|
|
||||||
return visited
|
|
||||||
}
|
|
||||||
|
|
||||||
toCheckList := []tools.Coordinate{
|
|
||||||
{startX - 1, startY},
|
|
||||||
{startX + 1, startY},
|
|
||||||
{startX, startY - 1},
|
|
||||||
{startX, startY + 1},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, toCheck := range toCheckList {
|
|
||||||
if toCheck.X < 0 || toCheck.Y < 0 || toCheck.X > maze.MaxX || toCheck.Y > maze.MaxY {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !maze.State(toCheck.X, toCheck.Y) && !visited.State(toCheck.X, toCheck.Y) {
|
|
||||||
newVisited = shortestPathToTarget(maze, origVisited.Copy(), toCheck.X, toCheck.Y)
|
|
||||||
if newVisited.State(targetX, targetY) && newVisited.GetOnCount() < minSteps {
|
|
||||||
minSteps = newVisited.GetOnCount()
|
|
||||||
visited = newVisited
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if minSteps < fullGrid.GetOnCount() {
|
|
||||||
return visited
|
|
||||||
} else {
|
|
||||||
return fullGrid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||||
favNumber, targetX, targetY = parseInput(puzzle.GetInputArray())
|
favNumber, targetX, targetY = parseInput(puzzle.GetInputArray())
|
||||||
maze := buildMaze(targetX+mazeHangover, targetY+mazeHangover)
|
maze := buildMaze(targetX+mazeHangover, targetY+mazeHangover)
|
||||||
|
path := maze.GetPathAStar(tools.Coordinate{X: 1, Y: 1}, tools.Coordinate{X: targetX, Y: targetY}, false)
|
||||||
path := shortestPathToTarget(maze, tools.NewGridToggle(), 1, 1)
|
|
||||||
printMaze(maze, path)
|
printMaze(maze, path)
|
||||||
|
|
||||||
return path.GetOnCount() - 1
|
return len(path) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user