Watch
1
0
Fork
You've already forked advent-of-code
0

2017 Day 9 Part 1

This commit is contained in:
Jeremy Kaplan 2026-07-30 22:06:53 -04:00
commit 63093277b0

View file

@ -1,94 +1,46 @@
import enum
def part1(text):
return score(clean(text))
@enum.unique
class Token(enum.Enum):
GroupStart = '{'
GroupEnd = '}'
GarbageStart = '<'
GarbageEnd = '>'
Cancel = '!'
def log(f):
def _(*args):
ret = f(*args)
print(*args, '->', ret)
return ret
return _
def tokenize(stream):
tokens = {t.value: t for t in Token}
return [tokens[c] for c in stream if c in tokens]
def cancel(tokens):
stack = []
def clean(text: str) -> str:
out = ""
i = 0
cancellations = 0
while i < len(tokens):
t = tokens[i]
if t == Token.Cancel:
cancellations += 1
garbage = False
while i < len(text):
c = text[i]
if c == "!":
i += 2
continue
stack.append(t)
if garbage and c == ">":
garbage = False
elif garbage:
pass
elif c == "<":
garbage = True
else:
out += c
i += 1
assert len(tokens) == len(stack) + 2*cancellations
assert not garbage, "All garbage must be closed"
return out
return stack
def clean(tokens):
stack = []
i = 0
while i < len(tokens):
if tokens[i] == Token.GarbageStart:
while tokens[i] != Token.GarbageEnd:
i += 1
i += 1
continue
print('PUSH:', i, tokens[i])
stack.append(tokens[i])
i += 1
return stack
def score(text: str) -> int:
depth = 0
points = 0
for c in text:
if c == "{":
depth += 1
if c == "}":
points += depth
depth -= 1
class Group:
def __init__(self):
self.children = []
assert depth == 0, "All groups must be closed"
return points
def append(self, child):
self.children.append(child)
def __repr__(self):
return '{{}}'.format(''.join(repr(c) for c in self.children))
__str__ = __repr__
def parse(tokens):
stack = []
outer = Group()
last = None
tokens = list(clean(cancel(tokens)))
print(len([t for t in tokens if t == Token.GroupStart]), len([t for t in tokens if t == Token.GroupEnd]))
assert len([t for t in tokens if t == Token.GroupStart]) == len([t for t in tokens if t == Token.GroupEnd])
for t in tokens:
if t == Token.GroupStart:
g = Group()
if stack:
stack[-1].append(g)
stack.append(g)
elif t == Token.GroupEnd:
last = stack.pop(-1)
return last
def score(group, depth=1):
return depth + sum(score(c, depth+1) for c in group.children)
def solve(stream):
stuff = parse(tokenize(stream))
if stuff is None: return 0
return score(stuff)
with open('input/day9') as f:
with open("input/day09.txt") as f:
puzzle_input = f.read()
# print(solve('<{o"i!a,<{i<a>'))
print(solve(puzzle_input))
print(part1(puzzle_input))