-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday11.go
127 lines (99 loc) Β· 2.57 KB
/
day11.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
123
124
125
126
127
package day11
import (
"strconv"
"strings"
"github.com/augustoccesar/adventofcode/utils"
)
type Day11 struct{}
func (d *Day11) InputFileName() string { return "input" }
func (d *Day11) PartOne(input string) string {
sMap := buildMap(input)
runIterations(&sMap, 4, 1)
return strconv.Itoa(utils.MatrixCount(sMap)["#"])
}
func (d *Day11) PartTwo(input string) string {
sMap := buildMap(input)
runIterations(&sMap, 5, -1)
return strconv.Itoa(utils.MatrixCount(sMap)["#"])
}
// row, col
var directionModifiers = [][]int{
{0, -1}, // Left
{-1, -1}, // Up Left
{-1, 0}, // Up
{-1, 1}, // Up Right
{0, 1}, // Right
{1, 1}, // Down Right
{1, 0}, // Down
{1, -1}, // Down Left
}
func buildMap(input string) [][]string {
rows := strings.Split(input, "\n")
sMap := make([][]string, len(rows))
for i, rowData := range rows {
row := strings.Split(rowData, "")
sMap[i] = row
}
return sMap
}
func getLineOfSigth(sMap [][]string, rowIdx int, colIdx int, sightLen int) []string {
maxRow := len(sMap) - 1
maxCol := len(sMap[0]) - 1
inSight := []string{}
for _, modifiers := range directionModifiers {
foundSeat := ""
reachedEnd := false
spotsChecked := 0
currRow, currCol := rowIdx, colIdx
// Continue to look further if:
// - Haven't fount a seat yet
// - AND haven't reached the end of the direction
// - AND (have unlimited sight OR haven't reached the sight limit)
for foundSeat == "" && !reachedEnd && (sightLen == -1 || spotsChecked < sightLen) {
currRow, currCol = currRow+modifiers[0], currCol+modifiers[1]
if currRow > maxRow || currCol > maxCol || currRow < 0 || currCol < 0 {
reachedEnd = true
continue
}
item := sMap[currRow][currCol]
if item == "L" || item == "#" {
foundSeat = item
}
spotsChecked++
}
if foundSeat != "" {
inSight = append(inSight, foundSeat)
}
}
return inSight
}
func runIterations(sMap *[][]string, maxOccupied int, sightLen int) {
hadChanges := true
for hadChanges {
nextMap := utils.MatrixDeepCopy(*sMap)
changes := 0
for rowIdx, row := range *sMap {
for colIdx, spot := range row {
if spot == "." {
continue
}
spotsOnSight := getLineOfSigth(*sMap, rowIdx, colIdx, sightLen)
itemsCount := utils.SliceCount(spotsOnSight)
if spot == "L" && itemsCount["#"] == 0 {
nextMap[rowIdx][colIdx] = "#"
changes++
continue
}
if spot == "#" && itemsCount["#"] >= maxOccupied {
nextMap[rowIdx][colIdx] = "L"
changes++
continue
}
}
}
*sMap = nextMap
if changes == 0 {
hadChanges = false
}
}
}