mirror of
https://github.com/thib8956/advent-of-code.git
synced 2024-12-25 21:36:29 +00:00
2024 day 9 part 2
This commit is contained in:
parent
d7b0cce606
commit
14426b0697
@ -29,10 +29,8 @@ def parse_disk(data):
|
|||||||
return disk, disk2
|
return disk, disk2
|
||||||
|
|
||||||
|
|
||||||
def main(inp):
|
def part1(disk):
|
||||||
disk, disk2 = parse_disk(inp)
|
|
||||||
max_file_location = max(disk.keys())
|
max_file_location = max(disk.keys())
|
||||||
|
|
||||||
write_ptr = 0
|
write_ptr = 0
|
||||||
read_ptr = max_file_location
|
read_ptr = max_file_location
|
||||||
while True:
|
while True:
|
||||||
@ -47,47 +45,66 @@ def main(inp):
|
|||||||
|
|
||||||
disk[write_ptr] = disk[read_ptr]
|
disk[write_ptr] = disk[read_ptr]
|
||||||
del disk[read_ptr]
|
del disk[read_ptr]
|
||||||
|
|
||||||
checksum = sum(i * disk.get(i, 0) for i in range(max_file_location))
|
checksum = sum(i * disk.get(i, 0) for i in range(max_file_location))
|
||||||
print("Part 1: ", checksum)
|
return checksum
|
||||||
|
|
||||||
print(len(disk2))
|
|
||||||
write_ptr = 0
|
def part2(disk):
|
||||||
read_ptr = len(disk2) - 1
|
max_id = max(f.id_ for f in disk)
|
||||||
for file_index in range(len(disk2) - 1, 0, -1):
|
for i in range(max_id, -1, -1):
|
||||||
file = disk2[file_index]
|
file, file_index = next((file, index) for index, file in enumerate(disk) if file.id_ == i)
|
||||||
if file.kind != "file":
|
|
||||||
continue
|
|
||||||
|
|
||||||
# find index of the first gap large enough
|
# find index of the first gap large enough
|
||||||
free_index, free_space = next(((i, b) for i, b in enumerate(disk2) if b.kind == "free" and b.size >= file.size), (None, None))
|
free_index, free_space = next(((i, b) for i, b in enumerate(disk) if b.kind == "free" and b.size >= file.size), (None, None))
|
||||||
if free_index is None:
|
if free_index is None:
|
||||||
continue
|
continue
|
||||||
# add a free space in place of the file
|
if free_index >= file_index: # always move file to the left
|
||||||
disk2[file_index] = Item("free", file.size)
|
continue
|
||||||
# insert file just before free space
|
|
||||||
disk2.insert(free_index, file)
|
|
||||||
# decrease free space by file size (in case free space is larger)
|
# decrease free space by file size (in case free space is larger)
|
||||||
free_space.size -= file.size
|
disk[free_index].size -= file.size
|
||||||
|
# add a free space in place of the file
|
||||||
|
disk[file_index] = Item("free", file.size)
|
||||||
|
# insert file just before free space
|
||||||
|
disk.insert(free_index, file)
|
||||||
|
|
||||||
|
#debug = debug_print(disk)
|
||||||
|
#print(debug)
|
||||||
|
|
||||||
|
# calculate checksum for part2
|
||||||
total_checksum = 0
|
total_checksum = 0
|
||||||
offset = 0
|
offset = 0
|
||||||
print(disk2)
|
#print(disk)
|
||||||
print(len(disk2))
|
debug_print(disk)
|
||||||
for f in disk2:
|
#print(len(disk))
|
||||||
|
for f in disk:
|
||||||
if f.kind != "file":
|
if f.kind != "file":
|
||||||
offset += f.size
|
offset += f.size
|
||||||
continue
|
continue
|
||||||
# S(n) = n*(n+1) // 2
|
# S(n) = n*(n+1) // 2
|
||||||
print(f"checksum = {f.id_} * ({offset} * {f.size} + ({f.size} * ({f.size - 1})) // 2")
|
#print(f"checksum = {f.id_} * ({offset} * {f.size} + ({f.size} * ({f.size - 1})) // 2")
|
||||||
checksum = f.id_ * (offset * f.size + (f.size * (f.size - 1)) // 2)
|
checksum = f.id_ * (offset * f.size + (f.size * (f.size - 1)) // 2)
|
||||||
print(f, checksum)
|
#print(f, checksum, total_checksum)
|
||||||
|
|
||||||
offset += f.size
|
offset += f.size
|
||||||
total_checksum += checksum
|
total_checksum += checksum
|
||||||
print(total_checksum)
|
return total_checksum
|
||||||
|
|
||||||
|
|
||||||
|
def main(inp):
|
||||||
|
disk, disk2 = parse_disk(inp)
|
||||||
|
print("Part 1: ", part1(disk))
|
||||||
|
print("Part 2: ", part2(disk2))
|
||||||
|
|
||||||
|
|
||||||
|
def debug_print(disk):
|
||||||
|
res = []
|
||||||
|
for item in disk:
|
||||||
|
if item.kind == "free" and item.size > 0:
|
||||||
|
res.extend(["."] * item.size)
|
||||||
|
else:
|
||||||
|
res.extend([str(item.id_)] * item.size)
|
||||||
|
return "".join(res)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user