From 07ee5861d143aa01a051c1ecae3b895af6eb029c Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Thu, 22 Dec 2022 23:46:15 -0600 Subject: [PATCH] day 11 --- flake.nix | 2 +- py-ver/11.py | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++ py-ver/11.txt | 55 ++++++++++++++++++++ 3 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 py-ver/11.py create mode 100644 py-ver/11.txt diff --git a/flake.nix b/flake.nix index 3e0a4c4..a440dc6 100644 --- a/flake.nix +++ b/flake.nix @@ -7,7 +7,7 @@ devShell = pkgs.mkShell { packages = with pkgs; [ - (python3.withPackages (p: with p; [ more-itertools ])) + (python3.withPackages (p: with p; [ more-itertools tqdm ])) ruby swiProlog yabasic diff --git a/py-ver/11.py b/py-ver/11.py new file mode 100644 index 0000000..ec198f6 --- /dev/null +++ b/py-ver/11.py @@ -0,0 +1,137 @@ +from tqdm import tqdm +import re +import math +from queue import Queue + + +with open("11.txt") as f: + data = f.read() + +ex_data = """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""" + +re1 = re.compile(r"^Monkey (\d+):$") +re2 = re.compile(r"^\s*Starting items: (\d+(, \d+)*)$") +re3 = re.compile(r"^\s*Operation: new = (.*)$") +re4 = re.compile(r"^\s*Test: divisible by (\d+)$") +re5 = re.compile(r"^\s*If true: throw to monkey (\d+)$") +re6 = re.compile(r"^\s*If false: throw to monkey (\d+)$") +def parse_data(data): + monkeys = dict() + monkey_data = data.split("\n\n") + for segment in monkey_data: + lines = segment.splitlines() + m = re1.match(lines[0]) + monkey_num = int(m.group(1)) + m = re2.match(lines[1]) + starting_items = list(map(int, m.group(1).split(", "))) + m = re3.match(lines[2]) + expr = m.group(1) + operation = eval(f"lambda old: {expr}") + m = re4.match(lines[3]) + div_by = int(m.group(1)) + m = re5.match(lines[4]) + throw_true = int(m.group(1)) + m = re6.match(lines[5]) + throw_false = int(m.group(1)) + monkey = dict(starting_items = starting_items, + operation = operation, + div_by = div_by, + throw_true = throw_true, + throw_false = throw_false) + monkeys[monkey_num] = monkey + + return monkeys + +def solve1(data): + data = parse_data(data) + + cur_items = [] + for monkey_num in range(len(data)): + monkey_info = data[monkey_num] + q = [] + for item in monkey_info["starting_items"]: + q.append(item) + cur_items.append(q) + # print(cur_items) + + cts = [0] * len(data) + + for i in range(20): + for monkey_num, monkey_items in enumerate(cur_items): + for item in monkey_items: + new_worry = data[monkey_num]["operation"](item) + new_worry //= 3 + is_divisible = new_worry % data[monkey_num]["div_by"] == 0 + next_monkey = data[monkey_num]["throw_true" if is_divisible else "throw_false"] + cur_items[next_monkey].append(new_worry) + cts[monkey_num] += len(monkey_items) + cur_items[monkey_num] = [] + + # print(cur_items) + + print(math.prod(sorted(cts, reverse=True)[:2])) + +def solve2(data): + data = parse_data(data) + + cur_items = [] + modulus = 1 + for monkey_num in range(len(data)): + monkey_info = data[monkey_num] + modulus *= monkey_info["div_by"] + q = [] + for item in monkey_info["starting_items"]: + q.append(item) + cur_items.append(q) + # print(cur_items) + + # print(modulus) + cts = [0] * len(data) + + for i in range(10000): + for monkey_num, monkey_items in enumerate(cur_items): + for item in monkey_items: + new_worry = data[monkey_num]["operation"](item) + new_worry %= modulus + is_divisible = new_worry % data[monkey_num]["div_by"] == 0 + next_monkey = data[monkey_num]["throw_true" if is_divisible else "throw_false"] + cur_items[next_monkey].append(new_worry) + cts[monkey_num] += len(monkey_items) + cur_items[monkey_num] = [] + + # if i % 100 == 0: print(cur_items) + # print(cur_items) + + print(math.prod(sorted(cts, reverse=True)[:2])) + +solve1(ex_data) +solve1(data) + +solve2(ex_data) +solve2(data) diff --git a/py-ver/11.txt b/py-ver/11.txt new file mode 100644 index 0000000..20b4b0a --- /dev/null +++ b/py-ver/11.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 98, 89, 52 + Operation: new = old * 2 + Test: divisible by 5 + If true: throw to monkey 6 + If false: throw to monkey 1 + +Monkey 1: + Starting items: 57, 95, 80, 92, 57, 78 + Operation: new = old * 13 + Test: divisible by 2 + If true: throw to monkey 2 + If false: throw to monkey 6 + +Monkey 2: + Starting items: 82, 74, 97, 75, 51, 92, 83 + Operation: new = old + 5 + Test: divisible by 19 + If true: throw to monkey 7 + If false: throw to monkey 5 + +Monkey 3: + Starting items: 97, 88, 51, 68, 76 + Operation: new = old + 6 + Test: divisible by 7 + If true: throw to monkey 0 + If false: throw to monkey 4 + +Monkey 4: + Starting items: 63 + Operation: new = old + 1 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 + +Monkey 5: + Starting items: 94, 91, 51, 63 + Operation: new = old + 4 + Test: divisible by 13 + If true: throw to monkey 4 + If false: throw to monkey 3 + +Monkey 6: + Starting items: 61, 54, 94, 71, 74, 68, 98, 83 + Operation: new = old + 2 + Test: divisible by 3 + If true: throw to monkey 2 + If false: throw to monkey 7 + +Monkey 7: + Starting items: 90, 56 + Operation: new = old * old + Test: divisible by 11 + If true: throw to monkey 3 + If false: throw to monkey 5