diff --git a/src/aoc2024/Day09.kt b/src/aoc2024/Day09.kt index d01488d..d3c6a38 100644 --- a/src/aoc2024/Day09.kt +++ b/src/aoc2024/Day09.kt @@ -50,43 +50,53 @@ fun main() { var isFile = true var fileId = 0 val freeList = Array>(10) { TreeSet() } - val fileList = ArrayList>>() - val newFileList = ArrayList>>() + val fileList = ArrayList>((input[0].length + 1) / 2) for (c in input[0]) { val size = c - '0' if (isFile) { - fileList.add(fileId to (pos to size)) + fileList.add(pos to size) fileId++ - } else { - if (size > 0) freeList[size].add(pos) + } else if (size > 0) { + freeList[size].add(pos) } pos += size isFile = !isFile } - for (file in fileList.reversed()) { - val (filePos, size) = file.second + val newFileList = Array?>(fileList.size) { null } + var revPos = fileList.size + for (file in fileList.asReversed()) { + val (filePos, size) = file var bestListSize = 0 + var bestListPos = 0 for (s in size..9) { val list = freeList[s] - val first = list.firstOrNull() - if ((first != null && first < filePos) && - (bestListSize == 0 || first < freeList[bestListSize].first()) + val firstPos = list.firstOrNull() + if ((firstPos != null && firstPos < filePos) && + (bestListSize == 0 || firstPos < bestListPos) ) { bestListSize = s + bestListPos = firstPos } } if (bestListSize != 0) { val newPos = freeList[bestListSize].first() freeList[bestListSize].remove(newPos) if (bestListSize > size) freeList[bestListSize - size].add(newPos + size) - newFileList.add(file.first to (newPos to size)) + newFileList[--revPos] = newPos to size } else { - newFileList.add(file) + newFileList[--revPos] = file + // stop if not even a size 1 file could be fit + if (size == 1) break } } + while (revPos >= 0) { + newFileList[revPos] = fileList[revPos] + revPos-- + } // Gauß to the rescue! - return newFileList.sumOf { it.first * (it.second.first.toLong() * it.second.second + (it.second.second * (it.second.second - 1) / 2)) } + return newFileList.mapIndexed { index, file -> index * (file!!.first.toLong() * file.second + (file.second * (file.second - 1) / 2)) } + .sum() } // test if implementation meets criteria from the description, like: