Optimized day 9 for no reason, part 2 now runs in about 50ms for really_evil_input.txt.
This commit is contained in:
parent
abb0225d06
commit
4b84ce2803
@ -2,6 +2,7 @@ package aoc2024
|
|||||||
|
|
||||||
import println
|
import println
|
||||||
import readInput
|
import readInput
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/*
|
/*
|
||||||
--- Day 9: Disk Fragmenter ---
|
--- Day 9: Disk Fragmenter ---
|
||||||
@ -45,24 +46,19 @@ fun main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun part2(input: List<String>): Long {
|
fun part2(input: List<String>): Long {
|
||||||
val diskSize = input[0].sumOf { it - '0' }
|
|
||||||
val bitmap = IntArray(diskSize) { 0 }
|
|
||||||
var pos = 0
|
var pos = 0
|
||||||
var isFile = true
|
var isFile = true
|
||||||
var fileId = 0
|
var fileId = 0
|
||||||
val freeList = HashMap<Int, MutableList<Int>>()
|
val freeList = Array<MutableSet<Int>>(10) { TreeSet() }
|
||||||
val fileList = ArrayList<Pair<Int, Pair<Int, Int>>>()
|
val fileList = ArrayList<Pair<Int, Pair<Int, Int>>>()
|
||||||
val newFileList = ArrayList<Pair<Int, Pair<Int, Int>>>()
|
val newFileList = ArrayList<Pair<Int, Pair<Int, Int>>>()
|
||||||
for (c in input[0]) {
|
for (c in input[0]) {
|
||||||
val size = c - '0'
|
val size = c - '0'
|
||||||
if (isFile) {
|
if (isFile) {
|
||||||
if (size == 0) println("Narf!")
|
|
||||||
fileList.add(fileId to (pos to size))
|
fileList.add(fileId to (pos to size))
|
||||||
fileId++
|
fileId++
|
||||||
} else {
|
} else {
|
||||||
if (size > 0) {
|
if (size > 0) freeList[size].add(pos)
|
||||||
freeList.getOrPut(size) { ArrayDeque(0) }.add(pos)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pos += size
|
pos += size
|
||||||
isFile = !isFile
|
isFile = !isFile
|
||||||
@ -70,35 +66,27 @@ fun main() {
|
|||||||
|
|
||||||
for (file in fileList.reversed()) {
|
for (file in fileList.reversed()) {
|
||||||
val (filePos, size) = file.second
|
val (filePos, size) = file.second
|
||||||
var bestList: MutableList<Int>? = null
|
|
||||||
var bestListSize = 0
|
var bestListSize = 0
|
||||||
for (s in size..9) {
|
for (s in size..9) {
|
||||||
val list = freeList[s]
|
val list = freeList[s]
|
||||||
if (list?.isNotEmpty() == true && list[0] < filePos) {
|
val first = list.firstOrNull()
|
||||||
if (bestList == null || list[0] < bestList[0]) {
|
if ((first != null && first < filePos) &&
|
||||||
bestList = list
|
(bestListSize == 0 || first < freeList[bestListSize].first())
|
||||||
|
) {
|
||||||
bestListSize = s
|
bestListSize = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (bestListSize != 0) {
|
||||||
if (bestList != null) {
|
val newPos = freeList[bestListSize].first()
|
||||||
val newPos = bestList.removeAt(0)
|
freeList[bestListSize].remove(newPos)
|
||||||
if (bestListSize > size) {
|
if (bestListSize > size) freeList[bestListSize - size].add(newPos + size)
|
||||||
val remBucket = freeList.getOrPut(bestListSize - size) { ArrayDeque(0) }
|
|
||||||
remBucket.add(newPos + size)
|
|
||||||
remBucket.sort()
|
|
||||||
}
|
|
||||||
newFileList.add(file.first to (newPos to size))
|
newFileList.add(file.first to (newPos to size))
|
||||||
} else {
|
} else {
|
||||||
newFileList.add(file)
|
newFileList.add(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (file in newFileList) {
|
// Gauß to the rescue!
|
||||||
for (i in 0 until file.second.second) {
|
return newFileList.sumOf { it.first * (it.second.first.toLong() * it.second.second + (it.second.second * (it.second.second - 1) / 2)) }
|
||||||
bitmap[i + file.second.first] = file.first
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bitmap.map(Int::toLong).reduceIndexed { index, acc, i -> acc + index * i }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if implementation meets criteria from the description, like:
|
// test if implementation meets criteria from the description, like:
|
||||||
|
Loading…
Reference in New Issue
Block a user