DEV Community

DoctorLai
DoctorLai

Posted on

Avent of Code - Day 11 - Monkey in the Middle

Advent of Code occurs at Dec 01 to 25 where each day, you will need to solve a puzzle. It is Festival and the problem statement is mostly related to Christmas.

Day 11 - Monkey in the Middle

https://adventofcode.com/2022/day/11

image.png

Q1

import sys
from collections import defaultdict, deque

file1 = open(sys.argv[1], "r")

data = defaultdict(defaultdict)

current = None
while True:
        line = file1.readline()
        if not line:
                break
        line = line.strip().split()
        if not line:
                continue
        if line[0] == 'Monkey':
                current = int(line[1][:-1])
                data[current]["cnt"] = 0
        elif line[0] == 'Starting':
                data[current]["items"] = deque([x.replace(',', '') for x in line[2:]])
        elif line[0] == 'Operation:':
                data[current]["ops"] = line[3:]
        elif line[0] == 'If':
                data[current][line[1][:-1]] = int(line[-1])
        elif line[0] == 'Test:':
                data[current]["test"] = int(line[-1])

for _ in range(20):
        for monkey in data.keys():
                print(f"Monkey {monkey}:")
                for _ in range(len(data[monkey]["items"])):
                        item = data[monkey]["items"].popleft()
                        print(f"  Monkey inspects an item with a worry level of {item}.")
                        data[monkey]["cnt"] += 1
                        item = eval("".join(data[monkey]["ops"]).replace("old", str(item)))
                        print(f"    Worry level is {item}.")
                        item //= 3
                        print(f"    Monkey gets bored with item. Worry level is divided by 3 to {item}")
                        if (item % data[monkey]["test"]) == 0:
                                print(f"    Current worry level is divisible by {data[monkey]['test']}")
                                data[data[monkey]["true"]]["items"].append(item)
                                print(f"    Item with worry level {item} is thrown to monkey {data[monkey]['true']}.")
                        else:
                                print(f"    Current worry level is not divisible by {data[monkey]['test']}")
                                data[data[monkey]["false"]]["items"].append(item)
                                print(f"    Item with worry level {item} is thrown to monkey {data[monkey]['false']}.")

cnt = sorted([data[x]["cnt"] for x in data.keys()])
print(cnt[-1] * cnt[-2])
Enter fullscreen mode Exit fullscreen mode

Q2

import sys
from collections import defaultdict, deque

file1 = open(sys.argv[1], "r")

data = defaultdict(defaultdict)

current = None
X = 1
while True:
        line = file1.readline()
        if not line:
                break
        line = line.strip().split()
        if not line:
                continue
        if line[0] == 'Monkey':
                current = int(line[1][:-1])
                data[current]["cnt"] = 0
        elif line[0] == 'Starting':
                data[current]["items"] = deque([x.replace(',', '') for x in line[2:]])
        elif line[0] == 'Operation:':
                data[current]["ops"] = line[3:]
        elif line[0] == 'If':
                data[current][line[1][:-1]] = int(line[-1])
        elif line[0] == 'Test:':
                data[current]["test"] = int(line[-1])
                X *= int(line[-1])

print(X)
def quick_eval(s, n, x):
        ans = 0
        arr = []
        for i in s:
                if i == "old":
                        arr.append(int(n))
                else:
                        arr.append(i)
        arr[2] = int(arr[2])
        if arr[1] == "+":
                return arr[0] + arr[2]
        elif arr[1] == "-":
                return arr[0] - arr[2]
        elif arr[1] == "*":
                return arr[0] * arr[2] % x
        elif arr[1] == "/":
                return arr[0] // arr[2]

for _ in range(10000):
        for monkey in data.keys():
                #print(f"Monkey {monkey}:")
                #n = len(data[monkey]["items"])
                for _ in range(len(data[monkey]["items"])):
                        item = data[monkey]["items"].popleft()
                        #print(f"  Monkey inspects an item with a worry level of {item}.")
                        data[monkey]["cnt"] += 1
                        item = quick_eval(data[monkey]["ops"], item, X)
                        #print(f"    Worry level is {item}.")
                        # item //= 3
                        #print(f"    Monkey gets bored with item. Worry level is divided by 3 to {item}")
                        if (item % data[monkey]["test"]) == 0:
                                #print(f"    Current worry level is divisible by {data[monkey]['test']}")
                                data[data[monkey]["true"]]["items"].append(item)
                                #print(f"    Item with worry level {item} is thrown to monkey {data[monkey]['true']}.")
                        else:
                                #print(f"    Current worry level is not divisible by {data[monkey]['test']}")
                                data[data[monkey]["false"]]["items"].append(item)
                                #print(f"    Item with worry level {item} is thrown to monkey {data[monkey]['false']}.")

cnt = sorted([data[x]["cnt"] for x in data.keys()])
print(cnt)
print(cnt[-1] * cnt[-2])
Enter fullscreen mode Exit fullscreen mode

The question 2 - we need to keep the numbers small so that we can apply the % X to the numbers where X is the product of all the test numbers.

The eval function may be slow - considering the test data is simple, we can replace eval with a simpler function or lambda function.


Steem to the Moon!

Top comments (0)