From a24bc493232288478751bedb151c5c59726caea6 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Fri, 13 Dec 2024 18:23:30 +0000 Subject: [PATCH] Y2015 D6-7 --- src/main/kotlin/utils/Point.kt | 13 +++ src/main/kotlin/y2015/day06/Day06.kt | 66 +++++++++++++++ src/main/kotlin/y2015/day06/input.txt | Bin 0 -> 9552 bytes src/main/kotlin/y2015/day07/Day07.kt | 101 +++++++++++++++++++++++ src/main/kotlin/y2015/day07/input.txt | Bin 0 -> 5324 bytes src/test/kotlin/y2015/day06/Day06Test.kt | 16 ++++ src/test/kotlin/y2015/day07/Day07Test.kt | 16 ++++ 7 files changed, 212 insertions(+) create mode 100644 src/main/kotlin/y2015/day06/Day06.kt create mode 100644 src/main/kotlin/y2015/day06/input.txt create mode 100644 src/main/kotlin/y2015/day07/Day07.kt create mode 100644 src/main/kotlin/y2015/day07/input.txt create mode 100644 src/test/kotlin/y2015/day06/Day06Test.kt create mode 100644 src/test/kotlin/y2015/day07/Day07Test.kt diff --git a/src/main/kotlin/utils/Point.kt b/src/main/kotlin/utils/Point.kt index f5e182e..529dd70 100644 --- a/src/main/kotlin/utils/Point.kt +++ b/src/main/kotlin/utils/Point.kt @@ -76,3 +76,16 @@ fun Map.traverse(block: (Point, T?) -> Unit) { } } } + +fun pointsInArea(point1: Point, point2: Point): List { + val (minY, maxY) = listOf(point1.y, point2.y).sorted() + val (minX, maxX) = listOf(point1.x, point2.x).sorted() + + return buildList { + (minY..maxY).forEach { y -> + (minX..maxX).forEach { x -> + add(Point(x, y)) + } + } + } +} diff --git a/src/main/kotlin/y2015/day06/Day06.kt b/src/main/kotlin/y2015/day06/Day06.kt new file mode 100644 index 0000000..69b5e80 --- /dev/null +++ b/src/main/kotlin/y2015/day06/Day06.kt @@ -0,0 +1,66 @@ +package y2015.day06 + +import utils.Point +import utils.getInputFile +import utils.pointsInArea + +fun main() { + println("Part one: " + Day06.solvePartOne()) + println("Part two: " + Day06.solvePartTwo()) +} + +object Day06 { + + private val regex = """^(turn on|turn off|toggle) (\d+),(\d+) through (\d+),(\d+)$""".toRegex() + private val input = getInputFile(this::class.java.packageName) + .readLines() + .map { + val (operation, aX, aY, bX, bY) = regex.find(it)!!.destructured + Triple(Operation.fromValue(operation), Point(aX.toInt(), aY.toInt()), Point(bX.toInt(), bY.toInt())) + } + + fun solvePartOne(): Int { + val lights = mutableMapOf() + + input.forEach { (operation, tl, br) -> + pointsInArea(tl, br).forEach { point -> + lights[point] = when (operation) { + Operation.ON -> true + Operation.OFF -> false + Operation.TOGGLE -> !lights.getOrDefault(point, false) + } + } + } + + return lights.values.count { it } + } + + fun solvePartTwo(): Int { + val lights = mutableMapOf() + + input.forEach { (operation, tl, br) -> + pointsInArea(tl, br).forEach { point -> + lights[point] = (lights.getOrDefault(point, 0) + when (operation) { + Operation.ON -> 1 + Operation.OFF -> -1 + Operation.TOGGLE -> 2 + }).coerceAtLeast(0) + } + } + + return lights.values.sum() + } + + enum class Operation { + ON, OFF, TOGGLE; + + companion object { + fun fromValue(value: String) = when (value) { + "turn on" -> ON + "turn off" -> OFF + "toggle" -> TOGGLE + else -> throw IllegalArgumentException("Unknown operation $value") + } + } + } +} diff --git a/src/main/kotlin/y2015/day06/input.txt b/src/main/kotlin/y2015/day06/input.txt new file mode 100644 index 0000000000000000000000000000000000000000..367e35153a0f60794b1cf2a20802534e4325fc9c GIT binary patch literal 9552 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 literal 0 HcmV?d00001 diff --git a/src/main/kotlin/y2015/day07/Day07.kt b/src/main/kotlin/y2015/day07/Day07.kt new file mode 100644 index 0000000..bc9318e --- /dev/null +++ b/src/main/kotlin/y2015/day07/Day07.kt @@ -0,0 +1,101 @@ +package y2015.day07 + +import utils.getInputFile + +fun main() { + println("Part one: " + Day07.solvePartOne()) + println("Part two: " + Day07.solvePartTwo()) +} + +object Day07 { + + private val input: Map = getInputFile(this::class.java.packageName, example = false) + .readLines() + .map { it.split(" -> ") } + .associate { (ins, out) -> + out to when { + "AND" in ins -> { + val (l, r) = ins.split(" AND ") + Operation.And(l, r, out) + } + "OR" in ins -> { + val (l, r) = ins.split(" OR ") + Operation.Or(l, r, out) + } + "LSHIFT" in ins -> { + val (l, r) = ins.split(" LSHIFT ") + Operation.LShift(l, r.toInt(), out) + } + "RSHIFT" in ins -> { + val (l, r) = ins.split(" RSHIFT ") + Operation.RShift(l, r.toInt(), out) + } + "NOT" in ins -> { + val x = ins.removePrefix("NOT ") + Operation.Not(x, out) + } + else -> Operation.Set(ins, out) + } + } + private val wires = mutableMapOf() + + fun solvePartOne(): Int = get("a") + + fun solvePartTwo(): Int { + val p1 = solvePartOne() + wires.clear() + wires["b"] = p1 + return get("a") + } + + private fun get(k: String): Int { + return k.toIntOrNull() ?: wires[k] ?: run { + val v = when (val ins = input[k]!!) { + is Operation.And -> get(ins.a) and get(ins.b) + is Operation.Or -> get(ins.a) or get(ins.b) + is Operation.LShift -> get(ins.a) shl ins.b + is Operation.RShift -> get(ins.a) shr ins.b + is Operation.Not -> 65536 + get(ins.a).inv() + is Operation.Set -> get(ins.v) + } + wires[k] = v + v + } + } + + sealed interface Operation { + data class And( + val a: String, + val b: String, + val out: String, + ) : Operation + + data class Or( + val a: String, + val b: String, + val out: String, + ) : Operation + + data class LShift( + val a: String, + val b: Int, + val out: String, + ) : Operation + + data class RShift( + val a: String, + val b: Int, + val out: String, + ) : Operation + + data class Not( + val a: String, + val out: String, + ) : Operation + + data class Set( + val v: String, + val out: String, + ) : Operation + } +} diff --git a/src/main/kotlin/y2015/day07/input.txt b/src/main/kotlin/y2015/day07/input.txt new file mode 100644 index 0000000000000000000000000000000000000000..b75880874bc43dfe278f5ed47b7b6dd34ce35211 GIT binary patch literal 5324 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