From 831b3606b4c77f7752c56c9bde61665db77794cf Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 4 Dec 2023 11:10:40 +0000 Subject: [PATCH] 2023: d04: ex1: add solution --- 2023/d04/ex1/ex1.py | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100755 2023/d04/ex1/ex1.py diff --git a/2023/d04/ex1/ex1.py b/2023/d04/ex1/ex1.py new file mode 100755 index 0000000..2df3a72 --- /dev/null +++ b/2023/d04/ex1/ex1.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +import dataclasses +import sys + + +@dataclasses.dataclass +class Card: + win_nums: set[int] + nums: set[int] + + +# The input is in order without skipping, but just in case... +Cards = dict[int, Card] + + +def solve(input: list[str]) -> int: + def parse_nums(nums: str) -> set[int]: + return {int(n) for n in nums.split(" ") if n != ""} + + # This does *not* expect the "Card :" bit + def parse_card(card: str) -> Card: + win_nums, nums = card.split("|") + return Card( + win_nums=parse_nums(win_nums), + nums=parse_nums(nums), + ) + + def parse_line(line: str) -> tuple[int, Card]: + card_id, card = line.split(": ") + return int(card_id.removeprefix("Card")), parse_card(card) + + def parse(input: list[str]) -> Cards: + parsed = map(parse_line, input) + return {id: card for id, card in parsed} + + def score(card: Card) -> int: + actual_win_nums = card.nums & card.win_nums + if len(actual_win_nums) == 0: + return 0 + return 2 ** (len(actual_win_nums) - 1) + + cards = parse(input) + return sum(score(card) for card in cards.values()) + + +def main() -> None: + input = sys.stdin.read().splitlines() + print(solve(input)) + + +if __name__ == "__main__": + main()