diff options
author | tchojnacki <tomaszchojnacki2001@gmail.com> | 2021-12-09 13:33:22 +0100 |
---|---|---|
committer | tchojnacki <tomaszchojnacki2001@gmail.com> | 2021-12-09 13:33:22 +0100 |
commit | aa6edaafc8ec598197a8c06b6326a0075e78bba4 (patch) | |
tree | 42cf8313614503c20bbe398bcc9cb36abbefb73e | |
parent | 67852df6b6b9bb816dceae94493457764a8a272d (diff) | |
download | gleam_aoc2020-aa6edaafc8ec598197a8c06b6326a0075e78bba4.tar.gz gleam_aoc2020-aa6edaafc8ec598197a8c06b6326a0075e78bba4.zip |
Finish day 9
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | src/Day05.kt | 10 | ||||
-rw-r--r-- | src/Day09.kt | 46 | ||||
-rw-r--r-- | src/Utils.kt | 8 |
4 files changed, 61 insertions, 9 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. @@ -16,7 +16,7 @@ Welcome to the Advent of Code[^aoc] Kotlin project created by [tchojnacki][githu | Day 6: Lanternfish | 🌟 | 🌟 | | Day 7: The Treachery of Whales | 🌟 | 🌟 | | Day 8: Seven Segment Search | 🌟 | 🌟 | -| Day 9: ??? | | | +| Day 9: Smoke Basin | 🌟 | 🌟 | | Day 10: ??? | | | | Day 11: ??? | | | | Day 12: ??? | | | diff --git a/src/Day05.kt b/src/Day05.kt index bc3f1bc..eaa7b66 100644 --- a/src/Day05.kt +++ b/src/Day05.kt @@ -2,14 +2,12 @@ import kotlin.math.absoluteValue import kotlin.math.max import kotlin.math.sign -data class Pos(val x: Int, val y: Int) - -data class Line(val start: Pos, val end: Pos) { +data class Line(val start: Pos2D, val end: Pos2D) { companion object { fun fromString(input: String): Line { val (start, end) = input.split(" -> ").map { coordinateString -> val (x, y) = coordinateString.split(",").map(String::toInt) - Pos(x, y) + Pos2D(x, y) } return Line(start, end) @@ -22,7 +20,7 @@ data class Line(val start: Pos, val end: Pos) { val isDiagonal: Boolean get() = (end.x - start.x).absoluteValue == (end.y - start.y).absoluteValue - val pointSequence: Sequence<Pos> + val pointSequence: Sequence<Pos2D> get() = sequence { val xOffset = end.x - start.x val yOffset = end.y - start.y @@ -31,7 +29,7 @@ data class Line(val start: Pos, val end: Pos) { val x = start.x + s * xOffset.sign val y = start.y + s * yOffset.sign - yield(Pos(x, y)) + yield(Pos2D(x, y)) } } } diff --git a/src/Day09.kt b/src/Day09.kt new file mode 100644 index 0000000..0d22610 --- /dev/null +++ b/src/Day09.kt @@ -0,0 +1,46 @@ +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) } } + +fun main() { + fun part1(input: List<String>): Int = + parseToMap(input).getLowPoints().values.sumOf { it + 1 } + + fun part2(input: List<String>): Int { + val map = parseToMap(input) + + fun traverseBasin(pos: Pos2D, acc: MutableSet<Pos2D>) { + acc.add(pos) + Pos2D.directions + .map { pos + it } + .filter { !acc.contains(it) && map.getOrDefault(it, 9) < 9 } + .forEach { traverseBasin(it, acc) } + } + + return map + .getLowPoints() + .map { + val visited = mutableSetOf<Pos2D>() + traverseBasin(it.key, visited) + visited.size + } + .sortedDescending() + .take(3) + .sum() + } + + + val testInput = readInputAsLines("Day09_test") + check(part1(testInput) == 15) + check(part2(testInput) == 1134) + + val input = readInputAsLines("Day09") + println(part1(input)) + println(part2(input)) +} diff --git a/src/Utils.kt b/src/Utils.kt index 7876c3a..492c71d 100644 --- a/src/Utils.kt +++ b/src/Utils.kt @@ -32,6 +32,14 @@ fun readInputAsBitLists(name: String): List<List<Int>> = readInputAsLines(name) .map { binaryString -> binaryString.toList().map { bit -> bit.toString().toInt() } } +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)) + } + + operator fun plus(other: Pos2D) = Pos2D(x + other.x, y + other.y) +} + /** * Converts string to md5 hash. * @receiver a string |