Quick actions

cmd+k|ctrl+k

Navigation

Languages

AoC 2022, day 11

Snippet info

Language

Raku

Visibility

public

Author

seaker

Created

2022-12-12T09:18:57.501368Z

Updated

2022-12-12T10:00:37.354885Z

grammar Monkey {
    rule TOP { <monkey-id> <items> <operation> <test> <action> }

    rule monkey-id { 'Monkey' <number> ':' }
    rule items     { 'Starting' 'items:' <number>+ % ',' }
    rule operation { 'Operation:' 'new' '=' 'old' <op> <operand> }
    rule test      { 'Test:' 'divisible' 'by' <number> }
    rule action    {
        'If' 'true:'  'throw' 'to' 'monkey' <number>
        'If' 'false:' 'throw' 'to' 'monkey' <number>
    }
    rule operand   { <number> | 'old' }

    token op     { '+' | '*' }
    token number { \d+ }
}

class MonkeyActions {
    method TOP($/) {
        make (|$<monkey-id>.made, |$<items>.made, 
              |$<operation>.made, |$<test>.made,
              |$<action>.made).Hash
    }

    method monkey-id($/) { make (:id($<number>.made)).Hash }
    method items($/)     { make (:items($<number>».made)).Hash }
    method operation($/) { make (:op($<op>.made), :oper($<operand>.made)).Hash }
    method test($/)      { make (:divisor($<number>.made)).Hash }
    method action($/)    { make (:targets($<number>».made.reverse.Array)).Hash }
    method operand($/)   { make $<number> ?? $<number>.made !! -1 }

    method op($/)     { make $/.Str }
    method number($/) { make $/.Int }
}

sub inspections-p1(@monkeys, UInt:D \rounds) {
    my @monkeys_ = @monkeys.deepmap(*.clone);

    for ^rounds {
        for @monkeys_ -> \mk {
            for |mk<items> -> \itm {
                my $level = do given mk<op> {
                    when '*' { itm * (mk<oper> == -1 ?? itm !! mk<oper>) }
                    when '+' { itm + (mk<oper> == -1 ?? itm !! mk<oper>) }
                } div 3;
                @monkeys_[mk<targets>[+($level %% mk<divisor>)]]<items>.push($level);

                ++mk<inspection>;
            }
            mk<items> = [ ];
        }
    }

    @monkeys_.map(*<inspection>).Array
}

sub inspections-p2(@monkeys, UInt:D \rounds) {
    my @monkeys_ = @monkeys.deepmap(*.clone);
    my $modulo = [*] @monkeys.map(*<divisor>);

    for ^rounds {
        for @monkeys_ -> \mk {
            for |mk<items> -> \itm {
                my $level = do given mk<op> {
                    when '*' { itm * (mk<oper> == -1 ?? itm !! mk<oper>) }
                    when '+' { itm + (mk<oper> == -1 ?? itm !! mk<oper>) }
                } mod $modulo;
                @monkeys_[mk<targets>[+($level %% mk<divisor>)]]<items>.push($level);

                ++mk<inspection>;
            }
            mk<items> = [ ];
        }
    }

    @monkeys_.map(*<inspection>).Array
}

my @monkeys = $*IN.slurp.split("\n\n").map({ Monkey.parse($_, :actions(MonkeyActions)).made }).Array;
put 'part 1: ', [*] inspections-p1(@monkeys, 20).sort.tail(2);
put 'part 2: ', [*] inspections-p2(@monkeys, 10000).sort.tail(2);
INFO