48 lines
1.2 KiB
Python
48 lines
1.2 KiB
Python
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]
|