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(
|
s.write(
|
||||||
f"""
|
f"""
|
||||||
import re
|
import re
|
||||||
from collections import deque, Counter
|
from collections import deque, Counter, defaultdict
|
||||||
from heapq import heappop, heappush
|
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):
|
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