|
@@ -5,6 +5,7 @@ import (
|
|
|
"fmt"
|
|
|
"log"
|
|
|
"os"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
const (
|
|
@@ -19,7 +20,7 @@ type Point struct {
|
|
|
direction int
|
|
|
}
|
|
|
|
|
|
-func (p *Point) move(maze []string, height int, width int) bool {
|
|
|
+func (p *Point) move(maze [][]byte, height int, width int) bool {
|
|
|
switch maze[p.y][p.x] {
|
|
|
case '|':
|
|
|
if p.direction == Up && p.y-1 >= 0 {
|
|
@@ -83,15 +84,68 @@ func (p *Point) move(maze []string, height int, width int) bool {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
-func part1(maze []string) int {
|
|
|
- biggest := 0
|
|
|
+const (
|
|
|
+ verticalAbove = "|7F"
|
|
|
+ verticalBelow = "|LJ"
|
|
|
+ horizontalLeft = "-LF"
|
|
|
+ horizontalRight = "-J7"
|
|
|
+)
|
|
|
+
|
|
|
+func establishS(s Point, maze [][]byte, height int, width int) (byte, Point) {
|
|
|
+ var left, right, up, down bool
|
|
|
+ if s.x-1 >= 0 && strings.Contains(horizontalLeft, string(maze[s.y][s.x-1])) {
|
|
|
+ left = true
|
|
|
+ }
|
|
|
+
|
|
|
+ if s.x+1 < width && strings.Contains(horizontalRight, string(maze[s.y][s.x+1])) {
|
|
|
+ right = true
|
|
|
+ }
|
|
|
+
|
|
|
+ if s.y-1 >= 0 && strings.Contains(verticalAbove, string(maze[s.y-1][s.x])) {
|
|
|
+ up = true
|
|
|
+ }
|
|
|
+
|
|
|
+ if s.y+1 < height && strings.Contains(verticalBelow, string(maze[s.y+1][s.x])) {
|
|
|
+ down = true
|
|
|
+ }
|
|
|
+
|
|
|
+ var char byte
|
|
|
+ if left {
|
|
|
+ if right {
|
|
|
+ char = '-'
|
|
|
+ s.direction = Right
|
|
|
+ } else if up {
|
|
|
+ char = 'J'
|
|
|
+ s.direction = Down
|
|
|
+ } else if down {
|
|
|
+ char = '7'
|
|
|
+ s.direction = Up
|
|
|
+ }
|
|
|
+ } else if right {
|
|
|
+ if up {
|
|
|
+ char = 'L'
|
|
|
+ s.direction = Down
|
|
|
+ } else if down {
|
|
|
+ char = 'F'
|
|
|
+ s.direction = Up
|
|
|
+ }
|
|
|
+ } else if up {
|
|
|
+ char = '|'
|
|
|
+ s.direction = Down
|
|
|
+ }
|
|
|
+
|
|
|
+ return char, s
|
|
|
+}
|
|
|
+
|
|
|
+func part1(maze [][]byte) int {
|
|
|
height := len(maze)
|
|
|
width := len(maze[0])
|
|
|
for y := range maze {
|
|
|
for x := range maze[y] {
|
|
|
- if maze[y][x] == 'F' {
|
|
|
- current := Point{y: y, x: x}
|
|
|
- start := Point{y: y, x: x}
|
|
|
+ if maze[y][x] == 'S' {
|
|
|
+ char, start := establishS(Point{y: y, x: x}, maze, height, width)
|
|
|
+ maze[y][x] = char
|
|
|
+ current := start
|
|
|
steps := 0
|
|
|
for {
|
|
|
if !current.move(maze, height, width) {
|
|
@@ -100,24 +154,20 @@ func part1(maze []string) int {
|
|
|
steps++
|
|
|
|
|
|
if current.x == start.x && current.y == start.y {
|
|
|
- steps /= 2
|
|
|
- if steps > biggest {
|
|
|
- biggest = steps
|
|
|
- }
|
|
|
-
|
|
|
- break
|
|
|
+ return steps / 2
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return biggest
|
|
|
+ return -1
|
|
|
}
|
|
|
|
|
|
-func readInput(file *os.File) []string {
|
|
|
+func readInput(file *os.File) [][]byte {
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
- var maze []string
|
|
|
+ var maze [][]byte
|
|
|
+ width := -1
|
|
|
|
|
|
for scanner.Scan() {
|
|
|
line := scanner.Text()
|
|
@@ -125,7 +175,16 @@ func readInput(file *os.File) []string {
|
|
|
break
|
|
|
}
|
|
|
|
|
|
- maze = append(maze, line)
|
|
|
+ if width < 0 {
|
|
|
+ width = len(line)
|
|
|
+ }
|
|
|
+
|
|
|
+ row := make([]byte, width)
|
|
|
+ for i := range line {
|
|
|
+ row[i] = line[i]
|
|
|
+ }
|
|
|
+
|
|
|
+ maze = append(maze, row)
|
|
|
}
|
|
|
|
|
|
return maze
|