aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--src/Day05.kt10
-rw-r--r--src/Day09.kt46
-rw-r--r--src/Utils.kt8
4 files changed, 61 insertions, 9 deletions
diff --git a/README.md b/README.md
index 1f33ce2..32a01b7 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Advent of Code 2021 in Kotlin
![Kotlin](https://img.shields.io/badge/Kotlin-grey?logo=Kotlin)
-![](https://img.shields.io/badge/⭐%20stars-16-yellow)
-![](https://img.shields.io/badge/📅%20days-8-blue)
+![](https://img.shields.io/badge/⭐%20stars-18-yellow)
+![](https://img.shields.io/badge/📅%20days-9-blue)
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