diff --git a/aoc_cas/aoc2023/day1.py b/aoc_cas/aoc2023/day1.py index 2cd7309..f4bddca 100644 --- a/aoc_cas/aoc2023/day1.py +++ b/aoc_cas/aoc2023/day1.py @@ -1,4 +1,4 @@ -from aoc_cas.util import test_with_examples +from aoc_cas.util import solve_with_examples def part_a(data) -> int: @@ -39,4 +39,4 @@ def part_b(data) -> int: if __name__ == "__main__": - test_with_examples(2023, 1) + solve_with_examples(2023, 1) diff --git a/aoc_cas/aoc2023/day2.py b/aoc_cas/aoc2023/day2.py new file mode 100644 index 0000000..d9866fd --- /dev/null +++ b/aoc_cas/aoc2023/day2.py @@ -0,0 +1,45 @@ +import dataclasses +from collections import defaultdict +from typing import Self + +from aoc_cas.util import solve_with_examples + + +@dataclasses.dataclass(frozen=True) +class Round: + id: int + red: int = 0 + blue: int = 0 + green: int = 0 + + @classmethod + def from_data_line(cls, line: str) -> Self: + game_part, cube_part = line.split(": ") + game_id = int(game_part.split(" ")[1]) + + most_seen: dict[str, int] = defaultdict(int) + for cube_set in cube_part.split("; "): + for draw in cube_set.split(", "): + count, color = draw.split(" ") + most_seen[color] = max(most_seen[color], int(count)) + + return Round(game_id, **most_seen) + + +def part_a(data: str) -> int: + result = 0 + for round in map(Round.from_data_line, data.splitlines()): + if round.red <= 12 and round.green <= 13 and round.blue <= 14: + result += round.id + return result + + +def part_b(data: str) -> int: + result = 0 + for round in map(Round.from_data_line, data.splitlines()): + result += round.blue * round.green * round.red + return result + + +if __name__ == "__main__": + solve_with_examples(year=2023, day=2) diff --git a/aoc_cas/cli.py b/aoc_cas/cli.py index 2e55313..2b71ebd 100644 --- a/aoc_cas/cli.py +++ b/aoc_cas/cli.py @@ -23,12 +23,12 @@ def main(): def solve(year: int, day: int, submit: bool) -> None: puzzle = Puzzle(year, day) log.info(f"--- {year} Day {day}: {puzzle.title} ---") - part_1_result, part_2_result = plugin(year, day) - log.info(f"PartA: {part_1_result}") - log.info(f"PartB: {part_2_result}") + part_a_result, part_b_result = plugin(year=year, day=day, data=puzzle.input_data) + log.info(f"PartA: {part_a_result}") + log.info(f"PartB: {part_b_result}") if submit: - puzzle.answer_a = part_1_result - puzzle.answer_2 = part_2_result + puzzle.answer_a = part_a_result + puzzle.answer_b = part_b_result @main.command() @@ -42,7 +42,7 @@ def init_challenge(year: int, day: int) -> None: year_folder.joinpath("__init__.py").touch() python_file = year_folder / f"day{day}.py" if not python_file.exists(): - python_file.write_text(challenge_template.format(day, year)) + python_file.write_text(challenge_template.format(day=day, year=year)) test_folder = Path.cwd() / f"tests/fixtures/{year}" test_folder.mkdir(exist_ok=True) diff --git a/aoc_cas/util.py b/aoc_cas/util.py index 46afcfa..f98b898 100644 --- a/aoc_cas/util.py +++ b/aoc_cas/util.py @@ -8,7 +8,7 @@ def load_module(year: int, day: int): return importlib.import_module(module_name) -def test_with_examples(year: int, day: int) -> None: +def solve_with_examples(year: int, day: int) -> None: mod = load_module(year, day) puzzle = Puzzle(year, day) print(f"Testing example data") @@ -19,6 +19,6 @@ def test_with_examples(year: int, day: int) -> None: correct = part_a_result == example.answer_a print(f"{'❌✅'[correct]} [Part A] Actual: {part_a_result} - Expected: {example.answer_a}") if example.answer_b is not None: - part_b_result = mod.part_b(example.input_data) - correct = part_b_result == example.answer_a + part_b_result = str(mod.part_b(example.input_data)) + correct = part_b_result == example.answer_b print(f"{'❌✅'[correct]} [Part B] Actual: {part_b_result} - Expected: {example.answer_b}\n") diff --git a/challenge_template.txt b/challenge_template.txt index 06336b2..0020c32 100644 --- a/challenge_template.txt +++ b/challenge_template.txt @@ -1,12 +1,12 @@ -from aoc_cas.util import test_with_examples +from aoc_cas.util import solve_with_examples -def part_a(data) -> int: +def part_a(data: str) -> int: pass -def part_b(data) -> int: +def part_b(data: str) -> int: pass if __name__ == "__main__": - test_with_examples({}, {}) + solve_with_examples(year={year}, day={day}) diff --git a/tests/fixtures/2023/2.txt b/tests/fixtures/2023/2.txt new file mode 100644 index 0000000..feae538 --- /dev/null +++ b/tests/fixtures/2023/2.txt @@ -0,0 +1,7 @@ +Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green +Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue +Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red +Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red +Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green +8 +2286 \ No newline at end of file