-
Notifications
You must be signed in to change notification settings - Fork 1
/
10.go
75 lines (71 loc) · 2.8 KB
/
10.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package main
import "bufio"
import "os"
import "fmt"
type pos struct { col, row int }
var up = pos{0, -1}; var right = pos{1, 0}; var down = pos{0, 1}; var left = pos{-1, 0}
func main() {
var scanner = bufio.NewScanner(os.Stdin)
var r, rows, cols = 0, 0, 0
var start pos
var grid, loop = make(map[pos]bool, 100000), make(map[pos]bool, 100000)
var set = func(c int, r int) { grid[pos{c, r}] = true; }
// .*. ... .*. .*. ... ... ... .*.
// | -> .*. - -> *** L -> .** J -> **. 7 -> **. F -> .** . -> ... S -> ***
// .*. ... ... ... .*. .*. ... .*.
for scanner.Scan() {
cols = len(scanner.Text())
for c, tile := range scanner.Text() {
switch tile {
case '|': set(c * 3 + 1, r * 3); set(c * 3 + 1, r * 3 + 1); set(c * 3 + 1, r * 3 + 2)
case '-': set(c * 3, r * 3 + 1); set(c * 3 + 1, r * 3 + 1); set(c * 3 + 2, r * 3 + 1)
case 'L': set(c * 3 + 1, r * 3); set(c * 3 + 1, r * 3 + 1); set(c * 3 + 2, r * 3 + 1)
case 'J': set(c * 3 + 1, r * 3); set(c * 3 + 1, r * 3 + 1); set(c * 3, r * 3 + 1)
case '7': set(c * 3, r * 3 + 1); set(c * 3 + 1, r * 3 + 1); set(c * 3 + 1, r * 3 + 2)
case 'F': set(c * 3 + 1, r * 3 + 2); set(c * 3 + 1, r * 3 + 1); set(c * 3 + 2, r * 3 + 1)
case 'S': set(c * 3 + 1, r * 3); set(c * 3 + 1, r * 3 + 1); set(c * 3 + 1, r * 3 + 2);
set(c * 3, r * 3 + 1); set(c * 3 + 2, r * 3 + 1); start = pos{c * 3 + 1, r * 3 + 1}
}
}
r++
}
rows = r
var p = start
var move = func (dir pos) bool {
var dest = pos{p.col + dir.col, p.row + dir.row}
if grid[dest] && !loop[dest] { p = dest; return true }
return false
}
loop[p] = true
if grid[pos{start.col + 2, start.row}] { p = pos{p.col + 1, p.row} } else
if grid[pos{start.col - 2, start.row}] { p = pos{p.col - 1, p.row} } else
if grid[pos{start.col, start.row + 2}] { p = pos{p.col, p.row + 1} } else
if grid[pos{start.col, start.row - 2}] { p = pos{p.col, p.row - 2} }
var moved = true
for moved {
loop[p] = true
moved = move(up) || move(right) || move(down) || move(left)
}
var inner = func (c int, r int) bool {
if loop[pos{c, r}] { return false }
var processed, queue = make(map[pos]bool, 100000), make([]pos, 0, 100000)
queue = append(queue, pos{c, r})
for len(queue) > 0 {
var p = queue[0]; queue = queue[1:]
if processed[p] { continue }
processed[p] = true
if p.col < 0 || p.row < 0 || p.row >= rows * 3 || p.col >= cols * 3 { return false }
var expand = func (dir pos) {
var dest = pos{p.col + dir.col, p.row + dir.row}
if !loop[dest] { queue = append(queue, dest) }
}
expand(up); expand(right); expand(down); expand(left)
}
return true
}
var inners = 0
for r := 0; r < rows; r++ {
for c := 0; c < cols; c++ { if inner(c * 3 + 1, r * 3 + 1) { inners++ } }
}
fmt.Println(len(loop) / 6, inners)
}