-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path06.go
58 lines (53 loc) · 1.47 KB
/
06.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package main
import "bufio"
import "os"
import "strings"
import "fmt"
type pos struct {x, y int}
var _map [][]rune
var directions = []pos{{0, -1}, {1, 0}, {0, 1}, {-1, 0}} // up, right, down, left (in order of 90 degree turns)
// return true if guard stuck in a loop. Second item in returned pair is number of visited points
func loop(guard pos, di int) (bool, int) {
var visited = make(map[pos]bool, 10000)
type vdt struct {p pos; di int}
var visitedDir = make(map[vdt]bool, 10000)
visited[guard] = true
visitedDir[vdt{guard, di}] = true
for {
var next = pos{guard.x + directions[di].x, guard.y + directions[di].y}
if next.x < 0 || next.y < 0 || next.x >= len(_map[guard.y]) || next.y >= len(_map) {
return false, len(visited)
}
if visitedDir[vdt{next, di}] { return true, len(visited) }
if _map[next.y][next.x] == '#' {
di = (di + 1) % 4
} else {
guard = next
}
visited[guard] = true
visitedDir[vdt{guard, di}] = true
}
}
func main() {
var scanner = bufio.NewScanner(os.Stdin)
var guard pos
var y int
for scanner.Scan() {
_map = append(_map, []rune(scanner.Text()))
if p := strings.IndexRune(scanner.Text(), '^'); p > 0 { guard = pos{p, y} }
y++
}
var _, nvisited = loop(guard, 0)
fmt.Print(nvisited)
var nloops int
for y, row := range _map {
for x, c := range row {
if c != '^' && c != '#' {
_map[y][x] = '#'
if isLoop, _ := loop(guard, 0); isLoop { nloops++ }
_map[y][x] = '.'
}
}
}
fmt.Println("", nloops)
}