#!/usr/bin/env kotlin import java.util.Scanner import java.util.PriorityQueue val scanner = Scanner(System.`in`) class PriorityCache(private val maxSize: Int) { private val cache = mutableMapOf() private val priorityQueue = PriorityQueue>(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(20000) fun getStonesAfter(input: List,iterations: Int, cache: PriorityCache): 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): 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)}")