aoc_2024/day11.kts
Logiar c359318235
All checks were successful
Solve / example-action (push) Successful in 6m6s
day 11
2024-12-11 16:42:20 +01:00

65 lines
2.3 KiB
Kotlin
Executable File

#!/usr/bin/env kotlin
import java.util.Scanner
import java.util.PriorityQueue
val scanner = Scanner(System.`in`)
class PriorityCache<K, V>(private val maxSize: Int) {
private val cache = mutableMapOf<K, V>()
private val priorityQueue = PriorityQueue<Pair<K, Int>>(compareBy { it.second }) // Pair(Key, Priority)
fun put(key: K, value: V, priority: Int) {
if (cache.size >= maxSize) {
val leastPriority = priorityQueue.poll() // Remove the lowest-priority item
cache.remove(leastPriority.first)
}
cache[key] = value
priorityQueue.add(Pair(key, priority))
}
fun get(key: K): V? {
return cache[key]
}
fun isCached(key: K): Boolean {
return cache.containsKey(key)
}
}
val priorityCache = PriorityCache<String, Long>(20000)
fun getStonesAfter(input: List<Long>,iterations: Int, cache: PriorityCache<String, Long>): Long {
var sum = 0L
for (i in input) {
sum += getStoneNumber(i, iterations, cache)
println("Done with $i")
}
return sum
}
fun getStoneNumber(number: Long, iterations: Int, cache: PriorityCache<String, Long>): Long {
if (iterations == 0) {
return 1L
} else if (cache.isCached("$iterations-$number")) {
return cache.get("$iterations-$number")!!
} else if (number == 0L) {
val stonesum = getStoneNumber(1, iterations - 1, cache)
cache.put("$iterations-0", stonesum, iterations)
return stonesum
} else if (number.toString().length % 2 == 0) {
val mid = number.toString().length / 2
val left = number.toString().substring(0, mid).toLong()
val right = number.toString().substring(mid).toLong()
val stonesum = getStoneNumber(left, iterations - 1, cache) + getStoneNumber(right, iterations - 1, cache)
cache.put("$iterations-$number", stonesum, iterations)
return stonesum
} else {
val newVal = number * 2024
val stonesum = getStoneNumber(newVal, iterations - 1, cache)
cache.put("$iterations-$number", stonesum, iterations)
return stonesum
}
}
val input = scanner.nextLine().split(" ").map { it.toLong() }
println("First part with 25 iterations: ${getStonesAfter(input, 25, priorityCache)}")
println("Second part with 75 iterations: ${getStonesAfter(input, 75, priorityCache)}")