Day 10 still not working, but math will save me.

This commit is contained in:
Chris Hodges 2025-12-11 07:25:11 +01:00
parent a69be406b1
commit 0192b33570

View File

@ -1,10 +1,13 @@
package aoc2025 package aoc2025
import calcCanonicalPrimesSieveOfEratosthenes import chineseRemainder
import gcdPositive
import primeFactors
import primeSequence
import println import println
import readInput import readInput
import sieveOfErastosthenes
import splitInts import splitInts
import java.math.BigInteger
import java.util.* import java.util.*
/* /*
@ -94,54 +97,55 @@ fun main() {
fun part2(input: List<String>): Int { fun part2(input: List<String>): Int {
val machines = parse(input) val machines = parse(input)
val primes = calcCanonicalPrimesSieveOfEratosthenes(10000) val sieve = sieveOfErastosthenes(10000)
val primes = primeSequence(sieve).take(500).toList()
var sumButts = 0 var sumButts = 0
for (m in machines) { for (m in machines) {
println() println()
val maxJoltage = m.joltage.max() val maxJoltage = m.joltage.max()
val numBits = 32 - maxJoltage.countLeadingZeroBits() val primefactors = primes.dropWhile { it <= maxJoltage }.take(m.size).map { it.toLong() }
val bigTarget = m.joltage.foldIndexed(BigInteger.ZERO) { index, acc, i -> acc.plus(BigInteger.valueOf(i.toLong()).shiftLeft(numBits * index)) } if (primefactors.size != m.size) throw IllegalStateException()
val bigToggles = ArrayList<Pair<BigInteger, BigInteger>>() val bigTarget = m.joltage.foldIndexed(0L) { index, acc, i -> acc.plus(i.toLong() * primefactors[index]) }
val bigToggles = ArrayList<Long>()
for (t in m.toggles) { for (t in m.toggles) {
var tt = t var tt = t
var bigToggle = BigInteger.ZERO var bigToggle = 0L
var shift = 0 var idx = 0
while (tt > 0) { while (tt > 0) {
if (tt and 1 != 0) { if (tt and 1 != 0) {
bigToggle = bigToggle.plus(BigInteger.ONE.shiftLeft(shift)) bigToggle += primefactors[idx]
} }
shift += numBits idx += 1
tt = tt shr 1 tt = tt shr 1
} }
val maxValue = bigTarget.divide(bigToggle).and(BigInteger.ONE.shiftLeft(numBits).minus(BigInteger.ONE)).toInt() + 1 bigToggles.add(bigToggle)
println(maxValue)
if (maxValue > 0) {
bigToggles.add(bigToggle to BigInteger.valueOf(maxValue.toLong()))
}
} }
var presses = BigInteger.ONE
var leastFingers = Integer.MAX_VALUE // j0 * bigtoggle[0] + j1 * bigtoggle[1] + ... = bigTarget
val maxPresses = bigToggles.fold(BigInteger.ONE) { acc, bt -> acc.multiply(bt.second) } // is a Linear Diophantine equation that can be solved with the extended Euclidean algorithm
while (presses <= maxPresses) {
var pe = 0 var gcd = gcdPositive(bigToggles[0], bigToggles[1])
var pr = presses for (i in 2 until bigToggles.size) {
var bt = bigTarget gcd = gcdPositive(gcd, bigToggles[i])
var fingers = 0 }
while (pe < bigToggles.size && pr > BigInteger.ZERO) { if (bigTarget % gcd != 0L) throw IllegalStateException()
val f = pr.mod(bigToggles[pe].second)
fingers += f.toInt() val factorMap = HashMap<Long, Long>()
if (fingers > leastFingers) break var good = true
bt = bt.minus(bigToggles[pe].first.multiply(f)) val primeFactors = primeFactors(bigTarget, sieve)
if (bt <= BigInteger.ZERO) break for (pf in primeFactors) {
pr = pr.divide(bigToggles[pe].second) val sf = factorMap[pf]
pe++ val pr = 1000 % pf
} if (sf != null && sf != pr) {
if (bt == BigInteger.ZERO) { good = false
leastFingers = leastFingers.coerceAtMost(fingers)
break break
} }
presses = presses.plus(BigInteger.ONE) factorMap[pf] = pr
} }
val reducedPairs = factorMap.map { it.value to it.key }.sortedBy { it.second }
val rx = reducedPairs.chineseRemainder()
val leastFingers = 0
println(leastFingers) println(leastFingers)
sumButts += leastFingers sumButts += leastFingers
} }
@ -231,7 +235,7 @@ fun main() {
val testInputPart2Result = part2(testInput) val testInputPart2Result = part2(testInput)
println("Part 2 Test: $testInputPart2Result") println("Part 2 Test: $testInputPart2Result")
check(testInputPart1Result == 7) check(testInputPart1Result == 7)
check(testInputPart2Result == 33) //check(testInputPart2Result == 33)
val input = readInput("aoc2025/Day10") val input = readInput("aoc2025/Day10")
part1(input).println() part1(input).println()