Day 10. Part 2 doesn't terminate in time and space yet.

This commit is contained in:
Chris Hodges 2025-12-10 07:44:08 +01:00
parent caf82dd7a9
commit 6299b10b85

123
src/aoc2025/Day10.kt Normal file
View File

@ -0,0 +1,123 @@
package aoc2025
import println
import readInput
import splitInts
import java.util.*
/*
--- Day 10: Factory ---
https://adventofcode.com/2025/day/10
*/
fun main() {
val inlineTestInput = """
[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}
[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}
"""
data class Machine(val size: Int, val target: Int, val toggles: IntArray, val joltage: IntArray)
fun parse(input: List<String>): ArrayList<Machine> {
val machines = ArrayList<Machine>()
for (i in input) {
val stuff = i.split(" ")
val machSize = stuff[0].length - 2
val target = stuff[0].removeSurrounding("[", "]").foldIndexed(0) { i, acc, ch -> acc + if (ch == '#') (1 shl i) else 0 }
val toggles =
stuff.drop(1).dropLast(1).map { it.removeSurrounding("(", ")").splitInts(",").fold(0) { acc, v -> acc + (1 shl v) } }
.sortedByDescending { it.countOneBits() }
.toIntArray()
val joltages = stuff.last().removeSurrounding("{", "}").splitInts(",").toIntArray()
machines.add(Machine(machSize, target, toggles, joltages))
}
return machines
}
fun part1(input: List<String>): Int {
val machines = parse(input)
var sumButts = 0
for (m in machines) {
val pq = PriorityQueue<Pair<Int, Int>>(compareBy { it.second })
val killSet = HashSet<Int>()
pq.add(0 to 0)
while (pq.isNotEmpty()) {
val (v, bi) = pq.poll()
if (v == m.target) {
sumButts += bi
break
}
killSet.add(v)
for (t in m.toggles) {
val nv = v xor t
if (!killSet.contains(nv)) {
pq.add(nv to bi + 1)
}
}
}
}
return sumButts
}
fun part2(input: List<String>): Int {
val machines = parse(input)
var sumButts = 0
// so this is not working in time and space, needs some clever pruning or prime factoring of button presses to reach the target values
for (m in machines) {
val pq = PriorityQueue(compareBy<Pair<Int, Pair<Int, IntArray>>> { it.second.first }.thenComparing { it.second.second.sum() })
pq.add(0 to (0 to m.joltage))
val bestMap = HashMap<IntArray, Int>()
while (pq.isNotEmpty()) {
val (v, bi) = pq.poll()
if (bi.second.sum() == 0) {
println("${bi.first}")
sumButts += bi.first
break
}
//println("$v ${bi.first} ${bi.second.joinToString(",")}")
for (t in m.toggles) {
val nv = v xor t
val nj = bi.second.copyOf()
var tt = t
var jp = 0
var valid = true
while (tt != 0) {
if (tt and 1 != 0) {
nj[jp]--
if (nj[jp] < 0) {
valid = false
break
}
}
tt = tt shr 1
jp++
}
if (valid) {
val cache = bestMap[nj]
if (cache == null || cache > bi.first + 1) {
val nbj = (bi.first + 1 to nj)
bestMap[nj] = bi.first + 1
pq.add(nv to nbj)
}
}
}
}
}
return sumButts
}
// test if implementation meets criteria from the description, like:
val testInput = inlineTestInput.trim().reader().readLines()
//val testInput = readInput("aoc2025/Day10_test")
val testInputPart1Result = part1(testInput)
println("Part 1 Test: $testInputPart1Result")
val testInputPart2Result = part2(testInput)
println("Part 2 Test: $testInputPart2Result")
check(testInputPart1Result == 7)
check(testInputPart2Result == 33)
val input = readInput("aoc2025/Day10")
part1(input).println()
part2(input).println()
}