Clean monkey code.

This commit is contained in:
Mikaël Capelle 2022-12-11 11:50:23 +01:00
parent 8795d7a276
commit 9ba338a4f1

View File

@ -3,16 +3,16 @@
import copy import copy
import sys import sys
from functools import reduce from functools import reduce
from typing import Callable from typing import Callable, Final, Mapping, Sequence
class Monkey: class Monkey:
id: int id: Final[int]
items: list[int] items: Final[Sequence[int]]
worry_fn: Callable[[int], int] worry_fn: Final[Callable[[int], int]]
test_value: int test_value: Final[int]
throw_targets: dict[bool, int] throw_targets: Final[Mapping[bool, int]]
def __init__( def __init__(
self, self,
@ -48,30 +48,18 @@ def parse_monkey(lines: list[str]) -> Monkey:
# parse worry # parse worry
worry_fn: Callable[[int], int] worry_fn: Callable[[int], int]
worry_s = lines[2].split("new =")[1].strip() worry_s = lines[2].split("new =")[1].strip()
operand = worry_s.split()[-1].strip() operand = worry_s.split()[2].strip()
if worry_s.startswith("old *"): if worry_s.startswith("old *"):
if operand == "old": if operand == "old":
worry_fn = lambda w: w * w # noqa: E731
def worry_fn(w: int) -> int:
return w * w
else: else:
worry_fn = lambda w: w * int(operand) # noqa: E731
def worry_fn(w: int) -> int:
return w * int(operand)
elif worry_s.startswith("old +"): elif worry_s.startswith("old +"):
if operand == "old": if operand == "old":
worry_fn = lambda w: w + w # noqa: E731
def worry_fn(w: int) -> int:
return w + w
else: else:
worry_fn = lambda w: w + int(operand) # noqa: E731
def worry_fn(w: int) -> int:
return w + int(operand)
else: else:
assert False, worry_s assert False, worry_s
@ -92,11 +80,10 @@ def run(
monkeys: list[Monkey], n_rounds: int, me_worry_fn: Callable[[int], int] monkeys: list[Monkey], n_rounds: int, me_worry_fn: Callable[[int], int]
) -> dict[Monkey, int]: ) -> dict[Monkey, int]:
""" """
The list of monkeys is modified in place. Perform a full run.
Args: Args:
monkeys: Initial list of monkeys. The Monkey will be modified in places (their monkeys: Initial list of monkeys. The Monkey are not modified.
items attributes).
n_rounds: Number of rounds to run. n_rounds: Number of rounds to run.
me_worry_fn: Worry function to apply after the Monkey operation (e.g., divide me_worry_fn: Worry function to apply after the Monkey operation (e.g., divide
by 3 for round 1). by 3 for round 1).
@ -104,12 +91,16 @@ def run(
Returns: Returns:
A mapping containing, for each monkey, the number of items inspected. A mapping containing, for each monkey, the number of items inspected.
""" """
# copy of the items
items = {monkey: list(monkey.items) for monkey in monkeys}
# number of inspects
inspects = {monkey: 0 for monkey in monkeys} inspects = {monkey: 0 for monkey in monkeys}
for round in range(n_rounds): for round in range(n_rounds):
for monkey in monkeys: for monkey in monkeys:
for item in monkey.items: for item in items[monkey]:
inspects[monkey] += 1 inspects[monkey] += 1
# compute the new worry level # compute the new worry level
@ -119,10 +110,10 @@ def run(
target = monkey.throw_targets[item % monkey.test_value == 0] target = monkey.throw_targets[item % monkey.test_value == 0]
assert target != monkey.id assert target != monkey.id
monkeys[target].items.append(item) items[monkeys[target]].append(item)
# clear after the loop # clear after the loop
monkey.items.clear() items[monkey].clear()
return inspects return inspects