From e688c2b674fc7ad6a964a48df379e5abd01843a7 Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Mon, 4 Dec 2023 10:40:34 +0100 Subject: Day4 --- day4/__init__.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 day4/__init__.py (limited to 'day4/__init__.py') diff --git a/day4/__init__.py b/day4/__init__.py new file mode 100644 index 0000000..677da75 --- /dev/null +++ b/day4/__init__.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +from abc import ABC +from typing import Iterator + +from aoc import BaseAssignment + +I = tuple[list[int], list[int]] +T = int + + +class Assignment(BaseAssignment, ABC): + def winning_numbers(self, winning: list[int], owned: list[int]) -> set[int]: + return set(winning) & set(owned) + + def parse_numbers(self, numbers: str) -> list[int]: + return [int(num) for num in numbers.split(" ") if num != ""] + + def parse_item(self, item: str) -> I: + _, numbers = item.split(": ") + winning, owned = numbers.split(" | ") + + return self.parse_numbers(winning), self.parse_numbers(owned) + + +class AssignmentOne(Assignment): + example_result = 13 + + def points(self, winning: list[int], owned: list[int]) -> int: + overlap = len(self.winning_numbers(winning, owned)) + return overlap if overlap < 2 else 2 ** (overlap - 1) + + def run(self, input: Iterator[I]) -> T: + return sum(self.points(winning, owned) for winning, owned in input) + + +class AssignmentTwo(Assignment): + example_result = 30 + + def run(self, input: Iterator[I]) -> T: + cards = list(input) + count = {index: 1 for index, _ in enumerate(cards)} + + for index, (winning, owned) in enumerate(cards): + for i in range(len(self.winning_numbers(winning, owned))): + winning_index = index + i + 1 + + if winning_index in count: + count[winning_index] += count[index] + + return sum(count.values()) -- cgit v1.2.3