Alter 5 files
Add `README.md` Add `benchmark.json` Add `info.json` Add `__init__.py` Update `running-times.png`
This commit is contained in:
parent
116673eec9
commit
8e65ed458b
5 changed files with 134 additions and 0 deletions
1
challenges/2022/11-monkeyInTheMiddle/README.md
Normal file
1
challenges/2022/11-monkeyInTheMiddle/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# [Day 11: Monkey In The Middle](https://adventofcode.com/2022/day/11)
|
15
challenges/2022/11-monkeyInTheMiddle/benchmark.json
Normal file
15
challenges/2022/11-monkeyInTheMiddle/benchmark.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"day": 11,
|
||||
"dir": "challenges/2022/11-monkeyInTheMiddle",
|
||||
"implementations": {
|
||||
"Python": {
|
||||
"part.1.avg": 0.0008889389038085938,
|
||||
"part.1.max": 0.002737283706665039,
|
||||
"part.1.min": 0.0006763935089111328,
|
||||
"part.2.avg": 0.46039318370819093,
|
||||
"part.2.max": 0.6005921363830566,
|
||||
"part.2.min": 0.3884415626525879
|
||||
}
|
||||
},
|
||||
"numRuns": 250
|
||||
}
|
17
challenges/2022/11-monkeyInTheMiddle/info.json
Normal file
17
challenges/2022/11-monkeyInTheMiddle/info.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"inputFile": "input.txt",
|
||||
"testCases": {
|
||||
"one": [
|
||||
{
|
||||
"input": "Monkey 0:\n Starting items: 79, 98\n Operation: new = old * 19\n Test: divisible by 23\n If true: throw to monkey 2\n If false: throw to monkey 3\n\nMonkey 1:\n Starting items: 54, 65, 75, 74\n Operation: new = old + 6\n Test: divisible by 19\n If true: throw to monkey 2\n If false: throw to monkey 0\n\nMonkey 2:\n Starting items: 79, 60, 97\n Operation: new = old * old\n Test: divisible by 13\n If true: throw to monkey 1\n If false: throw to monkey 3\n\nMonkey 3:\n Starting items: 74\n Operation: new = old + 3\n Test: divisible by 17\n If true: throw to monkey 0\n If false: throw to monkey 1\n",
|
||||
"expected": "10605"
|
||||
}
|
||||
],
|
||||
"two": [
|
||||
{
|
||||
"input": "Monkey 0:\n Starting items: 79, 98\n Operation: new = old * 19\n Test: divisible by 23\n If true: throw to monkey 2\n If false: throw to monkey 3\n\nMonkey 1:\n Starting items: 54, 65, 75, 74\n Operation: new = old + 6\n Test: divisible by 19\n If true: throw to monkey 2\n If false: throw to monkey 0\n\nMonkey 2:\n Starting items: 79, 60, 97\n Operation: new = old * old\n Test: divisible by 13\n If true: throw to monkey 1\n If false: throw to monkey 3\n\nMonkey 3:\n Starting items: 74\n Operation: new = old + 3\n Test: divisible by 17\n If true: throw to monkey 0\n If false: throw to monkey 1\n",
|
||||
"expected": "2713310158"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
101
challenges/2022/11-monkeyInTheMiddle/py/__init__.py
Normal file
101
challenges/2022/11-monkeyInTheMiddle/py/__init__.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
from functools import reduce
|
||||
from typing import *
|
||||
from aocpy import BaseChallenge
|
||||
from dataclasses import dataclass
|
||||
import re
|
||||
|
||||
|
||||
starting_items_regex = re.compile(r" *Starting items: ((?:\d+,? ?)+)")
|
||||
operation_regex = re.compile(r" *Operation: new = (.+)")
|
||||
test_regex = re.compile(r" *Test: divisible by (\d+)")
|
||||
true_regex = re.compile(r" *If true: throw to monkey (\d+)?")
|
||||
false_regex = re.compile(r" *If false: throw to monkey (\d+)?")
|
||||
|
||||
|
||||
def compile_operation(expr: str) -> Callable[[int], int]:
|
||||
a, op, b = expr.split(" ")
|
||||
assert a == "old"
|
||||
assert op == "*" or op == "+"
|
||||
|
||||
if op == "*":
|
||||
if b == "old":
|
||||
return lambda x: x * x
|
||||
else:
|
||||
bi = int(b)
|
||||
return lambda x: x * bi
|
||||
|
||||
elif op == "+":
|
||||
if b == "old":
|
||||
return lambda x: x + x
|
||||
else:
|
||||
bi = int(b)
|
||||
return lambda x: x + bi
|
||||
|
||||
assert False, "unreachable"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Monkey:
|
||||
items: List[int]
|
||||
op: Callable[[int], int]
|
||||
divisor: int
|
||||
if_true: int
|
||||
if_false: int
|
||||
|
||||
inspections: int
|
||||
|
||||
def __init__(self, inp: str):
|
||||
self.inspections = 0
|
||||
|
||||
parts = inp.splitlines()[1:]
|
||||
self.items = list(map(int, starting_items_regex.match(parts[0]).group(1).split(", ")))
|
||||
self.divisor = int(test_regex.match(parts[2]).group(1))
|
||||
self.if_true = int(true_regex.match(parts[3]).group(1))
|
||||
self.if_false = int(false_regex.match(parts[4]).group(1))
|
||||
self.op = compile_operation(operation_regex.match(parts[1]).group(1))
|
||||
|
||||
def inspect_first(self) -> int:
|
||||
self.inspections += 1
|
||||
|
||||
item = self.items.pop(0)
|
||||
item = self.op(item)
|
||||
return item
|
||||
|
||||
def calculate_throw(self, item: int) -> int:
|
||||
return self.if_true if item % self.divisor == 0 else self.if_false
|
||||
|
||||
|
||||
def parse(instr: str) -> List[Monkey]:
|
||||
raw_monkies = instr.strip().split("\n\n")
|
||||
monke = []
|
||||
for rm in raw_monkies:
|
||||
monke.append(Monkey(rm))
|
||||
return monke
|
||||
|
||||
|
||||
def run(inp: List[Monkey], n: int, mod: Callable[[int], int]) -> int:
|
||||
for _ in range(n):
|
||||
for monkey in inp:
|
||||
while len(monkey.items) != 0:
|
||||
item = monkey.inspect_first()
|
||||
item = mod(item)
|
||||
next_monkey = monkey.calculate_throw(item)
|
||||
|
||||
inp[next_monkey].items.append(item)
|
||||
|
||||
a, b = list(sorted(inp, reverse=True, key=lambda x: x.inspections))[:2]
|
||||
return a.inspections * b.inspections
|
||||
|
||||
|
||||
class Challenge(BaseChallenge):
|
||||
|
||||
@staticmethod
|
||||
def one(instr: str) -> int:
|
||||
inp = parse(instr)
|
||||
return run(inp, 20, lambda x: x // 3)
|
||||
|
||||
@staticmethod
|
||||
def two(instr: str) -> int:
|
||||
inp = parse(instr)
|
||||
p = reduce(lambda x, y: x * y, map(lambda x: x.divisor, inp))
|
||||
return run(inp, 10000, lambda x: x % p)
|
Binary file not shown.
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 57 KiB |
Loading…
Add table
Add a link
Reference in a new issue