From 1644c904de1544f788a8e88aa6c52bcd6a625b93 Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Wed, 28 Dec 2022 13:31:29 +0100 Subject: Day 21 [WIP] --- day21/__init__.py | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 day21/__init__.py (limited to 'day21/__init__.py') 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 @@ +# -*- coding: utf-8 -*- +from abc import ABC +from typing import Dict, Union, Iterator, Type, Callable, List +from operator import add, sub, mul, truediv, eq, floordiv + +from aoc import BaseAssignment +from aoc.decorators import list_input +from aoc.mixins import AStarMixin + + +class MonkeyActivity: + def __init__(self, name: str, monkeys: Dict[str, "MonkeyActivity"]): + self.name = name + self.monkeys = monkeys + self.monkeys[name] = self + + def __repr__(self): + return f"{self.name}" + + @property + def value(self) -> int: + raise NotImplementedError() + + +class Yell(MonkeyActivity): + def __init__(self, value: str, *args, **kwargs): + super().__init__(*args, **kwargs) + + self._value = int(value) + + @property + def value(self) -> int: + return self._value + + +class Operate(MonkeyActivity): + def __init__(self, a: str, b: str, operator: str, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.operator = operator + self._a = a + self._b = b + self._operator = { + "+": add, + "-": sub, + "*": mul, + "/": truediv, + }[operator] + + @property + def a(self) -> MonkeyActivity: + return self.monkeys[self._a] + + @property + def b(self) -> MonkeyActivity: + return self.monkeys[self._b] + + @property + def value(self) -> int: + return int(self._operator(self.a.value, self.b.value)) + + +class Assignment(BaseAssignment[int, MonkeyActivity], ABC): + monkeys = {} + + def parse_item(self, item: str) -> MonkeyActivity: + name, activity = item.split(": ") + activity = activity.split(" ") + + if len(activity) == 1: + return Yell(*activity, name, self.monkeys) + + a, operator, b = activity + + return Operate(a, b, operator, name, self.monkeys) + + +class AssignmentOne(Assignment): + example_result = 152 + + @list_input + def run(self, _: List[MonkeyActivity]) -> int: + return self.monkeys["root"].value + + +class AssignmentTwo(Assignment, AStarMixin[MonkeyActivity]): + example_result = 301 + + @staticmethod + def neighbours(node: MonkeyActivity): + if isinstance(node, Operate): + yield node.a + yield node.b + + @list_input + def run(self, _: List[MonkeyActivity]) -> int: + root = self.monkeys["root"] + humn = self.monkeys["humn"] + humn._value = 0 + + path = self.a_star( + root, + lambda n, _: n is humn, + self.neighbours, + ) + + for item in path: + if isinstance(item, Yell): + break + + item: Operate = item + reverse_operator = { + "+": sub, + "-": add, + "*": floordiv, + "/": mul, + }[item.operator] + + humn._value = reverse_operator(item.b.value, item.a.value) + pass + + return humn._value -- cgit v1.2.3