Skip to content

Commit

Permalink
Solve Day 24 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulWoitaschek committed Dec 24, 2024
1 parent 84eeabd commit fa3a233
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
66 changes: 66 additions & 0 deletions 2024/src/main/kotlin/aoc/year2024/Day24.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package aoc.year2024

import aoc.library.Puzzle

object Day24 : Puzzle<Long, Long>(day = 24) {

override fun solvePart1(input: String): Long {
val (wiresValue, gatesValue) = input.split("\n\n")
val wires = wiresValue.lines().associate {
val (name, value) = it.split(": ")
name to (value == "1")
}.toMutableMap()
val gates = gatesValue.lines().map(Gate::parse)

while (true) {
val solvableGate = gates.firstOrNull { gate ->
gate.left in wires && gate.right in wires && gate.output !in wires
} ?: break
wires[solvableGate.output] = solvableGate.operator(wires.getValue(solvableGate.left), wires.getValue(solvableGate.right))
}

return wires.filterKeys { it.startsWith("z") }
.toSortedMap()
.values
.reversed()
.joinToString("") {
if (it) "1" else "0"
}
.toLong(2)
}

data class Gate(val left: String, val right: String, val operator: Operator, val output: String) {
companion object {
// ntg XOR fgs -> mjb
fun parse(input: String): Gate {
val elements = input.split(" ")
return Gate(elements[0], elements[2], Operator.parse(elements[1]), elements[4])
}
}
}

enum class Operator {
Xor,
Or,
And,
;

operator fun invoke(
left: Boolean,
right: Boolean,
): Boolean = when (this) {
Xor -> left xor right
Or -> left or right
And -> left and right
}

companion object {
fun parse(input: String): Operator = entries.find { it.name.equals(input, ignoreCase = true) }
?: error("Invalid operator=$input")
}
}

override fun solvePart2(input: String): Long {
TODO()
}
}
96 changes: 96 additions & 0 deletions 2024/src/test/kotlin/aoc/year2024/Day24Test.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package aoc.year2024

import aoc.library.solvePart1
import aoc.library.solvePart2
import io.kotest.matchers.longs.shouldBeExactly
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test

class Day24Test {

@Test
fun part1TestInput() {
Day24.solvePart1(
"""
x00: 1
x01: 0
x02: 1
x03: 1
x04: 0
y00: 1
y01: 1
y02: 1
y03: 1
y04: 1
ntg XOR fgs -> mjb
y02 OR x01 -> tnw
kwq OR kpj -> z05
x00 OR x03 -> fst
tgd XOR rvg -> z01
vdt OR tnw -> bfw
bfw AND frj -> z10
ffh OR nrd -> bqk
y00 AND y03 -> djm
y03 OR y00 -> psh
bqk OR frj -> z08
tnw OR fst -> frj
gnj AND tgd -> z11
bfw XOR mjb -> z00
x03 OR x00 -> vdt
gnj AND wpb -> z02
x04 AND y00 -> kjc
djm OR pbm -> qhw
nrd AND vdt -> hwm
kjc AND fst -> rvg
y04 OR y02 -> fgs
y01 AND x02 -> pbm
ntg OR kjc -> kwq
psh XOR fgs -> tgd
qhw XOR tgd -> z09
pbm OR djm -> kpj
x03 XOR y03 -> ffh
x00 XOR y04 -> ntg
bfw OR bqk -> z06
nrd XOR fgs -> wpb
frj XOR qhw -> z04
bqk OR frj -> z07
y03 OR x01 -> nrd
hwm AND bqk -> z03
tgd XOR rvg -> z12
tnw OR pbm -> gnj
""".trimIndent(),
) shouldBeExactly 2024
}

@Test
fun gateParsing() {
Day24.Gate.parse("le XOR ri -> out")
.shouldBe(
Day24.Gate(
left = "le",
right = "ri",
output = "out",
operator = Day24.Operator.Xor,
),
)
}

@Test
fun part1() {
Day24.solvePart1() shouldBeExactly 48063513640678
}

@Test
@Disabled
fun part2TestInput() {
Day24.solvePart2() shouldBeExactly 42
}

@Test
@Disabled
fun part2() {
Day24.solvePart2() shouldBeExactly 42
}
}

0 comments on commit fa3a233

Please sign in to comment.