aboutsummaryrefslogtreecommitdiff
path: root/aoc-2021-kotlin
diff options
context:
space:
mode:
authortchojnacki <tomaszchojnacki2001@gmail.com>2022-08-14 16:57:25 +0200
committertchojnacki <tomaszchojnacki2001@gmail.com>2022-08-14 16:57:25 +0200
commitee60e254ed7eed4c0624fcd651575726f15f6e29 (patch)
treecfe18acffc41f99a749d843db9bf17aaf1c505fe /aoc-2021-kotlin
parent402ee25e6e63a40e292faf25c9e164ef5688d4a5 (diff)
downloadgleam_aoc2020-ee60e254ed7eed4c0624fcd651575726f15f6e29.tar.gz
gleam_aoc2020-ee60e254ed7eed4c0624fcd651575726f15f6e29.zip
Finish day 22
Diffstat (limited to 'aoc-2021-kotlin')
-rw-r--r--aoc-2021-kotlin/README.md6
-rw-r--r--aoc-2021-kotlin/src/Day19.kt18
-rw-r--r--aoc-2021-kotlin/src/Day22.kt90
-rw-r--r--aoc-2021-kotlin/src/Utils.kt18
4 files changed, 111 insertions, 21 deletions
diff --git a/aoc-2021-kotlin/README.md b/aoc-2021-kotlin/README.md
index 4d07eee..5a5e967 100644
--- a/aoc-2021-kotlin/README.md
+++ b/aoc-2021-kotlin/README.md
@@ -1,7 +1,7 @@
# Advent of Code 2021 in Kotlin
![Kotlin](https://img.shields.io/badge/Kotlin-grey?logo=Kotlin)
-![45/50 stars](https://img.shields.io/badge/🌟%20stars-45/50-orange)
-![23/25 days](https://img.shields.io/badge/📅%20days-23/25-blue)
+![47/50 stars](https://img.shields.io/badge/🌟%20stars-47/50-orange)
+![24/25 days](https://img.shields.io/badge/📅%20days-24/25-blue)
Welcome to the Advent of Code Kotlin project created by [tchojnacki][github] using the
[Advent of Code Kotlin Template][template] delivered by JetBrains.
@@ -31,7 +31,7 @@ Welcome to the Advent of Code Kotlin project created by [tchojnacki][github] usi
| Day 19: Beacon Scanner | 🌟 | 🌟 |
| Day 20: Trench Map | 🌟 | 🌟 |
| Day 21: Dirac Dice | 🌟 | 🌟 |
-| Day 22: Reactor Reboot | | |
+| Day 22: Reactor Reboot | 🌟 | 🌟 |
| Day 23: Amphipod | | |
| Day 24: Arithmetic Logic Unit | 🌟 | 🌟 |
| Day 25: Sea Cucumber | 🌟 | |
diff --git a/aoc-2021-kotlin/src/Day19.kt b/aoc-2021-kotlin/src/Day19.kt
index bcdabac..2092691 100644
--- a/aoc-2021-kotlin/src/Day19.kt
+++ b/aoc-2021-kotlin/src/Day19.kt
@@ -172,24 +172,6 @@ object Day19 {
}
}
- private data class Pos3D(val x: Int, val y: Int, val z: Int) {
- companion object {
- val zero = Pos3D(0, 0, 0)
- val unique = Pos3D(1, 2, 3)
-
- fun fromString(string: String) = string
- .split(",")
- .map(String::toInt)
- .let { Pos3D(it[0], it[1], it[2]) }
- }
-
- operator fun unaryMinus() = Pos3D(-x, -y, -z)
-
- operator fun plus(other: Pos3D) = Pos3D(x + other.x, y + other.y, z + other.z)
-
- operator fun minus(other: Pos3D) = Pos3D(x - other.x, y - other.y, z - other.z)
- }
-
private class Graph(private val adjacencyList: List<Set<Edge>>) {
data class Edge(val destination: Int, val transform: Transform)
diff --git a/aoc-2021-kotlin/src/Day22.kt b/aoc-2021-kotlin/src/Day22.kt
new file mode 100644
index 0000000..687011b
--- /dev/null
+++ b/aoc-2021-kotlin/src/Day22.kt
@@ -0,0 +1,90 @@
+import java.lang.Integer.max
+import java.lang.Integer.min
+
+object Day22 {
+ private val IntRange.width get() = last - first + 1
+
+ private infix fun IntRange.and(other: IntRange) =
+ if (last >= other.first && other.last >= first)
+ max(first, other.first)..min(last, other.last)
+ else
+ null
+
+ data class Cuboid(val x: IntRange, val y: IntRange, val z: IntRange) {
+ val volume get() = x.width.toLong() * y.width.toLong() * z.width.toLong()
+ val cubes
+ get() = sequence {
+ x.forEach { xv -> y.forEach { yv -> z.forEach { zv -> yield(Pos3D(xv, yv, zv)) } } }
+ }
+
+ infix fun and(other: Cuboid): Cuboid? {
+ val x = (x and other.x) ?: return null
+ val y = (y and other.y) ?: return null
+ val z = (z and other.z) ?: return null
+ return Cuboid(x, y, z)
+ }
+
+ operator fun contains(pos: Pos3D) = pos.x in x && pos.y in y && pos.z in z
+ }
+
+ data class RebootStep(val on: Boolean, val cuboid: Cuboid) {
+ companion object {
+ fun readSteps(input: List<String>) = input.asSequence().map { line ->
+ """(on|off) x=(-?\d+)..(-?\d+),y=(-?\d+)..(-?\d+),z=(-?\d+)..(-?\d+)"""
+ .toRegex()
+ .matchEntire(line)
+ ?.destructured
+ ?.let { (action, minX, maxX, minY, maxY, minZ, maxZ) ->
+ RebootStep(
+ when (action) {
+ "on" -> true
+ "off" -> false
+ else -> throw IllegalArgumentException()
+ },
+ Cuboid(
+ minX.toInt()..maxX.toInt(),
+ minY.toInt()..maxY.toInt(),
+ minZ.toInt()..maxZ.toInt()
+ )
+ )
+ } ?: throw IllegalArgumentException()
+ }
+ }
+ }
+
+ fun part1(input: List<String>) = RebootStep.readSteps(input).toList().let { steps ->
+ Cuboid(-50..50, -50..50, -50..50).cubes.sumOf { pos ->
+ if (steps.lastOrNull { pos in it.cuboid }?.on == true) 1L else 0L
+ }
+ }
+
+ fun part2(input: List<String>): Long {
+ val counts = mutableMapOf<Cuboid, Int>()
+
+ RebootStep.readSteps(input).forEach { step ->
+ val countChanges = mutableMapOf<Cuboid, Int>()
+
+ for (key in counts.keys) {
+ val overlap = (step.cuboid and key) ?: continue
+ countChanges.putIfAbsent(overlap, 0)
+ countChanges.merge(overlap, counts[key]!!, Int::minus)
+ }
+
+ if (step.on) countChanges.merge(step.cuboid, 1, Int::plus)
+
+ countChanges.forEach { (key, value) -> counts.merge(key, value, Int::plus) }
+ }
+
+ return counts.map { (cuboid, count) -> cuboid.volume * count }.sum()
+ }
+}
+
+fun main() {
+ val testInput = readInputAsLines("Day22_test")
+ check(Day22.part1(testInput) == 474140L)
+ check(Day22.part2(testInput) == 2758514936282235L)
+
+ val input = readInputAsLines("Day22")
+ println(Day22.part1(input))
+ println(Day22.part2(input))
+}
diff --git a/aoc-2021-kotlin/src/Utils.kt b/aoc-2021-kotlin/src/Utils.kt
index 4f78a1f..2be34ac 100644
--- a/aoc-2021-kotlin/src/Utils.kt
+++ b/aoc-2021-kotlin/src/Utils.kt
@@ -26,6 +26,24 @@ data class Pos2D(val x: Int, val y: Int) {
operator fun minus(other: Pos2D) = Pos2D(x - other.x, y - other.y)
}
+data class Pos3D(val x: Int, val y: Int, val z: Int) {
+ companion object {
+ val zero = Pos3D(0, 0, 0)
+ val unique = Pos3D(1, 2, 3)
+
+ fun fromString(string: String) = string
+ .split(",")
+ .map(String::toInt)
+ .let { Pos3D(it[0], it[1], it[2]) }
+ }
+
+ operator fun unaryMinus() = Pos3D(-x, -y, -z)
+
+ operator fun plus(other: Pos3D) = Pos3D(x + other.x, y + other.y, z + other.z)
+
+ operator fun minus(other: Pos3D) = Pos3D(x - other.x, y - other.y, z - other.z)
+}
+
fun parseToMap(input: List<String>): Map<Pos2D, Int> =
input.flatMapIndexed { y, line ->
line.mapIndexed { x, char ->