package main import ( "fmt" "os" ) func main() { if len(os.Args) < 2 { panic("Provide input file") } inputFile := os.Args[1] part1, part2 := solution(inputFile) fmt.Printf("(%s) Part 1: %d\n(%s) Part 2: %d\n", inputFile, part1, inputFile, part2) } type Patroller struct { x, y int direction int walkMap [][]bool height int width int } func solution(inputFile string) (int, int) { var part2 int // Read line by line input, err := os.Open(inputFile) if err != nil { panic(err) } defer input.Close() // patrolMap is a 2D bool array to keep track of the patrol var pX, pY int patrolMap := make([][]bool, 0) for { var line string _, err := fmt.Fscanf(input, "%s\n", &line) if err != nil { break } // Add the line to the patrolMap patrolMap = append(patrolMap, make([]bool, len(line))) for i, c := range line { if c == '#' { patrolMap[len(patrolMap)-1][i] = false } if c == '.' { patrolMap[len(patrolMap)-1][i] = true } if c == '^' { pX = i pY = len(patrolMap) patrolMap[len(patrolMap)-1][i] = true } } } fmt.Println(pX+1, pY+1) steps := 0 escaped := false p := NewPatroller(pX, pY, 0, patrolMap) for { steps++ switch p.direction { case 0: // NORTH if p.y-1 < 0 { escaped = true break } else if !p.walkMap[p.x][p.y-1] { p.turnRight() break } p.y-- case 1: // EAST if p.x+1 >= len(p.walkMap[0]) { escaped = true break } if !p.walkMap[p.x+1][p.y] { p.turnRight() break } p.x++ case 2: // SOUTH if p.y+1 >= len(p.walkMap) { escaped = true break } if !p.walkMap[p.x][p.y+1] { p.turnRight() break } p.y++ case 3: // WEST if p.x-1 < 0 { escaped = true break } if !p.walkMap[p.x-1][p.y] { p.turnRight() break } p.x-- } if escaped { break } } return steps, part2 } func NewPatroller(x, y, direction int, walkMap [][]bool) *Patroller { return &Patroller{ x: x, y: y, direction: direction, walkMap: walkMap, } } func (p *Patroller) turnRight() { p.direction = (p.direction + 1) % 4 }