Solve 2024:9 p1-2 "Disk Fragmenter"

Hard one. Comparing to earlier years, the
difficulty level seems higher than usual. I blame
the LLM hipsters.

This one I asumed, but missed when I tried to
find it:
> "If a block contains free space, skip it instead."

Lucky me.
This commit is contained in:
Anders Englöf Ytterström 2024-12-09 13:30:39 +01:00
parent dc44be89bf
commit 1b6502df7a
2 changed files with 70 additions and 3 deletions

View file

@ -30,11 +30,11 @@ if day_no and name:
s.write(
f"""
import re
from collections import deque, Counter
from collections import deque, Counter, defaultdict
from heapq import heappop, heappush
from itertools import compress, combinations, chain
from itertools import compress, combinations, chain, permutations
from output import matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg
from output import matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg, cw, ccw
def solve(data):

View file

@ -0,0 +1,67 @@
from collections import deque
def solve(data):
blocks_checksum = defrag(data)
files_checksum = defrag(data, True)
return blocks_checksum, files_checksum
def defrag(data, move_files=False):
expected_seq_len = sum(map(int, data[::2]))
seq = dict()
gaps = dict()
q = deque([])
i = 0
for fileid, pair in enumerate(zip(data[::2], data[1::2] + "0")):
size, free = map(int, pair)
q.append((i, fileid, size))
for _ in range(int(size)):
seq[i] = fileid
i += 1
gaps[i] = free
i += int(free)
while q:
i, fileid, size = q.pop()
if move_files:
updated = False
for pos, space in gaps.items():
if pos > i:
continue
if size <= space:
rem = space - size
updated = True
break
if updated:
for k in range(size):
seq[pos + k] = fileid
for k in range(i, i + size):
del seq[k]
del gaps[pos]
gaps[pos + size] = rem
gaps = dict(sorted(gaps.items(), key=lambda x: x[0]))
else:
move = False
for j in range(size):
for k in range(expected_seq_len):
if k not in seq:
seq[k] = fileid
del seq[i + j]
move = True
break
if not move:
break
return sum(
pos * id
for pos, id in enumerate(seq.get(fileid, 0) for fileid in range(max(seq) + 1))
)
if __name__ == "__main__":
with open("./input/09.txt", "r") as f:
inp = f.read().strip()
p1, p2 = solve(inp)
print(p1)
print(p2)