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:
parent
dc44be89bf
commit
1b6502df7a
2 changed files with 70 additions and 3 deletions
|
|
@ -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):
|
||||
|
|
|
|||
67
2024-python/output/day_09.py
Normal file
67
2024-python/output/day_09.py
Normal 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)
|
||||
Loading…
Add table
Reference in a new issue