Nice! Ik moet even kijken wat je precies doet.
Ik heb ondertussen mijn C++ oplossing ook geoptimaliseerd tot O(n) voor deel 1 en O(nm) voor deel 2 (waarbij m de maximale lengte van een bestand/gat is; m=9 voor dit probleem, dus theoretisch is dat ook O(n) is). Het lijkt zelfs iets sneller te zijn dan jouw oplossing:
$ time ./solve2 < aoc-2024-day-09-challenge-3.txt
Reading input took 11ms
Preprocessing took 25ms
Solving part 1 took 35ms
...353327
Solving part 2 took 120ms
...224418
real 0m0.198s
user 0m0.141s
sys 0m0.056s
Het idee hierachter is om m'n vorige aanpak om te keren:
spoiler:In plaats van de gaten te groeperen per grootte, groepeer ik de bestanden per grootte. Vervolgens loop ik van links naar rechts door de schijf heen, en om een gat te vullen pak ik greedily het meest rechter bestand dat in het gat past; dat kan ik in O(9) vinden.
C++ code (overigens bevat dit ook een voorbeeld van hoe je het antwoord correct kunt berekenen zonder 128-bits integer datatype te gebruiken).
Ik vond dit een erg leuk probleem, aangezien er een heleboel niet-triviale manieren zijn om het te optimaliseren! Ik denk dat dat we nu al een stuk of zes hebben gezien: brute force simuleren (wat ik vanochtend gedaan had), de segment tree van @
Robbinb1993, ik had eerst sorted sets en daarna binary heaps, jij hebt nu iets linears blijkbaar, en ik heb weer een andere (bijna) lineaire aanpak.