diff --git a/src/aoc2024/Day11.kt b/src/aoc2024/Day11.kt new file mode 100644 index 0000000..683614b --- /dev/null +++ b/src/aoc2024/Day11.kt @@ -0,0 +1,71 @@ +package aoc2024 + +import println +import readInput +import splitLongs + +/* +--- Day 11: Plutonian Pebbles --- +https://adventofcode.com/2024/day/11 +*/ +fun main() { + + val inlineTestInput = """ + 125 17 +""" + + val powTenTable = generateSequence(1L) { it * 10L }.take(20).toList().toLongArray() + val lookupTable = HashMap, Long>() + + fun fastCeilLog10(n: Long): Int { + for (i in 1 until powTenTable.size) { + if (powTenTable[i] > n) return i + } + return -1 + } + + fun rec(n: Long, i: Int): Long { + //println("$i $n") + if (i == 0) return 1 + val ll = lookupTable[n to i] + if (ll != null) return ll + val result = if (n == 0L) { + rec(1L, i - 1) + } else { + val size = fastCeilLog10(n) + if (size and 1 == 0) { + val left = n / powTenTable[size / 2] + val right = n % powTenTable[size / 2] + rec(left, i - 1) + rec(right, i - 1) + } else { + rec(n * 2024L, i - 1) + } + } + lookupTable[n to i] = result + return result + } + + fun part1(input: List): Long { + val numbers = input[0].splitLongs() + return numbers.sumOf { rec(it, 25) } + } + + fun part2(input: List): Long { + val numbers = input[0].splitLongs() + return numbers.sumOf { rec(it, 75) } + } + + // test if implementation meets criteria from the description, like: + val testInput = inlineTestInput.trim().reader().readLines() + //val testInput = readInput("aoc2024/Day11_test") + val testInputPart1Result = part1(testInput) + println("Part 1 Test: $testInputPart1Result") + val testInputPart2Result = part2(testInput) + println("Part 2 Test: $testInputPart2Result") + check(testInputPart1Result == 55312L) + //check(testInputPart2Result == 0L) + + val input = readInput("aoc2024/Day11") + part1(input).println() + part2(input).println() +}