|
| 1 | +package y24 |
| 2 | + |
| 3 | +import common.datastructures.* |
| 4 | +import common.ext.* |
| 5 | +import common.puzzle.* |
| 6 | +import common.util.* |
| 7 | +import java.util.* |
| 8 | +import kotlin.math.* |
| 9 | +import kotlin.system.exitProcess |
| 10 | + |
| 11 | +fun main() = solvePuzzle(year = 2024, day = 7, dryRun = false) { Day7(it) } |
| 12 | + |
| 13 | +class Day7(val input: Input) : Puzzle { |
| 14 | + |
| 15 | + enum class Operator(val s: String, val op: (a: Long, b: Long) -> Long) { |
| 16 | + Add("+", { a, b -> a + b }), |
| 17 | + Multiply("*", { a, b -> a * b }), |
| 18 | + Concatenate("||", {a, b -> "$a$b".toLong() }), |
| 19 | + } |
| 20 | + data class Equation(val testValue: Long, val numbers: List<Long>) |
| 21 | + data class Solution(val operators: List<Operator>) |
| 22 | + |
| 23 | + fun findSolutions(eq: Equation, availableOperators: List<Operator>, i: Int = 1, curTestValue: Long = eq.numbers[0], operators: MutableList<Operator> = mutableListOf()): List<Solution> { |
| 24 | + if (curTestValue > eq.testValue) { |
| 25 | + // No negative numbers, cannot reach testValue anymore. |
| 26 | + return emptyList() |
| 27 | + } |
| 28 | + |
| 29 | + if (i == eq.numbers.size) { |
| 30 | + if (curTestValue == eq.testValue) { |
| 31 | + return listOf(Solution(operators.toList())) |
| 32 | + } |
| 33 | + |
| 34 | + return emptyList() |
| 35 | + } |
| 36 | + |
| 37 | + val num = eq.numbers[i] |
| 38 | + return availableOperators.flatMap { op -> |
| 39 | + val newTestValue = op.op(curTestValue, num) |
| 40 | + |
| 41 | + operators.add(op) |
| 42 | + val solutions = findSolutions(eq, availableOperators, i + 1, newTestValue, operators) |
| 43 | + operators.removeLast() |
| 44 | + solutions |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + private fun parseInput(lines: List<String>): List<Equation> { |
| 49 | + return lines.map { line -> |
| 50 | + val (testValue, numbers) = line.split(": ") |
| 51 | + Equation(testValue.toLong(), numbers.splitToLongs(" ")) |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + override fun solveLevel1(): Any { |
| 56 | + val equations = parseInput(input.lines) |
| 57 | + |
| 58 | + return equations.filter { eq -> |
| 59 | + findSolutions(eq, listOf(Operator.Add, Operator.Multiply)).isNotEmpty() |
| 60 | + }.sumOf { it.testValue } |
| 61 | + } |
| 62 | + |
| 63 | + override fun solveLevel2(): Any { |
| 64 | + val equations = parseInput(input.lines) |
| 65 | + |
| 66 | + return equations.filter { eq -> |
| 67 | + findSolutions(eq, listOf(Operator.Add, Operator.Multiply, Operator.Concatenate)).isNotEmpty() |
| 68 | + }.sumOf { it.testValue } |
| 69 | + } |
| 70 | +} |
0 commit comments