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) }