Advertisement
Guest User

AoC 2022 - Day 11

a guest
Dec 11th, 2022
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.43 KB | None | 0 0
  1. """
  2. Advent of Code 2022 Day 11
  3. """
  4. import sys
  5.  
  6. from dataclasses import dataclass
  7. from math import prod
  8.  
  9. from advent_tools import get_daily_input
  10.  
  11. DAY = 11
  12.  
  13. DEBUG = sys.argv[1] == "debug" if len(sys.argv) > 1 else False
  14.  
  15. DEBUG_DATA = """
  16. Monkey 0:
  17.  Starting items: 79, 98
  18.  Operation: new = old * 19
  19.  Test: divisible by 23
  20.    If true: throw to monkey 2
  21.    If false: throw to monkey 3
  22.  
  23. Monkey 1:
  24.  Starting items: 54, 65, 75, 74
  25.  Operation: new = old + 6
  26.  Test: divisible by 19
  27.    If true: throw to monkey 2
  28.    If false: throw to monkey 0
  29.  
  30. Monkey 2:
  31.  Starting items: 79, 60, 97
  32.  Operation: new = old * old
  33.  Test: divisible by 13
  34.    If true: throw to monkey 1
  35.    If false: throw to monkey 3
  36.  
  37. Monkey 3:
  38.  Starting items: 74
  39.  Operation: new = old + 3
  40.  Test: divisible by 17
  41.    If true: throw to monkey 0
  42.    If false: throw to monkey 1
  43. """
  44.  
  45. if DEBUG:
  46.     def get_daily_input(_):
  47.         for line in DEBUG_DATA.strip().split("\n"):
  48.             yield line.strip("\n")
  49.  
  50.  
  51. @dataclass(kw_only=True)
  52. class Monkey:
  53.     items: list[int]
  54.     operation: str
  55.     test_divisible: int
  56.     if_true: int
  57.     if_false: int
  58.     all_monkeys: list["Monkey"]
  59.     inspected_count: int = 0
  60.  
  61.     def __post_init__(self):
  62.         self.operation_func = lambda old: eval(self.operation)
  63.  
  64.     def process_items(self, worry_level_divisor: int = 1, mod_factor: int = 0):
  65.         for item in self.items:
  66.             item = self.operation_func(item)
  67.             item = int(item / worry_level_divisor)
  68.             if mod_factor:
  69.                 item = item % mod_factor
  70.             if item % self.test_divisible == 0:
  71.                 self.all_monkeys[self.if_true].items.append(item)
  72.             else:
  73.                 self.all_monkeys[self.if_false].items.append(item)
  74.             self.inspected_count += 1
  75.         self.items = []
  76.  
  77.  
  78. def load_monkeys() -> list[Monkey]:
  79.     monkeys: list[Monkey] = []
  80.  
  81.     monkey_data: list[str] = [""]
  82.     for line in get_daily_input(DAY):
  83.         if not line:
  84.             monkey_data.append("")
  85.         else:
  86.             monkey_data[-1] += line + "\n"
  87.  
  88.     for monkey in monkey_data:
  89.         rows = monkey.split("\n")
  90.         items = eval("[" + rows[1].split(": ")[1] + "]")
  91.         operation = rows[2].split(" = ")[1]
  92.         test_divisible = int(rows[3].split(" by ")[1])
  93.         if_true = int(rows[4].split(" monkey ")[1])
  94.         if_false = int(rows[5].split(" monkey ")[1])
  95.         monkeys.append(
  96.             Monkey(
  97.                 items=items,
  98.                 operation=operation,
  99.                 test_divisible=test_divisible,
  100.                 if_true=if_true,
  101.                 if_false=if_false,
  102.                 all_monkeys=monkeys
  103.             )
  104.         )
  105.    
  106.     return monkeys
  107.  
  108.  
  109. def part_1() -> int:
  110.     monkeys = load_monkeys()
  111.    
  112.     for _ in range(20):
  113.         for monkey in monkeys:
  114.             monkey.process_items(worry_level_divisor=3)
  115.  
  116.     return prod(sorted([m.inspected_count for m in monkeys], reverse=True)[0:2])
  117.  
  118.  
  119. def part_2() -> int:
  120.     monkeys = load_monkeys()
  121.  
  122.     mod_factor = prod([m.test_divisible for m in monkeys])
  123.     for _ in range(10000):
  124.         for monkey in monkeys:
  125.             monkey.process_items(mod_factor=mod_factor)
  126.  
  127.     return prod(sorted([m.inspected_count for m in monkeys], reverse=True)[0:2])
  128.  
  129.  
  130. def main():
  131.     print(f"Part 1: {part_1()}")
  132.     print(f"Part 2: {part_2()}")
  133.  
  134.  
  135. if __name__ == "__main__":
  136.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement