import operator as op import re from collections import defaultdict from typing import Any, Callable, Iterator from ..base import BaseSolver MFCSAM: dict[str, int] = { "children": 3, "cats": 7, "samoyeds": 2, "pomeranians": 3, "akitas": 0, "vizslas": 0, "goldfish": 5, "trees": 3, "cars": 2, "perfumes": 1, } def match( aunts: list[dict[str, int]], operators: dict[str, Callable[[int, int], bool]] ) -> int: return next( i for i, aunt in enumerate(aunts, start=1) if all(operators[k](aunt[k], MFCSAM[k]) for k in aunt) ) class Solver(BaseSolver): def solve(self, input: str) -> Iterator[Any]: lines = input.splitlines() aunts: list[dict[str, int]] = [ { match[1]: int(match[2]) for match in re.findall( R"((?P[^:, ]+): (?P\d+))", line ) } for line in lines ] yield match(aunts, defaultdict(lambda: op.eq)) yield match( aunts, defaultdict( lambda: op.eq, trees=op.gt, cats=op.gt, pomeranians=op.lt, goldfish=op.lt, ), )