diff --git a/src/aoc2025/Day10.kt b/src/aoc2025/Day10.kt index 2e844d3..1a10a58 100644 --- a/src/aoc2025/Day10.kt +++ b/src/aoc2025/Day10.kt @@ -1,8 +1,10 @@ package aoc2025 +import calcCanonicalPrimesSieveOfEratosthenes import println import readInput import splitInts +import java.math.BigInteger import java.util.* /* @@ -29,7 +31,6 @@ fun main() { 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)) @@ -93,6 +94,63 @@ fun main() { fun part2(input: List): Int { val machines = parse(input) + val primes = calcCanonicalPrimesSieveOfEratosthenes(10000) + var sumButts = 0 + for (m in machines) { + println() + val maxJoltage = m.joltage.max() + val numBits = 32 - maxJoltage.countLeadingZeroBits() + val bigTarget = m.joltage.foldIndexed(BigInteger.ZERO) { index, acc, i -> acc.plus(BigInteger.valueOf(i.toLong()).shiftLeft(numBits * index)) } + val bigToggles = ArrayList>() + for (t in m.toggles) { + var tt = t + var bigToggle = BigInteger.ZERO + var shift = 0 + while (tt > 0) { + if (tt and 1 != 0) { + bigToggle = bigToggle.plus(BigInteger.ONE.shiftLeft(shift)) + } + shift += numBits + tt = tt shr 1 + } + val maxValue = bigTarget.divide(bigToggle).and(BigInteger.ONE.shiftLeft(numBits).minus(BigInteger.ONE)).toInt() + 1 + println(maxValue) + if (maxValue > 0) { + bigToggles.add(bigToggle to BigInteger.valueOf(maxValue.toLong())) + } + } + var presses = BigInteger.ONE + var leastFingers = Integer.MAX_VALUE + val maxPresses = bigToggles.fold(BigInteger.ONE) { acc, bt -> acc.multiply(bt.second) } + while (presses <= maxPresses) { + var pe = 0 + var pr = presses + var bt = bigTarget + var fingers = 0 + while (pe < bigToggles.size && pr > BigInteger.ZERO) { + val f = pr.mod(bigToggles[pe].second) + fingers += f.toInt() + if (fingers > leastFingers) break + bt = bt.minus(bigToggles[pe].first.multiply(f)) + if (bt <= BigInteger.ZERO) break + pr = pr.divide(bigToggles[pe].second) + pe++ + } + if (bt == BigInteger.ZERO) { + leastFingers = leastFingers.coerceAtMost(fingers) + break + } + presses = presses.plus(BigInteger.ONE) + } + println(leastFingers) + sumButts += leastFingers + } + return sumButts + } + + fun part2old(input: List): Int { + val machines = parse(input) + var sumButts = 0 for (m in machines) { // generate toggles and calculate the global maximum of toggle presses for this toggle @@ -129,12 +187,7 @@ fun main() { // press all buttons regarding their minimal count (if any) for (t in toggles) { - if (pressCount[t.idx] + t.min > t.max || !applyJoltage( - jolts, - t, - times = t.min - ) - ) throw IllegalStateException() + if (pressCount[t.idx] + t.min > t.max || !applyJoltage(jolts, t, times = t.min)) throw IllegalStateException() pressCount[t.idx] += t.min } // this is the starting point for the exhaustive search @@ -151,7 +204,7 @@ fun main() { } for (t in toggles) { if (tc[t.idx] + 2 <= t.max) { - val maxTimes = findMaxButtonPresses(j, t) + val maxTimes = 1//findMaxButtonPresses(j, t) if (maxTimes > 0) { val nj = j.copyOf() if (applyJoltage(nj, t, maxTimes)) { @@ -178,7 +231,7 @@ fun main() { val testInputPart2Result = part2(testInput) println("Part 2 Test: $testInputPart2Result") check(testInputPart1Result == 7) - //check(testInputPart2Result == 33) + check(testInputPart2Result == 33) val input = readInput("aoc2025/Day10") part1(input).println()