diff options
Diffstat (limited to 'day14/__init__.py')
| -rw-r--r-- | day14/__init__.py | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/day14/__init__.py b/day14/__init__.py new file mode 100644 index 0000000..738ea8f --- /dev/null +++ b/day14/__init__.py | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | import math | ||
| 2 | from abc import ABC | ||
| 3 | from collections import Counter | ||
| 4 | from copy import copy | ||
| 5 | from typing import List, Tuple, Union, Dict | ||
| 6 | |||
| 7 | from aoc import BaseAssignment | ||
| 8 | |||
| 9 | |||
| 10 | class Assignment(BaseAssignment, ABC): | ||
| 11 | max_pre_calculations = 4 | ||
| 12 | steps = 0 | ||
| 13 | mapping_cache = dict() | ||
| 14 | |||
| 15 | def parse_item(self, item: str) -> Union[str, Tuple[str, str], None]: | ||
| 16 | if '>' in item: | ||
| 17 | return item.split(' -> ') | ||
| 18 | |||
| 19 | if item == '': | ||
| 20 | return None | ||
| 21 | |||
| 22 | return item | ||
| 23 | |||
| 24 | |||
| 25 | def read_input(self, example = False) -> Tuple[str, Dict[str, str]]: | ||
| 26 | input = super().read_input(example) | ||
| 27 | |||
| 28 | template = next(input) | ||
| 29 | next(input) | ||
| 30 | |||
| 31 | mapping = dict(input) | ||
| 32 | |||
| 33 | return template, mapping | ||
| 34 | |||
| 35 | def run(self, input: Tuple[str, Dict[str, str]]) -> int: | ||
| 36 | template, mapping = input | ||
| 37 | |||
| 38 | counter = Counter([ | ||
| 39 | f'{template[i:i+2]}' | ||
| 40 | for i in range(len(template) - 1) | ||
| 41 | ]) | ||
| 42 | |||
| 43 | char_count = { | ||
| 44 | **{ | ||
| 45 | c: 1 if c in template else 0 | ||
| 46 | for c | ||
| 47 | in mapping.values() | ||
| 48 | }, | ||
| 49 | **Counter(template), | ||
| 50 | } | ||
| 51 | |||
| 52 | for _ in range(self.steps): | ||
| 53 | new_counter = { | ||
| 54 | pair: 0 | ||
| 55 | for pair | ||
| 56 | in mapping.keys() | ||
| 57 | } | ||
| 58 | |||
| 59 | for key, value in counter.items(): | ||
| 60 | middle = mapping[key] | ||
| 61 | |||
| 62 | char_count[middle] += value | ||
| 63 | new_counter[f'{key[0]}{middle}'] += value | ||
| 64 | new_counter[f'{middle}{key[1]}'] += value | ||
| 65 | |||
| 66 | counter = new_counter | ||
| 67 | |||
| 68 | return max(char_count.values()) - min(char_count.values()) | ||
| 69 | |||
| 70 | class AssignmentOne(Assignment): | ||
| 71 | example_result = 1588 | ||
| 72 | steps = 10 | ||
| 73 | |||
| 74 | class AssignmentTwo(Assignment): | ||
| 75 | max_pre_calculations = 4 | ||
| 76 | example_result = 2188189693529 | ||
| 77 | steps = 40 | ||
