aoc2016/day24/day.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)
}