-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay9.kt
61 lines (50 loc) · 1.93 KB
/
Day9.kt
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
import java.io.File
fun main() {
part1("src/main/resources/day9sample.txt")
part1("src/main/resources/day9.txt")
part2("src/main/resources/day9sample.txt")
part2("src/main/resources/day9.txt")
}
private typealias HeightMap = List<List<Int>>
data class Elevation(val x: Int, val y: Int, val height: Int)
private operator fun HeightMap.get(c: Pair<Int, Int>) = Elevation(c.first, c.second, this[c.first][c.second])
private fun HeightMap.sequenceOfAll(): Sequence<Elevation> =
generateSequence(this[0 to 0]) { c ->
if(c.y < this[0].indices.last) { this[c.x to c.y+1] }
else if (c.x < this.indices.last) { this[c.x+1 to 0] }
else { null }
}
private fun Elevation.getAdjacent(map: HeightMap): Sequence<Elevation> =
sequenceOf(
(this.x to this.y+1), (this.x to this.y-1),
(this.x+1 to this.y), (this.x-1 to this.y)
).filter {
it.first in (map.indices) && it.second in (map[0].indices)
}.map { map[it] }
private fun HeightMap.findLowPoints(): Sequence<Elevation> =
this.sequenceOfAll().filter { e -> e.getAdjacent(this).all { it.height > e.height } }
private fun part1(inputFile: String) {
File(inputFile).readLines()
.map { it.map { n -> n.digitToInt() } }
.findLowPoints()
.map { e -> e.height + 1 }
.apply { println(this.sum()) }
}
//part 2
private fun Elevation.extendAsBasin(map: HeightMap): Set<Elevation> =
this.getAdjacent(map)
.filter { it.height != 9 && it.height > this.height }
.flatMap { it.extendAsBasin(map) }
.toSet() + setOf(this)
private fun part2(inputFile: String) {
File(inputFile).readLines()
.map { it.map { n -> n.digitToInt() } }
.let { hmap ->
hmap.findLowPoints().map { it.extendAsBasin(hmap) }
}
.map { it.size }
.sortedDescending()
.take(3)
.reduce { acc, n -> acc * n }
.apply { println(this) }
}