Part 1


In [94]:
def parse():
    l = ! cat input.txt | tr '\n' ';'
    return list(map(int, l[0].rstrip(';').split(';')[0].split(' ')))

In [95]:
class Node:
    
    def __init__(self):
        self.pending  = None
        self.meta     = None
        self.parent   = None
        self.first    = True
            
    def add_child(self, node):
        node.parent   = self
        self.children.append(node)
    
    def read(self, acc, license):
        if self.first:
            self.pending = license.pop(0)
            self.meta    = license.pop(0)
            self.first   = False
        while self.pending > 0:
            node = Node()
            acc, license = node.read(acc, license)
            self.pending -= 1
        acc += sum(license[: self.meta])
        license = license[self.meta:]
        return acc, license

def sum_metadata(license):
    root = Node()
    s, unread = root.read(0, license)
    return s

Test


In [96]:
license = [2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2]
sum_metadata(license)


Out[96]:
138

Solution


In [97]:
l = parse()
sum_metadata(l)


Out[97]:
40984

Part 2


In [232]:
class Node:
    
    def __init__(self):
        self.children = []
        self.pending  = None
        self.meta     = None
        self.parent   = None
        self.metadata = None
        self.first    = True
            
    def add_child(self, node):
        node.parent   = self
        self.children.append(node)
    
    def read(self, license):
        if self.first:
            self.pending = license.pop(0)
            self.meta    = license.pop(0)
            self.first   = False
        while self.pending > 0:
            node = Node()
            self.add_child(node)
            license = node.read(license)
            self.pending -= 1
        self.metadata = license[: self.meta]
        license = license[self.meta:]
        return license
    
    def nodevalue(self):
        if self.children == []:
            return sum(self.metadata)
        acc = 0
        for i, n in enumerate(self.children):
            acc += self.metadata.count(i+1) * n.nodevalue()
        return acc

def root_value(license):
    root = Node()       
    root.read(license)
    return root.nodevalue()

Test


In [233]:
license = [2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2]
root_value(license)


Out[233]:
66

Solution


In [234]:
l = parse()
root_value(l)


Out[234]:
37067