from functools import reduce from typing import Any, Iterator from ..base import BaseSolver BRACKETS = {"{": "}", "[": "]", "<": ">", "(": ")"} CORRUPT_SCORES = {")": 3, "]": 57, "}": 1197, ">": 25137} COMPLETE_SCORES = {")": 1, "]": 2, "}": 3, ">": 4} def corrupted_or_incomplete(line: str) -> tuple[bool, str]: opens: list[str] = [] for c in line: if c in BRACKETS: opens.append(c) elif BRACKETS[opens[-1]] != c: return True, c else: opens.pop() return (False, "".join(opens)) class Solver(BaseSolver): def solve(self, input: str) -> Iterator[Any]: lines = input.splitlines() answer_1: int = 0 incomplete_scores: list[int] = [] for line in lines: c, r = corrupted_or_incomplete(line) if c: answer_1 += CORRUPT_SCORES[r] else: incomplete_scores.append( reduce( lambda s, c: s * 5 + COMPLETE_SCORES[BRACKETS[c]], reversed(r), 0, ), ) yield answer_1 yield sorted(incomplete_scores)[len(incomplete_scores) // 2]