diff options
| author | 2022-12-28 13:31:29 +0100 | |
|---|---|---|
| committer | 2022-12-28 13:31:29 +0100 | |
| commit | 1644c904de1544f788a8e88aa6c52bcd6a625b93 (patch) | |
| tree | 9818613092865c6ca527329477f350731cc2d4c6 /day21/__init__.py | |
| parent | c22544594e251613a5dbf6c4ee505716867e55e6 (diff) | |
| download | 2022-1644c904de1544f788a8e88aa6c52bcd6a625b93.tar.gz 2022-1644c904de1544f788a8e88aa6c52bcd6a625b93.tar.bz2 2022-1644c904de1544f788a8e88aa6c52bcd6a625b93.zip | |
Day 21 [WIP]main
Diffstat (limited to 'day21/__init__.py')
| -rw-r--r-- | day21/__init__.py | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/day21/__init__.py b/day21/__init__.py new file mode 100644 index 0000000..23fd520 --- /dev/null +++ b/day21/__init__.py | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | # -*- coding: utf-8 -*- | ||
| 2 | from abc import ABC | ||
| 3 | from typing import Dict, Union, Iterator, Type, Callable, List | ||
| 4 | from operator import add, sub, mul, truediv, eq, floordiv | ||
| 5 | |||
| 6 | from aoc import BaseAssignment | ||
| 7 | from aoc.decorators import list_input | ||
| 8 | from aoc.mixins import AStarMixin | ||
| 9 | |||
| 10 | |||
| 11 | class MonkeyActivity: | ||
| 12 | def __init__(self, name: str, monkeys: Dict[str, "MonkeyActivity"]): | ||
| 13 | self.name = name | ||
| 14 | self.monkeys = monkeys | ||
| 15 | self.monkeys[name] = self | ||
| 16 | |||
| 17 | def __repr__(self): | ||
| 18 | return f"{self.name}" | ||
| 19 | |||
| 20 | @property | ||
| 21 | def value(self) -> int: | ||
| 22 | raise NotImplementedError() | ||
| 23 | |||
| 24 | |||
| 25 | class Yell(MonkeyActivity): | ||
| 26 | def __init__(self, value: str, *args, **kwargs): | ||
| 27 | super().__init__(*args, **kwargs) | ||
| 28 | |||
| 29 | self._value = int(value) | ||
| 30 | |||
| 31 | @property | ||
| 32 | def value(self) -> int: | ||
| 33 | return self._value | ||
| 34 | |||
| 35 | |||
| 36 | class Operate(MonkeyActivity): | ||
| 37 | def __init__(self, a: str, b: str, operator: str, *args, **kwargs): | ||
| 38 | super().__init__(*args, **kwargs) | ||
| 39 | |||
| 40 | self.operator = operator | ||
| 41 | self._a = a | ||
| 42 | self._b = b | ||
| 43 | self._operator = { | ||
| 44 | "+": add, | ||
| 45 | "-": sub, | ||
| 46 | "*": mul, | ||
| 47 | "/": truediv, | ||
| 48 | }[operator] | ||
| 49 | |||
| 50 | @property | ||
| 51 | def a(self) -> MonkeyActivity: | ||
| 52 | return self.monkeys[self._a] | ||
| 53 | |||
| 54 | @property | ||
| 55 | def b(self) -> MonkeyActivity: | ||
| 56 | return self.monkeys[self._b] | ||
| 57 | |||
| 58 | @property | ||
| 59 | def value(self) -> int: | ||
| 60 | return int(self._operator(self.a.value, self.b.value)) | ||
| 61 | |||
| 62 | |||
| 63 | class Assignment(BaseAssignment[int, MonkeyActivity], ABC): | ||
| 64 | monkeys = {} | ||
| 65 | |||
| 66 | def parse_item(self, item: str) -> MonkeyActivity: | ||
| 67 | name, activity = item.split(": ") | ||
| 68 | activity = activity.split(" ") | ||
| 69 | |||
| 70 | if len(activity) == 1: | ||
| 71 | return Yell(*activity, name, self.monkeys) | ||
| 72 | |||
| 73 | a, operator, b = activity | ||
| 74 | |||
| 75 | return Operate(a, b, operator, name, self.monkeys) | ||
| 76 | |||
| 77 | |||
| 78 | class AssignmentOne(Assignment): | ||
| 79 | example_result = 152 | ||
| 80 | |||
| 81 | @list_input | ||
| 82 | def run(self, _: List[MonkeyActivity]) -> int: | ||
| 83 | return self.monkeys["root"].value | ||
| 84 | |||
| 85 | |||
| 86 | class AssignmentTwo(Assignment, AStarMixin[MonkeyActivity]): | ||
| 87 | example_result = 301 | ||
| 88 | |||
| 89 | @staticmethod | ||
| 90 | def neighbours(node: MonkeyActivity): | ||
| 91 | if isinstance(node, Operate): | ||
| 92 | yield node.a | ||
| 93 | yield node.b | ||
| 94 | |||
| 95 | @list_input | ||
| 96 | def run(self, _: List[MonkeyActivity]) -> int: | ||
| 97 | root = self.monkeys["root"] | ||
| 98 | humn = self.monkeys["humn"] | ||
| 99 | humn._value = 0 | ||
| 100 | |||
| 101 | path = self.a_star( | ||
| 102 | root, | ||
| 103 | lambda n, _: n is humn, | ||
| 104 | self.neighbours, | ||
| 105 | ) | ||
| 106 | |||
| 107 | for item in path: | ||
| 108 | if isinstance(item, Yell): | ||
| 109 | break | ||
| 110 | |||
| 111 | item: Operate = item | ||
| 112 | reverse_operator = { | ||
| 113 | "+": sub, | ||
| 114 | "-": add, | ||
| 115 | "*": floordiv, | ||
| 116 | "/": mul, | ||
| 117 | }[item.operator] | ||
| 118 | |||
| 119 | humn._value = reverse_operator(item.b.value, item.a.value) | ||
| 120 | pass | ||
| 121 | |||
| 122 | return humn._value | ||
