You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.7 KiB
69 lines
1.7 KiB
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
from copy import deepcopy
|
|
|
|
|
|
def compress(mem):
|
|
blocks = deepcopy(mem)
|
|
r = len(blocks) - 1
|
|
for p, b in enumerate(blocks):
|
|
if b == None:
|
|
while blocks[r] == None: r -= 1
|
|
# if you check this before moving it obviously does not work
|
|
if p >= r: break
|
|
blocks[p] = blocks[r]
|
|
blocks[r] = None
|
|
return blocks
|
|
|
|
|
|
def block_compress(free, full, size):
|
|
memory = [None] * size
|
|
for id, pos in reversed(full.items()):
|
|
p, b = pos
|
|
for i in sorted(free.keys()):
|
|
if i >= p: break
|
|
if free[i] < b: continue
|
|
else: p = i
|
|
if p != pos[0]:
|
|
free[p+b] = free[p] - b
|
|
free.pop(p)
|
|
if (pos[0]+b) in free:
|
|
free[pos[0]] = b + free[pos[0]+b]
|
|
free.pop(pos[0]+b)
|
|
else: free[pos[0]] = b
|
|
for j in range (p, p+b): memory[j] = id
|
|
return memory
|
|
|
|
|
|
def checksum(blocks):
|
|
cs = 0
|
|
for p, b in enumerate(blocks):
|
|
if b == None: continue
|
|
cs += p * b
|
|
return cs
|
|
|
|
|
|
if __name__ == '__main__':
|
|
blocks = [int(n) for n in list(open(sys.argv[1]).read().strip('\n'))]
|
|
|
|
memory = [None] * sum(blocks)
|
|
p, id = 0, 0
|
|
free, full = {}, {}
|
|
|
|
for i, b in enumerate(blocks):
|
|
if i % 2 == 0 and b > 0:
|
|
for j in range (p, p+b): memory[j] = id
|
|
full[id] = (p, b)
|
|
id += 1
|
|
else: free[p] = b
|
|
p += b
|
|
|
|
# challenge 1
|
|
res1 = checksum(compress(memory))
|
|
print(f"challenge 1:\n{res1}\n")
|
|
|
|
# challenge 2
|
|
res2 = checksum(block_compress(free, full, sum(blocks)))
|
|
print(f"challenge 2:\n{res2}")
|
|
|
|
|