Spaces:
Running
Running
| 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)) |