import math from typing import Any, Iterator, Sequence, cast import parse # type: ignore from ..base import BaseSolver def score(ingredients: list[list[int]], teaspoons: Sequence[int]) -> int: return math.prod( max( 0, sum( ingredient[prop] * teaspoon for ingredient, teaspoon in zip(ingredients, teaspoons) ), ) for prop in range(len(ingredients[0]) - 1) ) class Solver(BaseSolver): def solve(self, input: str) -> Iterator[Any]: lines = input.splitlines() ingredients: list[list[int]] = [] for line in lines: _, *scores = cast( tuple[str, int, int, int, int, int], parse.parse( # type: ignore "{}: capacity {:d}, durability {:d}, flavor {:d}, " "texture {:d}, calories {:d}", line, ), ) ingredients.append(scores) total_teaspoons = 100 calories: list[int] = [] scores: list[int] = [] for a in range(total_teaspoons + 1): for b in range(total_teaspoons + 1 - a): for c in range(total_teaspoons + 1 - a - b): teaspoons = (a, b, c, total_teaspoons - a - b - c) scores.append(score(ingredients, teaspoons)) calories.append( sum( ingredient[-1] * teaspoon for ingredient, teaspoon in zip(ingredients, teaspoons) ) ) yield max(scores) yield max(score for score, calory in zip(scores, calories) if calory == 500)