generated from public/aoc_template
day9 - p2 partial
This commit is contained in:
parent
4e749b6fdd
commit
939b55360d
138
day09.py
Normal file
138
day09.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from tools.aoc import AOCDay
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
class Block:
|
||||||
|
file_id: int
|
||||||
|
file_length: int
|
||||||
|
left: Block | None
|
||||||
|
right: Block | None
|
||||||
|
|
||||||
|
def __init__(self, file_id: int, file_length: int, left: Block | None = None):
|
||||||
|
self.file_id = file_id
|
||||||
|
self.file_length = file_length
|
||||||
|
self.left = left
|
||||||
|
self.right = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_checksum(head: Block) -> int:
|
||||||
|
checksum = 0
|
||||||
|
index = head
|
||||||
|
count = 0
|
||||||
|
while index is not None:
|
||||||
|
print((str(index.file_id) + "|") * index.file_length, end="")
|
||||||
|
if index.file_id > 0:
|
||||||
|
for _ in range(index.file_length):
|
||||||
|
checksum += index.file_id * count
|
||||||
|
count += 1
|
||||||
|
else:
|
||||||
|
count += index.file_length
|
||||||
|
index = index.right
|
||||||
|
|
||||||
|
print()
|
||||||
|
return checksum
|
||||||
|
|
||||||
|
|
||||||
|
class Day(AOCDay):
|
||||||
|
inputs = [
|
||||||
|
[
|
||||||
|
(1928, "input9_test"),
|
||||||
|
(6346871685398, "input9"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
(2858, "input9_test"),
|
||||||
|
(None, "input9"),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
def parse_input(self) -> tuple[Block, Block]:
|
||||||
|
head = Block(-1, 0)
|
||||||
|
tail = head
|
||||||
|
mode = False # False == file, True == free space
|
||||||
|
file_id = 0
|
||||||
|
for num in map(int, self.getInput()):
|
||||||
|
tail.right = Block(-1 if mode else file_id, num, tail)
|
||||||
|
tail = tail.right
|
||||||
|
|
||||||
|
if mode:
|
||||||
|
file_id += 1
|
||||||
|
mode = not mode
|
||||||
|
|
||||||
|
head = head.right
|
||||||
|
head.left = None
|
||||||
|
return head, tail
|
||||||
|
|
||||||
|
def part1(self) -> Any:
|
||||||
|
head, tail = self.parse_input()
|
||||||
|
|
||||||
|
index = head
|
||||||
|
while index is not None:
|
||||||
|
if index.file_id != -1:
|
||||||
|
index = index.right
|
||||||
|
continue
|
||||||
|
|
||||||
|
if tail.file_id == -1:
|
||||||
|
tail = tail.left
|
||||||
|
tail.right = None
|
||||||
|
|
||||||
|
if tail.file_length > index.file_length:
|
||||||
|
index.file_id = tail.file_id
|
||||||
|
tail.file_length -= index.file_length
|
||||||
|
elif tail.file_length < index.file_length:
|
||||||
|
space_left = index.file_length - tail.file_length
|
||||||
|
index.file_id = tail.file_id
|
||||||
|
index.file_length = tail.file_length
|
||||||
|
tail = tail.left
|
||||||
|
tail.right = None
|
||||||
|
new_space = Block(-1, space_left, index)
|
||||||
|
new_space.right = index.right
|
||||||
|
index.right = new_space
|
||||||
|
else:
|
||||||
|
index.file_id = tail.file_id
|
||||||
|
tail = tail.left
|
||||||
|
tail.right = None
|
||||||
|
|
||||||
|
index = index.right
|
||||||
|
|
||||||
|
return get_checksum(head)
|
||||||
|
|
||||||
|
def part2(self) -> Any:
|
||||||
|
head, tail = self.parse_input()
|
||||||
|
|
||||||
|
index = tail
|
||||||
|
while index is not None:
|
||||||
|
search = head
|
||||||
|
while search != index:
|
||||||
|
if search.file_id == -1 and search.file_length >= index.file_length:
|
||||||
|
new_free_space = Block(-1, index.file_length, index.left)
|
||||||
|
new_free_space.right = index.right
|
||||||
|
index.left.right = new_free_space
|
||||||
|
if index.right is not None:
|
||||||
|
index.right.left = new_free_space
|
||||||
|
|
||||||
|
search.file_id = index.file_id
|
||||||
|
if search.file_length > index.file_length:
|
||||||
|
space_left = search.file_length - index.file_length
|
||||||
|
search.file_length = index.file_length
|
||||||
|
new_space = Block(-1, space_left, search)
|
||||||
|
new_space.right = search.right
|
||||||
|
search.right.left = new_space
|
||||||
|
search.right = new_space
|
||||||
|
|
||||||
|
index = new_free_space
|
||||||
|
break
|
||||||
|
search = search.right
|
||||||
|
|
||||||
|
index = index.left
|
||||||
|
|
||||||
|
while tail.file_id == -1:
|
||||||
|
tail = tail.left
|
||||||
|
tail.right = None
|
||||||
|
|
||||||
|
return get_checksum(head)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
day = Day(2024, 9)
|
||||||
|
day.run(verbose=True)
|
||||||
1
inputs/input9
Normal file
1
inputs/input9
Normal file
File diff suppressed because one or more lines are too long
1
inputs/input9_test
Normal file
1
inputs/input9_test
Normal file
@ -0,0 +1 @@
|
|||||||
|
2333133121414131402
|
||||||
Loading…
Reference in New Issue
Block a user