From 36b33242be51e7cdf8376967c62f34a6acffdc03 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Sun, 11 Dec 2022 07:40:32 +0100 Subject: [PATCH] day11 --- day11.py | 100 ++++++++++++++++++++++++++++++++++++++++++++ inputs/input11 | 55 ++++++++++++++++++++++++ inputs/input11_test | 27 ++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 day11.py create mode 100644 inputs/input11 create mode 100644 inputs/input11_test diff --git a/day11.py b/day11.py new file mode 100644 index 0000000..1dac86e --- /dev/null +++ b/day11.py @@ -0,0 +1,100 @@ +from collections import defaultdict +from math import lcm +from tools.aoc import AOCDay +from typing import Any + + +class Monkey: + def __init__(self, monkey_id: int): + self.monkey_id = monkey_id + self.items = [] + self.operation = None + self.test = None + self.action_true = None + self.action_false = None + + def turn(self, part2: bool = False): + for _ in range(len(self.items)): + item = self.items.pop(0) + op, right = self.operation + + if op == "+": + item += int(right) + elif right == "old": + item *= item + else: + item *= int(right) + + if not part2: + item //= 3 + + if item % self.test == 0: + yield item, self.action_true + else: + yield item, self.action_false + + +class Day(AOCDay): + inputs = [ + [ + (10605, "input11_test"), + (98280, "input11"), + ], + [ + (2713310158, "input11_test"), + (17673687232, "input11"), + ] + ] + + def get_monkeys(self) -> list: + monkeys = {} + current_monkey = None + for line in self.getInput(): + if not line: + continue + + if line.startswith("Monkey"): + current_monkey = Monkey(int(line[:-1].split(" ")[1])) + monkeys[current_monkey.monkey_id] = current_monkey + elif line.startswith(" Starting items:"): + current_monkey.items = list(map(int, line.split(": ")[1].split(", "))) + elif line.startswith(" Operation"): + current_monkey.operation = line.split(": ")[1].split(" = ")[1].split(" ")[1:] + elif line.startswith(" Test:"): + current_monkey.test = int(line.split(" ")[-1]) + elif line.startswith(" If true:"): + current_monkey.action_true = int(line.split(" ")[-1]) + elif line.startswith(" If false:"): + current_monkey.action_false = int(line.split(" ")[-1]) + else: + print("Don't know how to parse '", line, "'") + + return [monkeys[x] for x in sorted(monkeys)] + + def get_monkey_business(self, amount: int = 20, part2: bool = False) -> int: + monkeys = self.get_monkeys() + monkey_inspects = defaultdict(int) + modder = lcm(*[m.test for m in monkeys]) + + for _ in range(amount): + for monkey in monkeys: + for item, target in monkey.turn(part2): + monkey_inspects[monkey.monkey_id] += 1 + if part2: + monkeys[target].items.append(item % modder) + else: + monkeys[target].items.append(item) + + f = sorted(monkey_inspects.values())[-2:] + return f[0] * f[1] + + def part1(self) -> Any: + return self.get_monkey_business(20, False) + + def part2(self) -> Any: + return self.get_monkey_business(10_000, True) + + +if __name__ == '__main__': + day = Day(2022, 11) + day.run(verbose=True) diff --git a/inputs/input11 b/inputs/input11 new file mode 100644 index 0000000..79e7808 --- /dev/null +++ b/inputs/input11 @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 56, 52, 58, 96, 70, 75, 72 + Operation: new = old * 17 + Test: divisible by 11 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 75, 58, 86, 80, 55, 81 + Operation: new = old + 7 + Test: divisible by 3 + If true: throw to monkey 6 + If false: throw to monkey 5 + +Monkey 2: + Starting items: 73, 68, 73, 90 + Operation: new = old * old + Test: divisible by 5 + If true: throw to monkey 1 + If false: throw to monkey 7 + +Monkey 3: + Starting items: 72, 89, 55, 51, 59 + Operation: new = old + 1 + Test: divisible by 7 + If true: throw to monkey 2 + If false: throw to monkey 7 + +Monkey 4: + Starting items: 76, 76, 91 + Operation: new = old * 3 + Test: divisible by 19 + If true: throw to monkey 0 + If false: throw to monkey 3 + +Monkey 5: + Starting items: 88 + Operation: new = old + 4 + Test: divisible by 2 + If true: throw to monkey 6 + If false: throw to monkey 4 + +Monkey 6: + Starting items: 64, 63, 56, 50, 77, 55, 55, 86 + Operation: new = old + 8 + Test: divisible by 13 + If true: throw to monkey 4 + If false: throw to monkey 0 + +Monkey 7: + Starting items: 79, 58 + Operation: new = old + 6 + Test: divisible by 17 + If true: throw to monkey 1 + If false: throw to monkey 5 diff --git a/inputs/input11_test b/inputs/input11_test new file mode 100644 index 0000000..c04eddb --- /dev/null +++ b/inputs/input11_test @@ -0,0 +1,27 @@ +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 \ No newline at end of file