#!/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}")