From 8c73824980fdcafc6989a82a9a891bcdd7c38a5c Mon Sep 17 00:00:00 2001 From: Christopher Bohn <bohn@unl.edu> Date: Mon, 4 Dec 2023 09:09:00 -0600 Subject: [PATCH] Completed 2023 Day 04 --- 2023/python/Day04.py | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 2023/python/Day04.py diff --git a/2023/python/Day04.py b/2023/python/Day04.py new file mode 100644 index 0000000..3451099 --- /dev/null +++ b/2023/python/Day04.py @@ -0,0 +1,61 @@ +from math import log2 +from typing import List, Tuple + +from ImportData import import_data + +day: int = 4 + +sample_data: List[str] = ''' +Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 +Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 +Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 +Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 +Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 +Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11 +'''.split('\n')[1:-1] + +data_structure: type = List[Tuple[List[int], List[int]]] + + +def parse_data(data: List[str]) -> data_structure: + cards: List[Tuple[List[int], List[int]]] = [] + for card in data: + numbers: List[str] = card.split(':')[1].split('|') + winning_numbers: List[int] = [int(number_string) for number_string in numbers[0].strip().split()] + your_numbers: List[int] = [int(number_string) for number_string in numbers[1].strip().split()] + cards.append((winning_numbers, your_numbers)) + return cards + + +def get_score(card: Tuple[List[int], List[int]]) -> int: + score: int = 0 + winning_numbers: List[int] = card[0] + your_numbers: List[int] = card[1] + for number in your_numbers: + if number in winning_numbers: + score = 1 if score == 0 else 2 * score + return score + + +def part1(data: data_structure) -> int: + return sum([get_score(card) for card in data]) + + +def part2(data: data_structure) -> int: + copy_count: List[int] = [1 for _ in data] + number_of_cards = len(data) + for i in range(number_of_cards): + card: Tuple[List[int], List[int]] = data[i] + score: int = get_score(card) + if score > 0: + count: int = int(log2(score)) + 1 # kludgey + for j in range(i + 1, min(number_of_cards, i + count + 1)): + copy_count[j] += copy_count[i] + return sum(copy_count) + + +if __name__ == '__main__': + production_ready = True + raw_data = import_data(day) if production_ready else sample_data + print(part1(parse_data(raw_data))) + print(part2(parse_data(raw_data))) -- GitLab