diff --git a/puzzles/solutions/2023/d04/p1.py b/puzzles/solutions/2023/d04/p1.py new file mode 100644 index 0000000..117ad15 --- /dev/null +++ b/puzzles/solutions/2023/d04/p1.py @@ -0,0 +1,36 @@ +import collections +import sys + + +Card = collections.namedtuple("Card", ("number", "winning_numbers", "chosen_numbers")) + + +def get_card_from_line(card_line: str) -> Card: + card_number, numbers_lists = card_line.split(": ") + card_number = int(card_number.split()[1]) + + winning_numbers, chosen_numbers = numbers_lists.split(" | ") + winning_numbers = set(winning_numbers.split()) + chosen_numbers = set(chosen_numbers.split()) + + return Card(card_number, winning_numbers, chosen_numbers) + + +def calculate_card_points(card: Card) -> int: + amount_of_card_winning_numbers = len(card.winning_numbers & card.chosen_numbers) + if amount_of_card_winning_numbers == 0: + return 0 + return 2 ** (amount_of_card_winning_numbers - 1) + + +def get_answer(input_text: str) -> int: + """Return the colourful cards total points worth.""" + cards = [get_card_from_line(line) for line in input_text.splitlines()] + return sum(map(calculate_card_points, cards)) + + +if __name__ == "__main__": + try: + print(get_answer(sys.argv[1])) + except IndexError: + pass # Don't crash if no input was passed through command line arguments. diff --git a/puzzles/solutions/2023/d04/p2.py b/puzzles/solutions/2023/d04/p2.py new file mode 100644 index 0000000..4e58cff --- /dev/null +++ b/puzzles/solutions/2023/d04/p2.py @@ -0,0 +1,32 @@ +import sys + + +import p1 + + +def get_answer(input_text: str) -> int: + """Return the amount of cards we end up with.""" + cards = [p1.get_card_from_line(line) for line in input_text.splitlines()] + + card_to_matching_numbers = {} + for card in cards: + matching_numbers_amount = len(card.winning_numbers & card.chosen_numbers) + cards_copies_numbers = range( + card.number + 1, card.number + matching_numbers_amount + 1 + ) + card_to_matching_numbers[card.number] = cards_copies_numbers + + card_to_amount = {card.number: 1 for card in cards} + + for card, matching_numbers in card_to_matching_numbers.items(): + for matching_number in matching_numbers: + card_to_amount[matching_number] += card_to_amount[card] + + return sum(card_to_amount.values()) + + +if __name__ == "__main__": + try: + print(get_answer(sys.argv[1])) + except IndexError: + pass # Don't crash if no input was passed through command line arguments.