def parse_input(s): # Convert the input string into alternating lengths of files and spaces lengths = [int(c) for c in s] # Convert to blocks representation blocks = [] file_id = 0 pos = 0 for i, length in enumerate(lengths): if i % 2 == 0: # File blocks.extend([file_id] * length) file_id += 1 else: # Space blocks.extend([-1] * length) # -1 represents free space return blocks def calculate_checksum(blocks): checksum = 0 for pos, block in enumerate(blocks): if block != -1: # Skip free space checksum += pos * block return checksum def compact_blocks_part1(blocks): result = blocks.copy() while True: # Find rightmost file block right = len(result) - 1 while right >= 0 and result[right] == -1: right -= 1 if right < 0: break # Find leftmost free space left = 0 while left < len(result) and result[left] != -1: left += 1 if left >= right: break # Move one block result[left] = result[right] result[right] = -1 return result def compact_blocks_part2(blocks): result = blocks.copy() # Get unique file IDs in descending order file_ids = sorted(set(x for x in result if x != -1), reverse=True) for file_id in file_ids: # Find all blocks of this file file_blocks = [] start = None for i, block in enumerate(result): if block == file_id: if start is None: start = i file_blocks.append(block) elif start is not None and block != file_id: break if not file_blocks: continue # Remove the file from its current position for i in range(start, start + len(file_blocks)): result[i] = -1 # Find leftmost position where file can fit pos = 0 while pos < len(result): if all(result[i] == -1 for i in range(pos, pos + len(file_blocks)) if i < len(result)): # Place file here for i in range(len(file_blocks)): result[pos + i] = file_id break pos += 1 return result # Read input with open("input.txt", "r") as f: input_data = f.read().strip() # Part 1 blocks = parse_input(input_data) compacted = compact_blocks_part1(blocks) checksum = calculate_checksum(compacted) print(str(checksum)) # Part 2 blocks = parse_input(input_data) compacted = compact_blocks_part2(blocks) checksum = calculate_checksum(compacted) print(str(checksum))