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()))
} }
// j0 * bigtoggle[0] + j1 * bigtoggle[1] + ... = bigTarget
// is a Linear Diophantine equation that can be solved with the extended Euclidean algorithm
var gcd = gcdPositive(bigToggles[0], bigToggles[1])
for (i in 2 until bigToggles.size) {
gcd = gcdPositive(gcd, bigToggles[i])
} }
var presses = BigInteger.ONE if (bigTarget % gcd != 0L) throw IllegalStateException()
var leastFingers = Integer.MAX_VALUE
val maxPresses = bigToggles.fold(BigInteger.ONE) { acc, bt -> acc.multiply(bt.second) } val factorMap = HashMap<Long, Long>()
while (presses <= maxPresses) { var good = true
var pe = 0 val primeFactors = primeFactors(bigTarget, sieve)
var pr = presses for (pf in primeFactors) {
var bt = bigTarget val sf = factorMap[pf]
var fingers = 0 val pr = 1000 % pf
while (pe < bigToggles.size && pr > BigInteger.ZERO) { if (sf != null && sf != pr) {
val f = pr.mod(bigToggles[pe].second) good = false
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 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()