diff --git a/src/aoc2024/Day22.kt b/src/aoc2024/Day22.kt new file mode 100644 index 0000000..b1266e4 --- /dev/null +++ b/src/aoc2024/Day22.kt @@ -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): 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): Int { + val normalStrings = ArrayList(2500) + val deltaStrings = ArrayList(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() +}