package day13 import ( "fmt" "strconv" "strings" "tools" ) const mazeHangover int = 10 var favNumber, targetX, targetY int var fullGrid = tools.NewGridToggle() func parseInput(input []string) (favNumber, targetX, targetY int) { favNumber, _ = strconv.Atoi(input[0]) parts := strings.Split(input[1], ",") targetX, _ = strconv.Atoi(parts[0]) targetY, _ = strconv.Atoi(parts[1]) return favNumber, targetX, targetY } func buildMaze(maxX, maxY int) tools.GridToggle { maze := tools.NewGridToggle() for x := 0; x <= maxX; x++ { for y := 0; y <= maxY; y++ { fullGrid.Set(x, y, tools.On) theNumber := int64(x*x + 3*x + 2*x*y + y + y*y + favNumber) binNumber := strconv.FormatInt(theNumber, 2) ones := 0 for _, c := range binNumber { if c == '1' { ones++ } } if ones%2 != 0 { maze.Set(x, y, tools.On) } } } return maze } func printMaze(maze, path tools.GridToggle) { for y := 0; y <= maze.MaxY; y++ { for x := 0; x <= maze.MaxX; x++ { if (x == targetX && y == targetY) || (x == 1 && y == 1) { fmt.Print("X") } else if path.State(x, y) { fmt.Print("O") } else if maze.State(x, y) { fmt.Print("#") } else { fmt.Print(".") } } 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{} { favNumber, targetX, targetY = parseInput(puzzle.GetInputArray()) maze := buildMaze(targetX+mazeHangover, targetY+mazeHangover) path := shortestPathToTarget(maze, tools.NewGridToggle(), 1, 1) printMaze(maze, path) return path.GetOnCount() - 1 } func Part2(puzzle tools.AoCPuzzle) interface{} { return 0 }