Day 10. Part 2 doesn't terminate in time and space yet.
This commit is contained in:
parent
caf82dd7a9
commit
6299b10b85
123
src/aoc2025/Day10.kt
Normal file
123
src/aoc2025/Day10.kt
Normal 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()
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user