Skip to content

Commit e79e34d

Browse files
committed
Solve part 2 day 9
1 parent 4ebbddc commit e79e34d

File tree

1 file changed

+62
-11
lines changed

1 file changed

+62
-11
lines changed

src/Day9.kt

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,95 @@
11
private const val DAY = 9
22

33
fun main() {
4-
fun part1(input: List<List<Byte>>): Int {
4+
fun part1(input: List<List<Point>>): Int {
55
var sum = 0
66
for (x in input.indices) {
77
for (y in input[0].indices) {
8-
val currentHeight = input[x][y]
9-
if (x > 0 && currentHeight >= input[x-1][y]) {
8+
val currentHeight = input[x][y].height
9+
if (x > 0 && currentHeight >= input[x-1][y].height) {
1010
continue
1111
}
12-
if (y > 0 && currentHeight >= input[x][y-1]) {
12+
if (y > 0 && currentHeight >= input[x][y-1].height) {
1313
continue
1414
}
15-
if (x < input.size - 1 && currentHeight >= input[x+1][y]) {
15+
if (x < input.size - 1 && currentHeight >= input[x+1][y].height) {
1616
continue
1717
}
18-
if (y < input[0].size - 1 && currentHeight >= input[x][y+1]) {
18+
if (y < input[0].size - 1 && currentHeight >= input[x][y+1].height) {
1919
continue
2020
}
2121
sum += currentHeight + 1
2222
}
2323
}
2424
return sum
2525
}
26-
fun part2(input: List<List<Byte>>) = -1
26+
27+
fun part2(input: List<List<Point>>): Int {
28+
val basinSizes = mutableListOf<Int>()
29+
for (x in input.indices) {
30+
for (y in input[0].indices) {
31+
val currentHeight = input[x][y].height
32+
if (x > 0 && currentHeight >= input[x-1][y].height) {
33+
continue
34+
}
35+
if (y > 0 && currentHeight >= input[x][y-1].height) {
36+
continue
37+
}
38+
if (x < input.size - 1 && currentHeight >= input[x+1][y].height) {
39+
continue
40+
}
41+
if (y < input[0].size - 1 && currentHeight >= input[x][y+1].height) {
42+
continue
43+
}
44+
val basinSize = getBasinSize(input, x, y) + 1 // plus low point itself
45+
basinSizes.add(basinSize)
46+
}
47+
}
48+
val biggest = basinSizes.apply {
49+
sort()
50+
reverse()
51+
}.take(3)
52+
return biggest[0] * biggest[1] * biggest[2]
53+
}
2754

2855
// test if implementation meets criteria from the description, like:
2956
val testInput = parseInput(readInput(day = DAY, useTestInput = true))
3057
check(part1(testInput) == 15)
31-
// check(part2(testInput) == 61229)
58+
check(part2(testInput) == 1134)
3259

3360
val input = parseInput(readInput(day = DAY))
3461
println(part1(input))
3562
println(part2(input))
3663
}
3764

38-
private fun parseInput(input: List<String>): List<List<Byte>> {
65+
private fun getBasinSize(input: List<List<Point>>, x: Int, y: Int): Int {
66+
var sum = 0
67+
val currentHeight = input[x][y].height
68+
if (x > 0 && currentHeight < input[x-1][y].height && input[x-1][y].height != 9.toByte() && !input[x-1][y].marked) {
69+
input[x-1][y].marked = true
70+
sum += getBasinSize(input, x - 1, y) + 1
71+
}
72+
if (y > 0 && currentHeight < input[x][y-1].height && input[x][y-1].height != 9.toByte() && !input[x][y-1].marked) {
73+
input[x][y-1].marked = true
74+
sum += getBasinSize(input, x, y - 1) + 1
75+
}
76+
if (x < input.size - 1 && currentHeight < input[x+1][y].height && input[x+1][y].height != 9.toByte() && !input[x+1][y].marked) {
77+
input[x+1][y].marked = true
78+
sum += getBasinSize(input, x + 1, y) + 1
79+
}
80+
if (y < input[0].size - 1 && currentHeight < input[x][y+1].height && input[x][y+1].height != 9.toByte() && !input[x][y+1].marked) {
81+
input[x][y+1].marked = true
82+
sum += getBasinSize(input, x, y + 1) + 1
83+
}
84+
return sum
85+
}
86+
87+
private fun parseInput(input: List<String>): List<List<Point>> {
3988
return input.map {
4089
it.map {
41-
it.toString().toByte()
90+
Point(it.toString().toByte())
4291
}
4392
}
44-
}
93+
}
94+
95+
private class Point(val height: Byte, var marked: Boolean = false)

0 commit comments

Comments
 (0)