diff --git a/inputs/day03/sample.txt b/inputs/day03/sample.txt new file mode 100644 index 0000000..2e1a90a --- /dev/null +++ b/inputs/day03/sample.txt @@ -0,0 +1 @@ +xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5)) \ No newline at end of file diff --git a/inputs/day03/sample2.txt b/inputs/day03/sample2.txt new file mode 100644 index 0000000..b774ec9 --- /dev/null +++ b/inputs/day03/sample2.txt @@ -0,0 +1 @@ +xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5)) \ No newline at end of file diff --git a/src/Day03.kt b/src/Day03.kt new file mode 100644 index 0000000..3937ce9 --- /dev/null +++ b/src/Day03.kt @@ -0,0 +1,86 @@ +class Day03( + inputType: String, +) : Day() { + enum class InstructionType { + Do, + Dont, + Mul, + } + + data class Instruction( + val type: InstructionType, + val value: Int, + ) + + companion object { + private val MUL_REGEX = "mul\\((\\d+),(\\d+)\\)".toRegex() + private val OP_REGEX = "(mul\\((\\d+),(\\d+)\\)|do\\(\\)|don't\\(\\))".toRegex() + } + + private val memory: String = readInputAsString(3, inputType) + private var multiplications: List> = listOf() + private var allInstructions: List = listOf() + + override fun precompute() { + multiplications = + MUL_REGEX + .findAll(memory) + .map { + val (x, y) = it.destructured + x.toInt() to y.toInt() + }.toList() + + allInstructions = + OP_REGEX + .findAll(memory) + .map { + val (op, l, r) = it.destructured + + val type = + when { + op.startsWith("mul") -> InstructionType.Mul + op.startsWith("don't") -> InstructionType.Dont + op.startsWith("do") -> InstructionType.Do + else -> error("cannot have other operation") + } + val value = + when (type) { + InstructionType.Mul -> l.toInt() * r.toInt() + else -> 0 + } + + Instruction(type, value) + }.toList() + } + + override fun part1(): Int = multiplications.sumOf { it.first * it.second } + + override fun part2(): Int = + allInstructions + .fold(true to 0) { (running, sum), instr -> + var (running, sum) = running to sum + when (instr.type) { + InstructionType.Do -> { + running = true + } + + InstructionType.Dont -> { + running = false + } + + InstructionType.Mul -> { + if (running) { + sum += instr.value + } + } + } + + running to sum + }.second +} + +fun main() { + Day03("sample").test(161) + Day03("sample2").test(null, 48) + Day03("input").run() +}