60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package day24
|
|
|
|
import (
|
|
"math"
|
|
"tools"
|
|
)
|
|
|
|
func getInputGrid(inp []string) (tools.GridToggle, map[int]tools.Coordinate) {
|
|
grid := tools.NewGridToggle()
|
|
targets := make(map[int]tools.Coordinate)
|
|
|
|
for y, line := range inp {
|
|
for x, c := range line {
|
|
if c == '#' {
|
|
grid.Set(x, y, tools.On)
|
|
} else if c != '.' {
|
|
targets[int(c-48)] = tools.Coordinate{X: x, Y: y}
|
|
}
|
|
}
|
|
}
|
|
|
|
return grid, targets
|
|
}
|
|
|
|
func findShortestPathBetweenNodes(grid tools.GridToggle, targets map[int]tools.Coordinate, startNode int, alreadyVisited tools.Set, pathLen int, part2 bool) int {
|
|
alreadyVisited.Add(startNode)
|
|
minLen := math.MaxInt32
|
|
for node, target := range targets {
|
|
if alreadyVisited.Contains(node) {
|
|
continue
|
|
}
|
|
thisLen := len(grid.GetPathAStar(targets[startNode], target, false)) - 1
|
|
if alreadyVisited.Len() == len(targets)-1 {
|
|
if part2 {
|
|
return thisLen + pathLen + len(grid.GetPathAStar(target, targets[0], false)) - 1
|
|
} else {
|
|
return thisLen + pathLen
|
|
}
|
|
} else {
|
|
thisLen = findShortestPathBetweenNodes(grid, targets, node, alreadyVisited.Copy(), thisLen, part2)
|
|
if thisLen < minLen {
|
|
minLen = thisLen
|
|
}
|
|
}
|
|
}
|
|
return minLen + pathLen
|
|
}
|
|
|
|
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
|
grid, targets := getInputGrid(puzzle.GetInputArray())
|
|
|
|
return findShortestPathBetweenNodes(grid, targets, 0, tools.NewSet(), 0, false)
|
|
}
|
|
|
|
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
|
grid, targets := getInputGrid(puzzle.GetInputArray())
|
|
|
|
return findShortestPathBetweenNodes(grid, targets, 0, tools.NewSet(), 0, true)
|
|
}
|