2021-12-10 - Syntax Scoring
(original .ipynb)
Day 10 puzzle input is a sequence of lines comprising different types of brackets - parentheses, curly braces, square brackets and curly braces (mine is here). Part 1 involves validating whether the closing bracket for each opening one - if there is an error we return report an error score and collect the total. Part 2 involves finding the valid sequences, determining the string that would complete each one, calculating a score for this additional string, sorting these scores and taking the middle one.
puzzle_input_str = open("puzzle_input/day10.txt").read()
test_input_str = """[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]"""
opener = {
"(": ")",
"[": "]",
"{": "}",
"<": ">"
}
error = {
")": 3,
"]": 57,
"}": 1197,
">": 25137
}
def parse_input(input_str):
return [list(line) for line in input_str.split("\n")]
def validate(line):
stack = []
for c in line:
if c in opener:
stack.append(opener[c])
else:
expected = stack.pop()
if expected != c:
return error[c], None
return 0, stack
def part_one(input_str):
total_score = 0
for line in parse_input(input_str):
score, _ = validate(line)
total_score += score
return total_score
assert 26397 == part_one(test_input_str)
print("part one:", part_one(puzzle_input_str))
part one: 167379
completion_score = {
")": 1,
"]": 2,
"}": 3,
">": 4
}
def part_two(input_str):
all_scores = []
for line in parse_input(input_str):
score, remaining = validate(line)
if score == 0:
for c in reversed(remaining):
score *= 5
score += completion_score[c]
all_scores.append(score)
return list(sorted(all_scores))[len(all_scores) // 2]
assert 288957 == part_two(test_input_str)
print("part two:", part_two(puzzle_input_str))
part two: 2776842859