[py] Port 2017_09

This commit is contained in:
Joscha 2022-12-06 19:50:21 +01:00
parent cd785a40b3
commit d27285ef23
3 changed files with 90 additions and 96 deletions

88
py/aoc/y2017/d09.py Normal file
View file

@ -0,0 +1,88 @@
class Stream:
def __init__(self, string):
self.content = list(string)
self.content.reverse()
def peek(self):
return self.content[-1]
def pop(self):
return self.content.pop()
def load_groups(inputstr):
groups = []
for line in inputstr.splitlines():
stream = Stream(line)
group, garbage = parse_group(stream)
groups.append((group, garbage))
return groups
def parse_group(stream):
assert stream.pop() == "{"
if stream.peek() == "}":
assert stream.pop() == "}"
return [], 0
groups = []
garbage = 0
while True:
# Determine which sub-parser to use
if stream.peek() == "{":
group, more_garbage = parse_group(stream)
groups.append(group)
garbage += more_garbage
elif stream.peek() == "<":
garbage += parse_garbage(stream)
else:
raise Exception("Incorrectly formatted input")
# Determine whether to stop parsing
if stream.peek() == "}":
break
elif stream.peek() == ",":
assert stream.pop() == ","
else:
raise Exception("Incorrectly formatted input")
assert stream.pop() == "}"
return groups, garbage
def parse_garbage(stream):
assert stream.pop() == "<"
escaped = False
garbage = 0
while True:
if escaped:
stream.pop()
escaped = False
elif stream.peek() == "!":
assert stream.pop() == "!"
escaped = True
elif stream.peek() == ">":
break
else:
stream.pop()
garbage += 1
assert stream.pop() == ">"
return garbage
def group_score(group, level=1):
return sum(group_score(subgroup, level + 1) for subgroup in group) + level
def solve(inputstr):
groups = load_groups(inputstr)
for group, garbage in groups:
score = group_score(group)
print(f"Part 1: {score}")
print(f"Part 2: {garbage}")