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 clean(text: str) -> str:
def _(*args): out = ""
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 = []
i = 0 i = 0
cancellations = 0 garbage = False
while i < len(tokens): while i < len(text):
t = tokens[i] c = text[i]
if t == Token.Cancel: if c == "!":
cancellations += 1
i += 2 i += 2
continue continue
stack.append(t)
if garbage and c == ">":
garbage = False
elif garbage:
pass
elif c == "<":
garbage = True
else:
out += c
i += 1 i += 1
assert len(tokens) == len(stack) + 2*cancellations assert not garbage, "All garbage must be closed"
return out
return stack
def clean(tokens): def score(text: str) -> int:
stack = [] depth = 0
i = 0 points = 0
while i < len(tokens): for c in text:
if tokens[i] == Token.GarbageStart: if c == "{":
while tokens[i] != Token.GarbageEnd: depth += 1
i += 1 if c == "}":
i += 1 points += depth
continue depth -= 1
print('PUSH:', i, tokens[i])
stack.append(tokens[i])
i += 1
return stack
class Group: assert depth == 0, "All groups must be closed"
def __init__(self): return points
self.children = []
def append(self, child):
self.children.append(child)
def __repr__(self): with open("input/day09.txt") as f:
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:
puzzle_input = f.read() puzzle_input = f.read()
# print(solve('<{o"i!a,<{i<a>')) print(part1(puzzle_input))
print(solve(puzzle_input))