88 lines
2.4 KiB
Python
88 lines
2.4 KiB
Python
from aocd.models import Puzzle
|
|
from aocd import submit
|
|
|
|
|
|
def get_winning_numbers(input_data: str) -> list:
|
|
"""
|
|
Parse input_data, extract all cards and turn them into sets.
|
|
Return the intersection between numbers and winning numbers.
|
|
"""
|
|
|
|
# separate cards into a list of strings and remove excess whitespace
|
|
pairs = [" ".join(card.split()) for card in input_data.split("\n")]
|
|
# extract a set of winning numbers
|
|
winners = [
|
|
set(pair.split(":")[1].split("|")[0].strip().split(" ")) for pair in pairs
|
|
]
|
|
# extract a set of scratch numbers
|
|
numbers = [
|
|
set(pair.split(":")[1].split("|")[1].strip().split(" ")) for pair in pairs
|
|
]
|
|
# calculate set intersection between numbers and winning numbers
|
|
intersections = [numbers[i].intersection(winners[i]) for i in range(len(numbers))]
|
|
|
|
return intersections
|
|
|
|
|
|
def calculate_scores(winning_numbers: list) -> list:
|
|
"""
|
|
Calculate the score for each number
|
|
- 0 points for no match
|
|
- 1 point for 1 match
|
|
- double the points for each successive match
|
|
"""
|
|
|
|
scores = []
|
|
for win in winning_numbers:
|
|
if len(win) == 0:
|
|
scores.append(0)
|
|
if len(win) == 1:
|
|
scores.append(1)
|
|
if len(win) > 1:
|
|
scores.append(2 ** (len(win) - 1))
|
|
|
|
return scores
|
|
|
|
|
|
def new_rules(input_data: list) -> list:
|
|
"""
|
|
Calculate the score for the updated rule set.
|
|
- If your card has n matches, get the next n cards
|
|
- repeat until there are no more matches
|
|
- return the total number of cards you've accumulated
|
|
"""
|
|
|
|
data = input_data.split("\n")
|
|
|
|
cards = [1 for i in range(len(data))]
|
|
|
|
win = 0
|
|
for i, line in enumerate(data):
|
|
wins = line.split("|")[0].split(":")[1].split()
|
|
nums = line.split("|")[1].split()
|
|
for num in nums:
|
|
if num in wins:
|
|
win += 1
|
|
for j in range(win):
|
|
cards[i + j + 1] += cards[i]
|
|
win = 0
|
|
|
|
return cards
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# get puzzle and parse data
|
|
puzzle = Puzzle(year=2023, day=4)
|
|
|
|
# parse_input(puzzle.input_data)
|
|
winning_numbers = get_winning_numbers(puzzle.input_data)
|
|
|
|
answer_a = sum(calculate_scores(winning_numbers))
|
|
print(f"{answer_a}")
|
|
submit(answer_a, part="a", day=4, year=2023)
|
|
|
|
# part b:
|
|
answer_b = sum(new_rules(puzzle.input_data))
|
|
print(f"{answer_b}")
|
|
submit(answer_b, part="b", day=4, year=2023)
|