Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solve 2023 day 04 #35

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions puzzles/solutions/2023/d04/p1.py
Original file line number Diff line number Diff line change
@@ -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.
32 changes: 32 additions & 0 deletions puzzles/solutions/2023/d04/p2.py
Original file line number Diff line number Diff line change
@@ -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.