diff options
| -rw-r--r-- | conftest.py | 9 | ||||
| -rw-r--r-- | day3/__init__.py | 96 | ||||
| -rw-r--r-- | day3/example.txt | 12 | ||||
| -rw-r--r-- | day3/input.txt | 1000 |
4 files changed, 1111 insertions, 6 deletions
diff --git a/conftest.py b/conftest.py index 3bae1e2..4832011 100644 --- a/conftest.py +++ b/conftest.py | |||
| @@ -12,13 +12,11 @@ def pytest_generate_tests(metafunc: Metafunc): | |||
| 12 | if 'assignment' in metafunc.fixturenames: | 12 | if 'assignment' in metafunc.fixturenames: |
| 13 | packages = [ | 13 | packages = [ |
| 14 | importlib.import_module(package.name) | 14 | importlib.import_module(package.name) |
| 15 | for package | 15 | for package in walk_packages([dir_path]) |
| 16 | in walk_packages([dir_path]) | ||
| 17 | if package.name.startswith('day') | ||
| 18 | ] | 16 | ] |
| 19 | 17 | ||
| 20 | assignments = [ | 18 | assignments = [ |
| 21 | (getattr(package, f'Assignment{day(part)}'), package) | 19 | (getattr(package, f'Assignment{day(part)}', None), package) |
| 22 | for package in packages | 20 | for package in packages |
| 23 | for part in ['1', '2'] | 21 | for part in ['1', '2'] |
| 24 | ] | 22 | ] |
| @@ -27,8 +25,7 @@ def pytest_generate_tests(metafunc: Metafunc): | |||
| 27 | argnames=f'assignment', | 25 | argnames=f'assignment', |
| 28 | argvalues=[ | 26 | argvalues=[ |
| 29 | Assignment(path=package.__path__[0]) | 27 | Assignment(path=package.__path__[0]) |
| 30 | for (Assignment, package) | 28 | for (Assignment, package) in assignments |
| 31 | in assignments | ||
| 32 | if Assignment is not None | 29 | if Assignment is not None |
| 33 | ], | 30 | ], |
| 34 | ids=lambda assignment: str(assignment) | 31 | ids=lambda assignment: str(assignment) |
diff --git a/day3/__init__.py b/day3/__init__.py new file mode 100644 index 0000000..29f4ab3 --- /dev/null +++ b/day3/__init__.py | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | from collections import Counter | ||
| 2 | from copy import copy | ||
| 3 | from dataclasses import dataclass | ||
| 4 | from typing import Iterator, List | ||
| 5 | |||
| 6 | from aoc import BaseAssignment | ||
| 7 | |||
| 8 | class Assignment(BaseAssignment): | ||
| 9 | def read_input(self, example = False) -> List[str]: | ||
| 10 | return list(super().read_input(example)) | ||
| 11 | |||
| 12 | @staticmethod | ||
| 13 | def flip(bits: str) -> str: | ||
| 14 | return bin(~int(bits, 2) + (1 << len(bits))).strip('0b') | ||
| 15 | |||
| 16 | |||
| 17 | class AssignmentOne(Assignment): | ||
| 18 | example_result = 198 | ||
| 19 | @staticmethod | ||
| 20 | def convert(input: List[str]) -> List[List[str]]: | ||
| 21 | items = [] | ||
| 22 | for item in input: | ||
| 23 | for index, char in enumerate([char for char in item]): | ||
| 24 | try: | ||
| 25 | items[index].append(char) | ||
| 26 | except IndexError: | ||
| 27 | items.append([char]) | ||
| 28 | |||
| 29 | return items | ||
| 30 | |||
| 31 | @staticmethod | ||
| 32 | def gamma_rate(input: List[str]) -> str: | ||
| 33 | converted = AssignmentOne.convert(input) | ||
| 34 | return ''.join([ | ||
| 35 | Counter(i).most_common(1)[0][0] | ||
| 36 | for i | ||
| 37 | in converted | ||
| 38 | ]) | ||
| 39 | |||
| 40 | @staticmethod | ||
| 41 | def epsilon_rate(input: List[str]) -> str: | ||
| 42 | return Assignment.flip(AssignmentOne.gamma_rate(input)) | ||
| 43 | |||
| 44 | def run(self, input: List[str]) -> int: | ||
| 45 | return int(self.gamma_rate(input), 2) * int(self.epsilon_rate(input), 2) | ||
| 46 | |||
| 47 | |||
| 48 | class AssignmentTwo(Assignment): | ||
| 49 | example_result = 230 | ||
| 50 | |||
| 51 | @staticmethod | ||
| 52 | def oxygen_generator_rating(input: List[str]): | ||
| 53 | bit_length = len(input[0]) | ||
| 54 | |||
| 55 | modified_input = copy(input) | ||
| 56 | bits = '' | ||
| 57 | for i in range(bit_length): | ||
| 58 | count = Counter([_[i] for _ in modified_input]).most_common(2) | ||
| 59 | |||
| 60 | most_used = count[0] | ||
| 61 | most_used_count = most_used[1] | ||
| 62 | least_used = count[-1] | ||
| 63 | least_used_count = least_used[1] | ||
| 64 | |||
| 65 | bit = '1' if most_used_count == least_used_count else most_used[0] | ||
| 66 | |||
| 67 | bits += bit | ||
| 68 | modified_input = list(filter(lambda _: _[i] == bit, modified_input)) | ||
| 69 | |||
| 70 | return bits | ||
| 71 | |||
| 72 | @staticmethod | ||
| 73 | def co2_scrubbing_rating(input: List[str]): | ||
| 74 | bit_length = len(input[0]) | ||
| 75 | |||
| 76 | modified_input = copy(input) | ||
| 77 | for i in range(bit_length): | ||
| 78 | if len(modified_input) == 1: | ||
| 79 | return modified_input[0] | ||
| 80 | |||
| 81 | count = Counter([_[i] for _ in modified_input]).most_common(2) | ||
| 82 | |||
| 83 | most_used = count[0] | ||
| 84 | most_used_count = most_used[1] | ||
| 85 | least_used = count[-1] | ||
| 86 | least_used_count = least_used[1] | ||
| 87 | |||
| 88 | bit = '0' if most_used_count == least_used_count else least_used[0] | ||
| 89 | |||
| 90 | modified_input = list(filter(lambda _: _[i] == bit, modified_input)) | ||
| 91 | |||
| 92 | |||
| 93 | def run(self, input: List[str]) -> int: | ||
| 94 | return int(AssignmentTwo.oxygen_generator_rating(input), 2) \ | ||
| 95 | * int(AssignmentTwo.co2_scrubbing_rating(input), 2) | ||
| 96 | |||
diff --git a/day3/example.txt b/day3/example.txt new file mode 100644 index 0000000..665fd57 --- /dev/null +++ b/day3/example.txt | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | 00100 | ||
| 2 | 11110 | ||
| 3 | 10110 | ||
| 4 | 10111 | ||
| 5 | 10101 | ||
| 6 | 01111 | ||
| 7 | 00111 | ||
| 8 | 11100 | ||
| 9 | 10000 | ||
| 10 | 11001 | ||
| 11 | 00010 | ||
| 12 | 01010 \ No newline at end of file | ||
diff --git a/day3/input.txt b/day3/input.txt new file mode 100644 index 0000000..16977ec --- /dev/null +++ b/day3/input.txt | |||
| @@ -0,0 +1,1000 @@ | |||
| 1 | 000110000001 | ||
| 2 | 011011001101 | ||
| 3 | 001101100111 | ||
| 4 | 001101011001 | ||
| 5 | 110111011101 | ||
| 6 | 110011101010 | ||
| 7 | 111101010001 | ||
| 8 | 010100111101 | ||
| 9 | 011000011000 | ||
| 10 | 001110110011 | ||
| 11 | 001100010110 | ||
| 12 | 110111101100 | ||
| 13 | 110001111100 | ||
| 14 | 001011111100 | ||
| 15 | 000000011010 | ||
| 16 | 110101100111 | ||
| 17 | 011000011111 | ||
| 18 | 011000000111 | ||
| 19 | 011111000110 | ||
| 20 | 100101110111 | ||
| 21 | 010101001110 | ||
| 22 | 111101000011 | ||
| 23 | 010010010110 | ||
| 24 | 100100011111 | ||
| 25 | 101011001110 | ||
| 26 | 001111110000 | ||
| 27 | 110000011111 | ||
| 28 | 110000011000 | ||
| 29 | 011001111100 | ||
| 30 | 010010001101 | ||
| 31 | 000111001110 | ||
| 32 | 110111001110 | ||
| 33 | 110001010101 | ||
| 34 | 100111011001 | ||
| 35 | 000101110000 | ||
| 36 | 110001011100 | ||
| 37 | 111101010010 | ||
| 38 | 101011000001 | ||
| 39 | 001101001111 | ||
| 40 | 110111101010 | ||
| 41 | 101111111000 | ||
| 42 | 110101000110 | ||
| 43 | 011111001001 | ||
| 44 | 001110100001 | ||
| 45 | 010100110111 | ||
| 46 | 110100000110 | ||
| 47 | 101010110010 | ||
| 48 | 100100101110 | ||
| 49 | 101111011110 | ||
| 50 | 000110110101 | ||
| 51 | 011011110101 | ||
| 52 | 111001011110 | ||
| 53 | 110110100111 | ||
| 54 | 000100010001 | ||
| 55 | 001101010110 | ||
| 56 | 100011000110 | ||
| 57 | 001110010010 | ||
| 58 | 010111110111 | ||
| 59 | 011010011101 | ||
| 60 | 110000011100 | ||
| 61 | 010100001001 | ||
| 62 | 000110100000 | ||
| 63 | 101001010000 | ||
| 64 | 000001110000 | ||
| 65 | 101110010011 | ||
| 66 | 010011100111 | ||
| 67 | 010011011000 | ||
| 68 | 110111011111 | ||
| 69 | 000111010010 | ||
| 70 | 101010111010 | ||
| 71 | 111001100100 | ||
| 72 | 101110100011 | ||
| 73 | 111101111110 | ||
| 74 | 010111111000 | ||
| 75 | 010010001111 | ||
| 76 | 110010000011 | ||
| 77 | 001110000010 | ||
| 78 | 100101111110 | ||
| 79 | 000100101001 | ||
| 80 | 101101010000 | ||
| 81 | 111111010000 | ||
| 82 | 101010011000 | ||
| 83 | 011100100001 | ||
| 84 | 011101101000 | ||
| 85 | 001010010100 | ||
| 86 | 010010100011 | ||
| 87 | 110011111111 | ||
| 88 | 110100011001 | ||
| 89 | 111010011110 | ||
| 90 | 011110001101 | ||
| 91 | 011010011100 | ||
| 92 | 100100000001 | ||
| 93 | 111111001010 | ||
| 94 | 110100110011 | ||
| 95 | 110100011111 | ||
| 96 | 100010001110 | ||
| 97 | 101000111100 | ||
| 98 | 100001110010 | ||
| 99 | 110101010011 | ||
| 100 | 101010011101 | ||
| 101 | 011010011010 | ||
| 102 | 101110101101 | ||
| 103 | 001100011010 | ||
| 104 | 101001010101 | ||
| 105 | 101010000100 | ||
| 106 | 000110101010 | ||
| 107 | |||
