-
Notifications
You must be signed in to change notification settings - Fork 6
/
surface.go
94 lines (77 loc) · 1.89 KB
/
surface.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"fmt"
"github.com/glendc/cgreader"
)
const (
WATER_MASK = 1
GROUP_SHIFT = 1
WATER = 79
)
type waterInfo struct {
value, position uint32
}
func main() {
cgreader.RunStaticPrograms(
cgreader.GetFileList("../../input/surface_%d.txt", 9),
cgreader.GetFileList("../../output/surface_%d.txt", 9),
true,
func(input <-chan string, output chan string) {
var G, h, v, g, o, i, t uint32
var L, H, N, X, Y int
var LINE string
var V rune
var w waterInfo
fmt.Sscanf(<-input, "%d", &L)
fmt.Sscanf(<-input, "%d", &H)
WORLD, GROUPS := make([]uint32, L*H), make(map[uint32][]waterInfo)
for Y = 0; Y < H; Y++ {
LINE = <-input
for X, V = range LINE {
h, v = uint32(Y*L), 0
i = h + uint32(X)
if V == WATER {
if t = i - 1; X != 0 && WORLD[t]&WATER_MASK == 1 {
v = WORLD[t]
}
if t = i - uint32(L); h != 0 && WORLD[t]&WATER_MASK == 1 {
if v&WATER_MASK == 1 {
g, o = v>>GROUP_SHIFT, WORLD[t]>>GROUP_SHIFT
if g != o {
for _, w = range GROUPS[o] {
WORLD[w.position] = v
}
GROUPS[g] = append(GROUPS[g], GROUPS[o]...)
delete(GROUPS, o)
}
} else {
v = WORLD[t]
g = v >> GROUP_SHIFT
}
GROUPS[g] = append(GROUPS[g], waterInfo{v, i})
} else if v&WATER_MASK == 1 {
g = v >> GROUP_SHIFT
GROUPS[g] = append(GROUPS[g], waterInfo{v, i})
} else {
g = G
G++
v = (g << GROUP_SHIFT) | 1
GROUPS[g] = append(GROUPS[g], waterInfo{v, i})
}
WORLD[i] = v
}
}
}
fmt.Sscanf(<-input, "%d", &N)
for ; N > 0; N-- {
fmt.Sscanf(<-input, "%d %d", &X, &Y)
t = uint32(Y*L + X)
if WORLD[t]&WATER_MASK == 0 {
output <- "0\n"
} else {
g = WORLD[t] >> GROUP_SHIFT
output <- fmt.Sprintf("%d\n", len(GROUPS[g]))
}
}
})
}