mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
109 lines
2.4 KiB
Go
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
|
|
}
|