From 63093277b0ed4b4b68e52096a0f9d6235689f33a Mon Sep 17 00:00:00 2001 From: Jeremy Kaplan Date: Thu, 30 Jul 2026 22:06:53 -0400 Subject: [PATCH] 2017 Day 9 Part 1 --- 2017/day09.py | 112 +++++++++++++++----------------------------------- 1 file changed, 32 insertions(+), 80 deletions(-) diff --git a/2017/day09.py b/2017/day09.py index 50483dd..55945de 100644 --- a/2017/day09.py +++ b/2017/day09.py @@ -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')) -print(solve(puzzle_input)) +print(part1(puzzle_input))