diff options
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | src/Day09.kt | 11 | ||||
-rw-r--r-- | src/Day11.kt | 50 | ||||
-rw-r--r-- | src/Utils.kt | 15 |
4 files changed, 69 insertions, 13 deletions
@@ -1,7 +1,7 @@ # Advent of Code 2021 in Kotlin  - - + + Welcome to the Advent of Code[^aoc] Kotlin project created by [tchojnacki][github] using the [Advent of Code Kotlin Template][template] delivered by JetBrains. @@ -18,7 +18,7 @@ Welcome to the Advent of Code[^aoc] Kotlin project created by [tchojnacki][githu | Day 8: Seven Segment Search | 🌟 | 🌟 | | Day 9: Smoke Basin | 🌟 | 🌟 | | Day 10: Syntax Scoring | 🌟 | 🌟 | -| Day 11: ??? | | | +| Day 11: Dumbo Octopus | 🌟 | 🌟 | | Day 12: ??? | | | | Day 13: ??? | | | | Day 14: ??? | | | diff --git a/src/Day09.kt b/src/Day09.kt index 0d22610..9fef398 100644 --- a/src/Day09.kt +++ b/src/Day09.kt @@ -1,12 +1,5 @@ -fun parseToMap(input: List<String>): Map<Pos2D, Int> = - input.flatMapIndexed { y, line -> - line.mapIndexed { x, char -> - Pos2D(x, y) to char.toString().toInt() - } - }.toMap() - fun Map<Pos2D, Int>.getLowPoints(): Map<Pos2D, Int> = - filter { (pos, num) -> Pos2D.directions.all { num < getOrDefault(pos + it, 9) } } + filter { (pos, num) -> Pos2D.directions4.all { num < getOrDefault(pos + it, 9) } } fun main() { fun part1(input: List<String>): Int = @@ -17,7 +10,7 @@ fun main() { fun traverseBasin(pos: Pos2D, acc: MutableSet<Pos2D>) { acc.add(pos) - Pos2D.directions + Pos2D.directions4 .map { pos + it } .filter { !acc.contains(it) && map.getOrDefault(it, 9) < 9 } .forEach { traverseBasin(it, acc) } diff --git a/src/Day11.kt b/src/Day11.kt new file mode 100644 index 0000000..9a15344 --- /dev/null +++ b/src/Day11.kt @@ -0,0 +1,50 @@ +fun flashSequence(input: Map<Pos2D, Int>) = sequence { + val map = input.toMutableMap() + + while (true) { + val flashed = mutableSetOf<Pos2D>() + fun canFlash(entry: Map.Entry<Pos2D, Int>): Boolean = entry.value > 9 && !flashed.contains(entry.key) + + // 1) + map.forEach { (pos, energy) -> map[pos] = energy + 1 } + + // 2) + while (map.any(::canFlash)) { + map + .filter(::canFlash) + .forEach { (pos, _) -> + flashed.add(pos) + Pos2D.directions8.map { pos + it }.forEach { + if (map.containsKey(it)) { + map[it] = map[it]!! + 1 + } + } + } + } + + // 3) + flashed.forEach { map[it] = 0 } + + yield(flashed.size) + } +} + +fun main() { + fun part1(input: List<String>): Int = + flashSequence(parseToMap(input)) + .take(100) + .sum() + + fun part2(input: List<String>): Int = + flashSequence(parseToMap(input)) + .indexOfFirst { it == 100 } + 1 + + + val testInput = readInputAsLines("Day11_test") + check(part1(testInput) == 1656) + check(part2(testInput) == 195) + + val input = readInputAsLines("Day11") + println(part1(input)) + println(part2(input)) +} diff --git a/src/Utils.kt b/src/Utils.kt index 492c71d..c0f4f61 100644 --- a/src/Utils.kt +++ b/src/Utils.kt @@ -34,12 +34,25 @@ fun readInputAsBitLists(name: String): List<List<Int>> = data class Pos2D(val x: Int, val y: Int) { companion object { - val directions = listOf(Pos2D(0, 1), Pos2D(1, 0), Pos2D(0, -1), Pos2D(-1, 0)) + val directions4 = listOf(Pos2D(0, 1), Pos2D(1, 0), Pos2D(0, -1), Pos2D(-1, 0)) + val directions8 = directions4 + listOf( + Pos2D(1, 1), + Pos2D(1, -1), + Pos2D(-1, -1), + Pos2D(-1, 1), + ) } operator fun plus(other: Pos2D) = Pos2D(x + other.x, y + other.y) } +fun parseToMap(input: List<String>): Map<Pos2D, Int> = + input.flatMapIndexed { y, line -> + line.mapIndexed { x, char -> + Pos2D(x, y) to char.toString().toInt() + } + }.toMap() + /** * Converts string to md5 hash. * @receiver a string |