-
Notifications
You must be signed in to change notification settings - Fork 0
/
part2.go
122 lines (99 loc) · 2.48 KB
/
part2.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"bufio"
"fmt"
"os"
)
func get(world [][]rune, x int, y int) rune {
if y < 0 || x < 0 {
return 0
}
if y >= len(world) {
return 0
}
line := world[y]
if x >= len(line) {
return 0
}
return line[x]
}
func tryAddToBuffer(candidate [2]int, visited map[[2]int]struct{}, buffer *[][2]int) {
if _, inVisited := visited[candidate]; !inVisited {
addToBuffer := true
for _, b := range *buffer {
if b == candidate {
addToBuffer = false
break
}
}
if addToBuffer {
*buffer = append(*buffer, candidate)
}
}
}
func main() {
file, _ := os.Open("full.txt")
defer file.Close()
scanner := bufio.NewScanner(file)
var world [][]rune
height := -1
for scanner.Scan() {
height++
line := scanner.Text()
var worldLine []rune
for _, character := range line {
worldLine = append(worldLine, character)
}
world = append(world, worldLine)
}
sum := 0
visited := make(map[[2]int]struct{})
for y, line := range world {
for x, char := range line {
_, ok := visited[[2]int{x, y}]
if ok {
continue
}
var buffer = [][2]int{{x, y}}
border := 0
skipped := 0
i := 0
for i = 0; i < len(buffer); i++ {
item := buffer[i]
_, ok := visited[item]
if ok {
skipped++
continue
}
visited[item] = struct{}{}
if get(world, item[0]+1, item[1]) == char { // South
candidate := [2]int{item[0] + 1, item[1]}
tryAddToBuffer(candidate, visited, &buffer)
} else if !(get(world, item[0]+1, item[1]+1) != char && get(world, item[0], item[1]+1) == char) {
border++
}
if get(world, item[0]-1, item[1]) == char { // North
candidate := [2]int{item[0] - 1, item[1]}
tryAddToBuffer(candidate, visited, &buffer)
} else if !(get(world, item[0]-1, item[1]-1) != char && get(world, item[0], item[1]-1) == char) {
border++
}
if get(world, item[0], item[1]+1) == char { // East
candidate := [2]int{item[0], item[1] + 1}
tryAddToBuffer(candidate, visited, &buffer)
} else if !(get(world, item[0]+1, item[1]+1) != char && get(world, item[0]+1, item[1]) == char) {
border++
}
if get(world, item[0], item[1]-1) == char { // West
candidate := [2]int{item[0], item[1] - 1}
tryAddToBuffer(candidate, visited, &buffer)
} else if !(get(world, item[0]-1, item[1]-1) != char && get(world, item[0]-1, item[1]) == char) {
border++
}
}
fmt.Println(i-skipped, border, string(char))
sum += (i - skipped) * border
}
}
fmt.Println(sum)
}