package main
import (
"bufio"
"fmt"
"os"
)
func waitEnter() {
fmt.Printf("Press ENTER to continue\n")
bufio.NewReader(os.Stdin).ReadBytes('\n')
}
var doors = map[byte]Point{
'N': Point{0, -1},
'W': Point{-1, 0},
'E': Point{1, 0},
'S': Point{0, 1},
}
type Puzzle struct {
}
func (p *Puzzle) PrintMap() {
/* for y := 0; y < p.gridH; y++ {
i := y * p.gridW
for x := 0; x < p.gridW; x++ {
c := p.grid[i+x]
if c == 0 {
c = ' '
}
fmt.Printf("%c", c)
}
fmt.Printf("\n")
}
*/
}
type Point struct {
X, Y int
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func (p *Puzzle) Map(directions []byte) {
positions := make([]Point, 0, 100)
distances := make(map[Point]int)
pos := Point{5000, 5000}
prev := pos
for _, c := range directions[1 : len(directions)-1] {
switch c {
case '(':
positions = append(positions, pos)
case ')':
pos, positions = positions[len(positions)-1], positions[:len(positions)-1]
case '|':
pos = positions[len(positions)-1]
default:
target := doors[c]
pos.X += target.X
pos.Y += target.Y
if _, ok := distances[pos]; ok {
distances[pos] = min(distances[pos], distances[prev]+1)
} else {
distances[pos] = distances[prev] + 1
}
}
prev = pos
}
dist := 0
count := 0
for _, d := range distances {
if d > dist {
dist = d
}
if d >= 1000 {
count++
}
}
fmt.Println("Solution 1:", dist, "steps")
fmt.Println("Solution 2:", count, "rooms")
}
func (p *Puzzle) MapFile(filepath string) {
var buf []byte
input, err := os.Open(filepath)
if err != nil {
panic(err.Error())
}
defer input.Close()
scanner := bufio.NewScanner(input)
for scanner.Scan() {
buf = scanner.Bytes()
}
if err := scanner.Err(); err != nil {
panic(err.Error())
}
p.Map(buf)
}
func main() {
// Tests
p := Puzzle{}
p.Map([]byte("^WNE$"))
p.Map([]byte("^ENWWW(NEEE|SSE(EE|N))$"))
p.Map([]byte("^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$"))
p.MapFile("input.txt")
waitEnter()
}