79 lines
2.2 KiB
Python
79 lines
2.2 KiB
Python
from tools.aoc import AOCDay
|
|
from typing import Any
|
|
|
|
|
|
class Node:
|
|
def __init__(self, data: list) -> None:
|
|
self.metadata: list = data[-data[1]:]
|
|
self.children: list = []
|
|
|
|
def get_metadata_sum(self):
|
|
return sum(self.metadata) + sum(x.get_metadata_sum() for x in self.children)
|
|
|
|
def get_value(self):
|
|
if not self.children:
|
|
return sum(self.metadata)
|
|
else:
|
|
my_value = 0
|
|
for x in self.metadata:
|
|
if x - 1 < len(self.children):
|
|
my_value += self.children[x - 1].get_value()
|
|
|
|
return my_value
|
|
|
|
def print(self, depth: int = 0):
|
|
print(" " * depth, self.metadata)
|
|
for x in self.children:
|
|
x.print(depth + 2)
|
|
|
|
|
|
class Day(AOCDay):
|
|
inputs = [
|
|
[
|
|
(138, "input8_test"),
|
|
(40746, "input8"),
|
|
],
|
|
[
|
|
(66, "input8_test"),
|
|
(37453, "input8"),
|
|
]
|
|
]
|
|
|
|
def get_node_tree(self) -> Node:
|
|
inp = self.getInputAsArraySplit(' ', int)
|
|
children = []
|
|
while inp:
|
|
index = 0
|
|
parent_index = 0
|
|
while index < len(inp) and inp[index]:
|
|
if isinstance(inp[index], str):
|
|
index += 1
|
|
else:
|
|
parent_index = index
|
|
index += 2
|
|
sub_children = []
|
|
while index < len(inp) - 2 and str(inp[index + 2]).startswith("A"):
|
|
try:
|
|
sub_children.append(children[int(inp.pop(index + 2)[1:])])
|
|
except IndexError:
|
|
print(children, index)
|
|
node = Node(inp[index:index+2+inp[index + 1]])
|
|
node.children = sub_children
|
|
children.append(node)
|
|
inp[parent_index] -= 1
|
|
inp = inp[:index] + ['A'+str(len(children) - 1)] + inp[index+2+inp[index + 1]:]
|
|
if len(inp) == 1:
|
|
del children
|
|
return node
|
|
|
|
def part1(self) -> Any:
|
|
return self.get_node_tree().get_metadata_sum()
|
|
|
|
def part2(self) -> Any:
|
|
return self.get_node_tree().get_value()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
day = Day(2018, 8)
|
|
day.run(verbose=True)
|