with open("input") as f: data = f.read() blocks = [] last_file_id = None for idx, count in enumerate(data): block_char = "." if idx % 2 == 1 else str(idx // 2) for ii in range(int(count)): blocks.append(block_char) last_file_id = block_char end_seek_idx = len(blocks) - 1 for file in range(int(last_file_id), -1, -1): file_block = str(file) file_start_block = None file_end_block = None for idx in range(end_seek_idx, -1, -1): if blocks[idx] == file_block: if file_end_block is None: file_end_block = idx else: if file_end_block is not None: file_start_block = idx + 1 end_seek_idx = idx break else: break file_size = file_end_block - file_start_block + 1 empty_block_size = 0 for idx, block_content in enumerate(blocks): if idx > end_seek_idx: break if block_content == ".": empty_block_size += 1 else: empty_block_size = 0 if empty_block_size == file_size: empty_block_start = idx - file_size + 1 for ii in range(file_size): blocks[empty_block_start + ii], blocks[file_start_block + ii] = blocks[file_start_block + ii], blocks[empty_block_start + ii] break def calculate_checksum(blocks: list[str]): checksum = 0 for index, elem in enumerate(blocks): if elem == ".": continue checksum += index * int(elem) return checksum print(calculate_checksum(blocks))