This commit is contained in:
Chris Hodges 2024-12-22 07:03:10 +01:00
parent f494b763cf
commit 0cb180ddf3

103
src/aoc2024/Day22.kt Normal file
View File

@ -0,0 +1,103 @@
package aoc2024
import println
import readInput
/*
--- Day 22: Monkey Market ---
https://adventofcode.com/2024/day/22
*/
fun main() {
val inlineTestInput = """
1
10
100
2024
"""
val inlineTestInput2 = """
1
2
3
2024
"""
fun next(number: Int): Int {
val r1 = (number xor (number shl 6)) and 0xff_ff_ff
val r2 = (r1 xor (r1 shr 5)) and 0xff_ff_ff
val r3 = (r2 xor (r2 shl 11)) and 0xff_ff_ff
return r3
}
fun part1(input: List<String>): Long {
var sum = 0L
for (i in input.map(String::toInt)) {
var v = i
for (p in 1..2000) {
v = next(v)
}
sum += v
}
return sum
}
fun part2(input: List<String>): Int {
val normalStrings = ArrayList<String>(2500)
val deltaStrings = ArrayList<String>(2500)
for (i in input.map(String::toInt)) {
val normalString = StringBuffer(2024)
val deltaString = StringBuffer(2024)
var v = i
var lastd = v % 10
normalString.append(lastd)
for (p in 1..2000) {
v = next(v)
val d = v % 10
val delta = d - lastd
normalString.append(d)
deltaString.append('j' + delta)
lastd = d
}
normalStrings.add(normalString.toString())
deltaStrings.add(deltaString.toString())
}
// it's not my fault that brute force is still working
val tokenBuffer = StringBuffer(5)
tokenBuffer.append(" ")
val maxIdx = deltaStrings[0].length - 3
var maxBananas = 0
for (code in 0 until 19 * 19 * 19 * 19) {
tokenBuffer.setCharAt(0, 'a' + (code / (19 * 19 * 19)))
tokenBuffer.setCharAt(1, 'a' + ((code / (19 * 19)) % 19))
tokenBuffer.setCharAt(2, 'a' + ((code / 19) % 19))
tokenBuffer.setCharAt(3, 'a' + ((code % 19)))
var bananas = 0
val token = tokenBuffer.toString()
for (i in deltaStrings.indices) {
val idx = deltaStrings[i].indexOf(token)
if (idx in 0..maxIdx) {
bananas += normalStrings[i][idx + 4].digitToInt()
}
}
maxBananas = maxBananas.coerceAtLeast(bananas)
}
return maxBananas
}
// test if implementation meets criteria from the description, like:
val testInput = inlineTestInput.trim().reader().readLines()
val testInput2 = inlineTestInput2.trim().reader().readLines()
//val testInput = readInput("aoc2024/Day22_test")
val testInputPart1Result = part1(testInput)
println("Part 1 Test: $testInputPart1Result")
val testInputPart2Result = part2(testInput2)
println("Part 2 Test: $testInputPart2Result")
check(testInputPart1Result == 37327623L)
check(testInputPart2Result == 23)
val input = readInput("aoc2024/Day22")
part1(input).println()
part2(input).println()
}