summaryrefslogtreecommitdiffstats
path: root/20/py/d07.py
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2020-12-09 10:13:45 +0100
committerGustav Sörnäs <gustav@sornas.net>2020-12-09 10:13:45 +0100
commit3899b5c2c5afd1725c69bf1f7f0d437d97df7e0e (patch)
tree22e3eba4eebc30b526131809a3a8f5301eec9f99 /20/py/d07.py
parent81d5b6d06a47168874629c2444c73e1d4c34f070 (diff)
downloadaoc-3899b5c2c5afd1725c69bf1f7f0d437d97df7e0e.tar.gz
d7 no regex parse
Diffstat (limited to '20/py/d07.py')
-rw-r--r--20/py/d07.py23
1 files changed, 16 insertions, 7 deletions
diff --git a/20/py/d07.py b/20/py/d07.py
index 1d25e53..3cf37ba 100644
--- a/20/py/d07.py
+++ b/20/py/d07.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
import aoc20
import sys
-import regex as re
import functools
@@ -9,6 +8,7 @@ class Node:
def __init__(self, name, children=[]):
self.name = name
self.children = children
+ self.parents = []
def __iter__(self):
yield from (child for child, _ in self.children)
@@ -17,21 +17,30 @@ class Node:
def parse(_in):
nodes = {}
for line in _in:
- match = re.match(r"(\w+ \w+) bags contain (no other bags|(((\d+) (\w+ \w+)) bags?(, )?)+)\.", line)
- children = [(node_str, int(amount)) for amount, node_str in zip(match.captures(5), match.captures(6))]
- nodes[match[1]] = Node(match[1], children)
+ line = line.split()
+ # muted lime bags contain 1 wavy lime bag, 1 vibrant green bag, 3 light yellow bags.
+ # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ # dotted teal bags contain no other bags.
+ if line[4] != "no":
+ children = [(" ".join(line[i+1:i+3]), int(line[i+0])) for i in range(4, len(line), 4)]
+ else:
+ children = []
+ name = " ".join(line[0:2])
+ nodes[name] = Node(name, children)
for node in nodes.values():
node.children = [(nodes[node_str], amount) for node_str, amount in node.children]
+ for child in node:
+ child.parents.append(node)
return nodes
def pt1(_in):
@functools.cache
- def can_contain(node, target):
- return target in node or any(can_contain(child, target) for child in node)
+ def types_above(node):
+ return node.parents + list(functools.reduce(lambda a, b: a + b, (types_above(parent) for parent in node.parents), []))
nodes = parse(_in)
- return len([node for node in nodes.values() if can_contain(node, nodes["shiny gold"])])
+ return len(set(types_above(nodes["shiny gold"])))
def pt2(_in):