Okay okay, really last optimization on day 9, now beyond what the profiler can reliably measure.

This commit is contained in:
Chris Hodges 2024-12-10 16:36:05 +01:00
parent 4b84ce2803
commit bc1888299b

View File

@ -50,43 +50,53 @@ fun main() {
var isFile = true
var fileId = 0
val freeList = Array<MutableSet<Int>>(10) { TreeSet() }
val fileList = ArrayList<Pair<Int, Pair<Int, Int>>>()
val newFileList = ArrayList<Pair<Int, Pair<Int, Int>>>()
val fileList = ArrayList<Pair<Int, Int>>((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<Pair<Int, Int>?>(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: