Files
advent-of-code-go/2017/day19/main.go
T
2020-12-19 14:24:51 -05:00

109 lines
2.4 KiB
Go

package main
import (
"flag"
"fmt"
"math"
"regexp"
"strings"
"github.com/alexchao26/advent-of-code-go/util"
)
func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Println("Running part", part)
visitedChars, steps := movePacket(util.ReadFile("./input.txt"))
if part == 1 {
fmt.Println("Output:", visitedChars)
} else {
fmt.Println("Output:", steps)
}
}
var dirs = [4][2]int{
{1, 0}, // down
{0, -1}, // left
{-1, 0}, // up
{0, 1}, // right
}
var pathRegexp = regexp.MustCompile("^[-|+A-Z]$")
var capsRegexp = regexp.MustCompile("^[A-Z]$")
func movePacket(input string) (visitedChars string, steps int) {
grid := parseInput(input)
// finding starting point in first row
var row, col int
for c := 0; c < len(grid[0]); c++ {
if grid[0][c] == "|" {
col = c
break
}
}
// track which index in dirs is the current directions, start facing down
var dirIndex int
// include starting tile...
steps = 1
// basically an infinite loop...
for i := 0; i < math.MaxInt64; i++ {
inFrontVal := getNextValue(grid, row, col, dirs[dirIndex])
if pathRegexp.MatchString(inFrontVal) {
row += dirs[dirIndex][0]
col += dirs[dirIndex][1]
steps++
// also check if it's a letter
if capsRegexp.MatchString(inFrontVal) {
visitedChars += inFrontVal
}
} else if inFrontVal == " " {
// just try to turn right then left, assuming no 3 way intersections...
dirIndex = (dirIndex + 1) % 4
if pathRegexp.MatchString(getNextValue(grid, row, col, dirs[dirIndex])) {
continue
}
// if right isn't a path, then try to turn left from original direction
// i.e. add 2 more & mod
dirIndex = (dirIndex + 2) % 4
if pathRegexp.MatchString(getNextValue(grid, row, col, dirs[dirIndex])) {
continue
}
// can't turn, break out of loop
break
} else {
panic("unhandled char " + inFrontVal)
}
}
return visitedChars, steps
}
func getNextValue(grid [][]string, row, col int, diff [2]int) string {
inFrontRow := row + diff[0]
inFrontCol := col + diff[1]
// if not in bounds, just return a space
if inFrontRow < 0 || inFrontRow >= len(grid) || inFrontCol < 0 || inFrontCol >= len(grid[0]) {
return " "
}
return grid[inFrontRow][inFrontCol]
}
func parseInput(input string) [][]string {
var grid [][]string
for _, line := range strings.Split(input, "\n") {
grid = append(grid, strings.Split(line, ""))
}
return grid
}