60 lines
1.7 KiB
Python
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()
|