diff options
| -rw-r--r-- | aoc/decorators.py | 17 | ||||
| -rw-r--r-- | day21/__init__.py | 122 | ||||
| -rw-r--r-- | day21/example.txt | 15 | ||||
| -rw-r--r-- | day21/input.txt | 2727 |
4 files changed, 2879 insertions, 2 deletions
diff --git a/aoc/decorators.py b/aoc/decorators.py index a31993a..42603c2 100644 --- a/aoc/decorators.py +++ b/aoc/decorators.py | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- |
| 2 | from functools import wraps | 2 | from functools import wraps |
| 3 | from typing import Iterator, TypeVar, Callable | 3 | from typing import Iterator, TypeVar, Callable, List |
| 4 | 4 | ||
| 5 | T = TypeVar("T") | 5 | T = TypeVar("T") |
| 6 | I = TypeVar("I") | ||
| 6 | 7 | ||
| 8 | AssignmentRun = Callable[[Iterator[I], ...], Iterator[T]] | ||
| 9 | AssignmentRunList = Callable[[List[I], ...], Iterator[T]] | ||
| 7 | 10 | ||
| 8 | def infinite_generator(func: Callable[[...], Iterator[T]]): | 11 | |
| 12 | def infinite_generator(func: AssignmentRun) -> AssignmentRun: | ||
| 9 | @wraps(func) | 13 | @wraps(func) |
| 10 | def wrapper(*args, **kwargs): | 14 | def wrapper(*args, **kwargs): |
| 11 | items = list(func(*args, **kwargs)) | 15 | items = list(func(*args, **kwargs)) |
| @@ -15,3 +19,12 @@ def infinite_generator(func: Callable[[...], Iterator[T]]): | |||
| 15 | yield item | 19 | yield item |
| 16 | 20 | ||
| 17 | return wrapper | 21 | return wrapper |
| 22 | |||
| 23 | |||
| 24 | def list_input(func: AssignmentRun) -> AssignmentRunList: | ||
| 25 | @wraps(func) | ||
| 26 | def wrapper(self, input: Iterator, *args, **kwargs) -> T: | ||
| 27 | |||
| 28 | return func(self, list(input), *args, **kwargs) | ||
| 29 | |||
| 30 | return wrapper | ||
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 | ||
diff --git a/day21/example.txt b/day21/example.txt new file mode 100644 index 0000000..e14be60 --- /dev/null +++ b/day21/example.txt | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | root: pppw + sjmn | ||
| 2 | dbpl: 5 | ||
| 3 | cczh: sllz + lgvd | ||
| 4 | zczc: 2 | ||
| 5 | ptdq: humn - dvpt | ||
| 6 | dvpt: 3 | ||
| 7 | lfqf: 4 | ||
| 8 | humn: 5 | ||
| 9 | ljgn: 2 | ||
| 10 | sjmn: drzm * dbpl | ||
| 11 | sllz: 4 | ||
| 12 | pppw: cczh / lfqf | ||
| 13 | lgvd: ljgn * ptdq | ||
| 14 | drzm: hmdt - zczc | ||
| 15 | hmdt: 32 | ||
diff --git a/day21/input.txt b/day21/input.txt new file mode 100644 index 0000000..0696184 --- /dev/null +++ b/day21/input.txt | |||
| @@ -0,0 +1,2727 @@ | |||
| 1 | cjdb: 3 | ||
| 2 | hhfs: 5 | ||
| 3 | jvjn: 4 | ||
| 4 | tjzm: bngm * mrfm | ||
| 5 | mbbs: 2 | ||
| 6 | dzlq: tcdz * bjdj | ||
| 7 | htzp: 3 | ||
| 8 | hsmn: 5 | ||
| 9 | sblh: 2 | ||
| 10 | pghw: 5 | ||
| 11 | pqtp: vtcr * bcts | ||
| 12 | mvgz: 2 | ||
| 13 | sszn: 3 | ||
| 14 | zqlr: nlfq * htfq | ||
| 15 | djsb: 2 | ||
| 16 | vccw: zzsz * thbz | ||
| 17 | tlvg: fncr + glvj | ||
| 18 | grql: nqch * jhmw | ||
| 19 | rngv: 4 | ||
| 20 | prjv: 2 | ||
| 21 | rmdl: lzdr * qpzh | ||
| 22 | pdqm: 2 | ||
| 23 | jrpn: zcnv + pgqr | ||
| 24 | llzf: 2 | ||
| 25 | bzfp: qbwz + zsts | ||
| 26 | bvsf: rbcd + npcs | ||
| 27 | jmpm: 3 | ||
| 28 | zgrs: 15 | ||
| 29 | lcrs: 5 | ||
| 30 | cqcc: swtj + wnzt | ||
| 31 | vhts: 2 | ||
| 32 | pbgz: 1 | ||
| 33 | mqpb: 2 | ||
| 34 | jzcf: 2 | ||
| 35 | sfls: 10 | ||
| 36 | cnhh: 8 | ||
| 37 | clsh: mcwb * jfrq | ||
| 38 | cqch: 4 | ||
| 39 | brvd: 19 | ||
| 40 | fprh: 2 | ||
| 41 | dccm: gbhn / tczb | ||
| 42 | wmgt: ldsd + csmf | ||
| 43 | hbrs: 6 | ||
| 44 | bjqq: 12 | ||
| 45 | pvnl: 6 | ||
| 46 | htdg: 2 | ||
| 47 | tpcm: hfdz * sfrt | ||
| 48 | sgcj: slfv * wzdf | ||
| 49 | fljs: 2 | ||
| 50 | qmml: 2 | ||
| 51 | sbqt: 2 | ||
| 52 | wjqn: 4 | ||
| 53 | fmzj: 1 | ||
| 54 | dnwt: 18 | ||
| 55 | dzld: rvhr * jfjj | ||
| 56 | qnfn: mrhp * wlhj | ||
| 57 | sccz: 3 | ||
| 58 | lbcv: hqjn + lhcg | ||
| 59 | bwdw: 16 | ||
| 60 | jmgq: czzm * sjqr | ||
| 61 | zqnd: fhfm + sstq | ||
| 62 | mlwd: 3 | ||
| 63 | mpnz: vdqm * ccgq | ||
| 64 | bcsn: cmrp * prhj | ||
| 65 | gsvq: cqcc / twjg | ||
| 66 | zcgv: 4 | ||
| 67 | sjvd: cvsz * zdmr | ||
| 68 | fzwf: 5 | ||
| 69 | cdpv: 1 | ||
| 70 | ndcq: 4 | ||
| 71 | mvps: 2 | ||
| 72 | twsv: qfsn * pmrb | ||
| 73 | gglt: nlnl * cjdb | ||
| 74 | pvnm: 1 | ||
| 75 | wcfh: 7 | ||
