Unable to load image

ADVENT OF CODE DAY 11: MONKEY BUSINESS :marseymonke:

Those FRICKING monkeys stole your stuff! Get it back! :soycry: :!marseymonke:

(Also, remember to leave a comment if you did something interesting :marseylove:)

35
Jump in the discussion.

No email address required.

    monkeys = []
    @dataclass
    class Monkey:
        items : List[int] = dataclass_field(default_factory=list)
        operation = None
        test = 0
        test_true = 0
        test_false= 0
        inspected = 0

    def consume(s, prefix):
        assert s.startswith(prefix)
        return s[len(prefix):]

    for s in data:
        op, args = s.split(':')
        # print(f'{op!r}: {args!r}')
        if op.startswith('Monkey'):
            assert not args
            _, arg = op.split()
            assert int(arg) == len(monkeys)
            monke = Monkey()
            monkeys.append(monke)
        elif op == 'Starting items':
            monke.items = [int(s.strip()) for s in args.split(',')]
        elif op == 'Operation':
            args = consume(args, ' new = old ')
            op = args[0]
            assert op in '*+'
            arg = args[1:].strip()
            if arg != 'old':
                arg = int(arg)
            if op == '+':
                monke.operation = lambda x, arg=arg: x + (x if arg == 'old' else arg)
            else:
                monke.operation = lambda x, arg=arg: x * (x if arg == 'old' else arg)
        elif op == 'Test':
            args = consume(args, ' divisible by ')
            monke.test = int(args)
        elif op == 'If true':
            args = consume(args, ' throw to monkey ')
            monke.test_true = int(args)
        elif op == 'If false':
            args = consume(args, ' throw to monkey ')
            monke.test_false = int(args)
        else:
            assert False

    # pprint(monkeys)

    modulo = functools.reduce(operator.mul, [m.test for m in monkeys], 1)

    for round in range(10_000 if second else 20):
        for i, m in enumerate(monkeys):
            # print(f'Monke {i}')
            items = m.items
            m.items = []
            for it in items:
                m.inspected += 1
                # print(f'inspect {it}')
                it = m.operation(it)
                # print(f'worry to {it}')
                if not second:
                    it //= 3
                it %= modulo
                # print(f'worry to {it}')
                target = m.test_false if it % m.test else m.test_true
                # print(f'target {target}')
                monkeys[target].items.append(it)
        # pprint(monkeys)

    top = [-m.inspected for m in monkeys]
    heapify(top)
    a, b = heappop(top), heappop(top)
    return a * b
Jump in the discussion.

No email address required.

Are you feeling okay bud?

Jump in the discussion.

No email address required.

 top = [-m.inspected for m in monkeys]
     heapify(top)
     a, b = heappop(top), heappop(top)
     return a * b

@JollyMoon look at this shit, me being O(n) instead of sorting the whole array!

Jump in the discussion.

No email address required.

heap creation is O(n logn) tho

Jump in the discussion.

No email address required.

Link copied to clipboard
Action successful!
Error, please refresh the page and try again.