60 lines
2.2 KiB
Plaintext
60 lines
2.2 KiB
Plaintext
|
#!/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, Int>(20000)
|
||
|
fun getStonesAfter(input: List<Int>,iterations: Int, cache: PriorityCache<String, Int>): Int {
|
||
|
return input.fold(0) { acc, i -> acc + getStoneNumber(i, iterations, cache) }
|
||
|
}
|
||
|
fun getStoneNumber(number: Int, iterations: Int, cache: PriorityCache<String, Int>): Int {
|
||
|
if (iterations == 0) {
|
||
|
return 1
|
||
|
} else if (cache.isCached("$iterations-$number")) {
|
||
|
return cache.get("$iterations-$number")!!
|
||
|
} else if (number == 0) {
|
||
|
val stonesum = getStonesAfter(listOf(3), 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).toInt()
|
||
|
val right = number.toString().substring(mid).toInt()
|
||
|
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.toInt() }
|
||
|
println("First part with 25 iterations: ${getStonesAfter(input, 25, priorityCache)}")
|
||
|
|
||
|
|