/
run.go
107 lines (79 loc) · 2.6 KB
/
run.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
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
func getCellVal(row int, col int, twoDArray [][]string) int {
if row < 0 || col < 0 || row > len(twoDArray)-1 || col > len(twoDArray[row])-1 {
return 10
}
var curCell, _ = strconv.Atoi(twoDArray[row][col])
return curCell
}
func isLowPoint(row int, col int, twoDArray [][]string) bool {
var curCell = getCellVal(row, col, twoDArray)
// check neighbors to determine if this is a low point
// only need to compare adjacent locations
if curCell < getCellVal(row-1, col, twoDArray) &&
curCell < getCellVal(row, col-1, twoDArray) && curCell < getCellVal(row, col+1, twoDArray) &&
curCell < getCellVal(row+1, col, twoDArray) {
return true
}
return false
}
func getBasinSize(row int, col int, twoDArray [][]string) int {
var cellVal int = getCellVal(row, col, twoDArray)
if cellVal >= 9 || cellVal == -1 {
return 0
}
twoDArray[row][col] = strconv.Itoa(-1) // mark cell visited
var northVal = getBasinSize(row-1, col, twoDArray)
var southVal = getBasinSize(row+1, col, twoDArray)
var eastVal = getBasinSize(row, col+1, twoDArray)
var westVal = getBasinSize(row, col-1, twoDArray)
return 1 + northVal + southVal + eastVal + westVal
}
func main() {
file, _ := os.Open("input.txt")
defer file.Close()
var twoDArray [100][]string
var lowPoints [500][3]int // oversized, i know
var startRow = 0
// get all the points into a 2D array
scanner := bufio.NewScanner(file)
for scanner.Scan() {
// could probably optimize and store int instead
twoDArray[startRow] = strings.Split(scanner.Text(), "")
startRow += 1
}
var riskLevelAllLowPoints = 0
var lowPointCounter int = 0
// first determine all the low points and the risk level sum
for i := 0; i < 100; i++ {
var row = twoDArray[i]
if row != nil {
for j := 0; j < len(row); j++ {
if isLowPoint(i, j, twoDArray[:]) {
var lowPoint = getCellVal(i, j, twoDArray[:])
riskLevelAllLowPoints += lowPoint + 1
lowPoints[lowPointCounter] = [3]int{i, j, lowPoint} // store low points
lowPointCounter += 1
}
}
}
}
var basinSizes [300]int
for i, lowPoint := range lowPoints {
if lowPoint != [3]int{0, 0, 0} { // quit after we get "null" entries in this oversized array
basinSizes[i] = getBasinSize(lowPoint[0], lowPoint[1], twoDArray[:])
}
}
fmt.Println("Risk Level of all low points", riskLevelAllLowPoints)
sort.Ints(basinSizes[:]) // cause we only need to top 3
var solution2 int = basinSizes[len(basinSizes)-1] * basinSizes[len(basinSizes)-2] * basinSizes[len(basinSizes)-3]
fmt.Println("Largest 3 basins multiplied ", solution2)
}