Avent of Code - Day 11 - Monkey in the Middle

in adventofcode •  2 years ago 

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])

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])

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!

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE BLURT!