aoc2016/day13/day.go
Stefan Harmuth 9bfc7ee244 day13p1
2021-02-19 08:35:50 +01:00

115 lines
2.5 KiB
Go

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
}