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