-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path12.go
81 lines (74 loc) · 1.9 KB
/
12.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
package main
import "bufio"
import "os"
import "fmt"
import "slices"
type pos struct {row, col int}
var processed = make(map[pos]bool)
var _map [][]rune
func inside(p pos) bool {
return p.row >= 0 && p.row < len(_map) && p.col >= 0 && p.col < len(_map[p.row]);
}
func expand(t rune, p pos, outsides *int, reg map[pos]bool) {
if !inside(p) || _map[p.row][p.col] != t {
(*outsides)++
return
}
if processed[p] {
return
}
processed[p] = true
reg[p] = true
for _, d := range []pos{{0, 1}, {1, 0}, {0, -1}, {-1, 0}} {
expand(t, pos{p.row + d.row, p.col + d.col}, outsides, reg);
}
}
func region(p pos) (int, int) {
var reg = make(map[pos]bool)
var outsides, sides int
var _type = _map[p.row][p.col]
expand(_type, p, &outsides, reg)
var outDirections = make(map[pos][]pos)
for row, _ := range _map {
for col, _ := range _map[0] {
if !reg[pos{row, col}] {
continue
}
for _, d := range []pos{{0, 1}, {1, 0}, {0, -1}, {-1, 0}} {
var np = pos{row + d.row, col + d.col}
if inside(np) && _map[np.row][np.col] == _type {
continue
}
var ldir, rdir = pos{-d.col, d.row}, pos{d.col, -d.row}
var left = pos{row + ldir.row, col + ldir.col}
var right = pos{row + rdir.row, col + rdir.col}
if !slices.Contains(outDirections[left], d) && !slices.Contains(outDirections[right], d) {
sides++
}
outDirections[pos{row, col}] = append(outDirections[pos{row, col}], d)
}
}
}
return outsides, sides
}
func main() {
var scanner = bufio.NewScanner(os.Stdin)
for scanner.Scan() {
_map = append(_map, []rune(scanner.Text()))
}
var sums [2]int64
var p pos
for p.row, _ = range _map {
for p.col, _ = range _map[p.row] {
if processed[p] {
continue
}
var prev = len(processed)
var perimeter, sides = region(p)
var area = len(processed) - prev
sums[0] += int64(area) * int64(perimeter)
sums[1] += int64(area) * int64(sides)
}
}
fmt.Println(sums)
}