mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
2017-day19: simple following a 2D path
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/alexchao26/advent-of-code-go/util"
|
||||
)
|
||||
|
||||
// easier to look at this input in the format, but need to remove leading/trailing newlines
|
||||
var example = strings.Trim(`
|
||||
|
|
||||
| +--+
|
||||
A | C
|
||||
F---|----E|--+
|
||||
| | | D
|
||||
+B-+ +--+
|
||||
`, "\n")
|
||||
|
||||
func Test_movePacket(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
wantVisitedChars string
|
||||
wantSteps int
|
||||
}{
|
||||
{"example", example, "ABCDEF", 38},
|
||||
{"actual", util.ReadFile("input.txt"), "EPYDUXANIT", 17544},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotVisitedChars, gotSteps := movePacket(tt.input)
|
||||
if gotVisitedChars != tt.wantVisitedChars {
|
||||
t.Errorf("movePacket() gotVisitedChars = %v, want %v", gotVisitedChars, tt.wantVisitedChars)
|
||||
}
|
||||
if gotSteps != tt.wantSteps {
|
||||
t.Errorf("movePacket() gotSteps = %v, want %v", gotSteps, tt.wantSteps)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user