diff options
| author | 2021-12-04 12:31:52 +0100 | |
|---|---|---|
| committer | 2021-12-04 12:31:52 +0100 | |
| commit | 5ba784ae1220ec930ffce9ea1ccbb1d6411f841e (patch) | |
| tree | 2c11dce971ce179e3c2b9c022970d2e57fc7eb23 | |
| parent | 3df1c0af382c6c04370b879c7168b46d833c761f (diff) | |
| download | 2021-5ba784ae1220ec930ffce9ea1ccbb1d6411f841e.tar.gz 2021-5ba784ae1220ec930ffce9ea1ccbb1d6411f841e.tar.bz2 2021-5ba784ae1220ec930ffce9ea1ccbb1d6411f841e.zip | |
Day 4
| -rw-r--r-- | day4/__init__.py | 121 | ||||
| -rw-r--r-- | day4/example.txt | 19 | ||||
| -rw-r--r-- | day4/input.txt | 601 |
3 files changed, 741 insertions, 0 deletions
diff --git a/day4/__init__.py b/day4/__init__.py new file mode 100644 index 0000000..74c01f1 --- /dev/null +++ b/day4/__init__.py | |||
| @@ -0,0 +1,121 @@ | |||
| 1 | from collections import Counter | ||
| 2 | from copy import copy | ||
| 3 | from dataclasses import dataclass | ||
| 4 | from typing import Iterator, List, Optional, Tuple, Callable | ||
| 5 | |||
| 6 | from aoc import BaseAssignment | ||
| 7 | |||
| 8 | def bold(item: str, condition: Callable[[], bool]): | ||
| 9 | return f'\033[36m{item}\033[0m' if condition() else item | ||
| 10 | |||
| 11 | @dataclass | ||
| 12 | class Number: | ||
| 13 | nr: int | ||
| 14 | marked: bool = False | ||
| 15 | |||
| 16 | def __int__(self): | ||
| 17 | return self.nr | ||
| 18 | |||
| 19 | def __bool__(self): | ||
| 20 | return self.marked | ||
| 21 | |||
| 22 | def __radd__(self, other): | ||
| 23 | return other + int(self) | ||
| 24 | |||
| 25 | def mark(self): | ||
| 26 | self.marked = True | ||
| 27 | |||
| 28 | @dataclass | ||
| 29 | class BingoCard: | ||
| 30 | card: List[List[Number]] | ||
| 31 | |||
| 32 | @property | ||
| 33 | def bingo(self) -> bool: | ||
| 34 | return any([ | ||
| 35 | *[all(bool(item) for item in row) for row in self.card], | ||
| 36 | *[all(bool(row[col_index]) for row in self.card) for col_index in range(5)] | ||
| 37 | ]) | ||
| 38 | |||
| 39 | def mark(self, nr: int): | ||
| 40 | for row in self.card: | ||
| 41 | for item in row: | ||
| 42 | if int(item) == nr: | ||
| 43 | item.mark() | ||
| 44 | |||
| 45 | @property | ||
| 46 | def unmarked(self): | ||
| 47 | return [ | ||
| 48 | item | ||
| 49 | for row in self.card | ||
| 50 | for item in row | ||
| 51 | if not bool(item) | ||
| 52 | ] | ||
| 53 | |||
| 54 | def __str__(self): | ||
| 55 | return '\n'.join([ | ||
| 56 | ''.join([ | ||
| 57 | bold(str(int(item)).rjust(2, ' ').ljust(3, ' '), lambda: item.marked) | ||
| 58 | for item in row | ||
| 59 | ]) | ||
| 60 | for row in self.card | ||
| 61 | ]) | ||
| 62 | |||
| 63 | |||
| 64 | class Assignment(BaseAssignment): | ||
| 65 | def read_input(self, example = False) -> Tuple[List[int], List[BingoCard]]: | ||
| 66 | cards = [] | ||
| 67 | card = None | ||
| 68 | |||
| 69 | input = super().read_input(example) | ||
| 70 | nrs = [ int(n) for n in next(input).split(',') ] | ||
| 71 | |||
| 72 | try: | ||
| 73 | row = next(input) | ||
| 74 | |||
| 75 | while True: | ||
| 76 | if row == '': | ||
| 77 | if card is not None: | ||
| 78 | cards.append(BingoCard(card=card)) | ||
| 79 | card = [] | ||
| 80 | else: | ||
| 81 | card.append([ Number(nr=int(item)) for item in row.split(' ') if item != '']) | ||
| 82 | |||
| 83 | row = next(input) | ||
| 84 | |||
| 85 | except StopIteration: | ||
| 86 | if card is not None: | ||
| 87 | cards.append(BingoCard(card=card)) | ||
| 88 | |||
| 89 | return nrs, cards | ||
| 90 | |||
| 91 | |||
| 92 | class AssignmentOne(Assignment): | ||
| 93 | example_result = 4512 | ||
| 94 | |||
| 95 | def run(self, input: Tuple[List[int], List[BingoCard]]) -> int: | ||
| 96 | nrs, cards = input | ||
| 97 | |||
| 98 | for nr in nrs: | ||
| 99 | for card in cards: | ||
| 100 | card.mark(nr) | ||
| 101 | |||
| 102 | if card.bingo: | ||
| 103 | return nr * sum(card.unmarked) | ||
| 104 | |||
| 105 | |||
| 106 | class AssignmentTwo(Assignment): | ||
| 107 | example_result = 1924 | ||
| 108 | |||
| 109 | def run(self, input: Tuple[List[int], List[BingoCard]]) -> int: | ||
| 110 | nrs, cards = input | ||
| 111 | |||
| 112 | in_game = copy(cards) | ||
| 113 | for nr in nrs: | ||
| 114 | for card in copy(in_game): | ||
| 115 | card.mark(nr) | ||
| 116 | |||
| 117 | if card.bingo: | ||
| 118 | in_game.remove(card) | ||
| 119 | |||
| 120 | if len(in_game) == 0: | ||
| 121 | return nr * sum(card.unmarked) \ No newline at end of file | ||
diff --git a/day4/example.txt b/day4/example.txt new file mode 100644 index 0000000..49d17bc --- /dev/null +++ b/day4/example.txt | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 | ||
| 2 | |||
| 3 | 22 13 17 11 0 | ||
| 4 | 8 2 23 4 24 | ||
| 5 | 21 9 14 16 7 | ||
| 6 | 6 10 3 18 5 | ||
| 7 | 1 12 20 15 19 | ||
| 8 | |||
| 9 | 3 15 0 2 22 | ||
| 10 | 9 18 13 17 5 | ||
| 11 | 19 8 7 25 23 | ||
| 12 | 20 11 10 24 4 | ||
| 13 | 14 21 16 12 6 | ||
| 14 | |||
| 15 | 14 21 17 24 4 | ||
| 16 | 10 16 15 9 19 | ||
| 17 | 18 8 23 26 20 | ||
| 18 | 22 11 13 6 5 | ||
| 19 | 2 0 12 3 7 \ No newline at end of file | ||
diff --git a/day4/input.txt b/day4/input.txt new file mode 100644 index 0000000..0c1c262 --- /dev/null +++ b/day4/input.txt | |||
| @@ -0,0 +1,601 @@ | |||
| 1 | 17,25,31,22,79,72,58,47,62,50,30,91,11,63,66,83,33,75,44,18,56,81,32,46,93,13,41,65,14,95,19,38,8,35,52,7,12,70,84,23,4,42,90,60,6,40,97,16,27,86,5,48,54,64,29,67,26,89,99,53,34,0,57,3,92,37,59,9,21,78,51,80,73,82,76,28,88,96,45,69,98,1,2,71,68,49,36,15,55,39,87,77,74,94,61,85,10,43,20,24 | ||
| 2 | |||
| 3 | 36 11 70 77 80 | ||
| 4 | 63 3 56 75 28 | ||
| 5 | 89 91 27 33 82 | ||
| 6 | 53 79 52 96 32 | ||
| 7 | 58 14 78 65 38 | ||
| 8 | |||
| 9 | 26 15 50 56 2 | ||
| 10 | 20 27 42 11 16 | ||
| 11 | 93 44 38 28 68 | ||
| 12 | 66 88 78 81 77 | ||
| 13 | 91 46 55 86 6 | ||
| 14 | |||
| 15 | 46 53 14 17 75 | ||
| 16 | 71 4 70 99 48 | ||
| 17 | 65 96 68 80 72 | ||
| 18 | 3 97 62 37 88 | ||
| 19 | 82 35 36 23 39 | ||
| 20 | |||
| 21 | 17 1 61 77 5 | ||
| 22 | 74 60 12 24 48 | ||
| 23 | 34 19 68 65 86 | ||
| 24 | 44 59 38 40 95 | ||
| 25 | 67 64 9 52 27 | ||
| 26 | |||
| 27 | 44 60 8 81 3 | ||
| 28 | 30 71 85 23 99 | ||
| 29 | 68 88 38 97 48 | ||
| 30 | 27 70 63 28 12 | ||
| 31 | 67 57 34 13 93 | ||
| 32 | |||
| 33 | 52 82 88 61 0 | ||
| 34 | 68 21 59 75 71 | ||
| 35 | 86 36 39 20 48 | ||
| 36 | 50 40 19 6 34 | ||
| 37 | 93 26 14 41 49 | ||
| 38 | |||
| 39 | 74 18 93 59 77 | ||
| 40 | 14 45 57 61 92 | ||
| 41 | 10 78 42 63 52 | ||
| 42 | 87 3 0 62 20 | ||
| 43 | 25 64 48 22 96 | ||
| 44 | |||
| 45 | 11 73 88 47 30 | ||
| 46 | 10 6 5 25 67 | ||
| 47 | 89 41 62 94 85 | ||
| 48 | 45 99 58 7 57 | ||
| 49 | 77 19 66 43 48 | ||
| 50 | |||
| 51 | 94 47 45 73 44 | ||
| 52 | 22 8 84 79 6 | ||
| 53 | 14 58 26 92 5 | ||
| 54 | 40 48 42 25 2 | ||
| 55 | 37 76 18 80 74 | ||
| 56 | |||
| 57 | 15 3 89 77 98 | ||
| 58 | 13 99 10 97 59 | ||
| 59 | 18 96 64 47 37 | ||
| 60 | 68 92 90 56 11 | ||
| 61 | 76 81 12 91 69 | ||
| 62 | |||
| 63 | 82 97 69 47 10 | ||
| 64 | 51 12 41 23 45 | ||
| 65 | 71 6 67 80 46 | ||
| 66 | 31 70 40 9 42 | ||
| 67 | 27 1 17 25 74 | ||
| 68 | |||
| 69 | 2 77 1 37 29 | ||
| 70 | 50 8 87 12 76 | ||
| 71 | 74 88 48 60 79 | ||
| 72 | 41 35 92 33 34 | ||
| 73 | 45 52 75 24 28 | ||
| 74 | |||
| 75 | 97 41 49 40 96 | ||
| 76 | 84 54 12 24 45 | ||
| 77 | 39 1 17 85 52 | ||
| 78 | 3 29 67 33 9 | ||
| 79 | 50 7 47 48 81 | ||
| 80 | |||
| 81 | 76 77 15 84 71 | ||
| 82 | 41 7 32 29 62 | ||
| 83 | 30 87 14 10 48 | ||
| 84 | 98 22 96 45 9 | ||
| 85 | 66 91 83 21 55 | ||
| 86 | |||
| 87 | 20 42 33 9 91 | ||
| 88 | 11 71 64 83 61 | ||
| 89 | 82 54 67 38 60 | ||
| 90 | 77 57 81 78 98 | ||
| 91 | 18 1 27 55 87 | ||
| 92 | |||
| 93 | 7 13 36 93 47 | ||
| 94 | 45 25 44 58 72 | ||
| 95 | 74 80 52 24 15 | ||
| 96 | 64 43 96 42 20 | ||
| 97 | 82 10 73 46 57 | ||
| 98 | |||
| 99 | 40 36 86 87 76 | ||
| 100 | 16 11 70 81 25 | ||
| 101 | 55 31 83 72 88 | ||
| 102 | 57 33 44 58 5 | ||
| 103 | 64 15 19 67 53 | ||
| 104 | |||
| 105 | 61 95 27 3 20 | ||
