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