aoc24/day9/solution2.py
2024-12-09 15:22:50 +01:00

60 lines
1.7 KiB
Python

import sys
def main():
raw_line = sys.stdin.read().strip()
line = [int(x) for x in raw_line]
blocks = []
file_id = 0
is_file_len = True
for num in line:
if is_file_len:
if num > 0:
blocks.extend([str(file_id)] * num)
file_id += 1
else:
if num > 0:
blocks.extend(["."] * num)
is_file_len = not is_file_len
# Move whole files in order of decreasing file ID
max_file_id = file_id - 1
for fid in range(max_file_id, -1, -1):
file_positions = [i for i, b in enumerate(blocks) if b == str(fid)]
if not file_positions:
continue
file_len = len(file_positions)
leftmost_file_index = min(file_positions)
candidate_spans = []
free_count = 0
start_index = 0
for i in range(leftmost_file_index):
if blocks[i] == '.':
if free_count == 0:
start_index = i
free_count += 1
if free_count == file_len:
candidate_spans.append((start_index, i))
else:
free_count = 0
if not candidate_spans:
continue
span_start, span_end = candidate_spans[0]
for pos in file_positions:
blocks[pos] = '.'
for i in range(span_start, span_start + file_len):
blocks[i] = str(fid)
# Compute checksum
checksum_parts = []
for idx, val in enumerate(blocks):
if val != ".":
checksum_parts.append(idx * int(val))
print("System Checksum Found: " + str(sum(checksum_parts)))
if __name__ == "__main__":
main()