Skip to content

Instantly share code, notes, and snippets.

@bartoszm
Last active December 9, 2021 07:43
Show Gist options
  • Save bartoszm/e56fe996ecea02178459a1f94cdc9e3e to your computer and use it in GitHub Desktop.
Save bartoszm/e56fe996ecea02178459a1f94cdc9e3e to your computer and use it in GitHub Desktop.
AoC2021 Day 9 part 2
package day9
import java.nio.file.Files
import java.nio.file.Path
class Day9b(val inputs: Array<IntArray>) {
val inner = inputs[0].size - 1
val outer = inputs.size - 1
val used = mutableSetOf<Pair<Int, Int>>()
fun solve(): Int {
val basins = sequence {
(0..outer).forEach { iO ->
(0..inner).forEach { iI ->
if(isMinimum(Pair(iO, iI))) {
yield(basin(Pair(iO, iI)))
}
}
}
}
return basins.sortedDescending()
.take(3)
.reduce(Int::times)
}
private fun basin(p:Pair<Int, Int>): Int {
val res = basinPoints(p).toSet()
return res.size + 1
}
private fun basinPoints(p: Pair<Int,Int>): List<Pair<Int, Int>> {
if(used.contains(p)) return listOf()
used.add(p)
val neighbors = neighbours(p)
.filter { inBasin(it) }
.toList() - used
return neighbors + neighbors.flatMap { basinPoints(it) }
}
private fun inBasin(v:Pair<Int, Int>) = inputs[v.first][v.second] < 9
private fun isMinimum(p: Pair<Int,Int>): Boolean {
return neighbours(p).map { inputs[it.first][it.second] }
.all { it > inputs[p.first][p.second] }
}
private fun neighbours(p: Pair<Int,Int>): Sequence<Pair<Int,Int>> {
val (o, i) = p
return sequence {
if(i > 0) yield(Pair(o, i - 1))
if(i < inner) yield(Pair(o, i + 1))
if(o > 0) yield(Pair(o - 1, i))
if(o < outer) yield(Pair(o + 1, i))
}
}
}
fun main(args: Array<String>) {
val path = Path.of(args[0])
val inputs = Files.readAllLines(path)
.map{ Day9.parse(it) }.toTypedArray()
println(Day9b(inputs).solve())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment