AoC 2023, day 19

Run Settings
LanguageRaku
Language Version
Run Command
grammar Xmas { rule TOP { <name> '{' <work>+ % ',' '}' } token name { <[a..z]>+ || 'A' || 'R' } rule work { <rate> <op> <value> ':' <name> || <name> } token rate { <[xmas]> } token op { '<' | '>' } token value { \d+ } rule input { '{' <entry>+ % ',' '}' } rule entry { <rate> '=' <value> } } class XmasActions { method TOP($/) { make $<name>.made => ($<work>».made).Array } method name($/) { make ~$/ } method work($/) { my %h = 'next' => $<name>.made, ; with $<rate>.made { %h<rate> = $<rate>.made; %h<op> = $<op>.made; %h<value> = $<value>.made; } make %h } method rate($/) { make ~$/ } method op($/) { make ~$/ } method value($/) { make +$/ } method input($/) { make ($<entry>».made).Hash } method entry($/) { make $<rate>.made => $<value>.made } } my (%flows, $sum2); put 'part 1: ', do with $*IN.split("\n\n") { %flows = .[0].lines.map({ Xmas.parse($_, :actions(XmasActions)).made }); [+] (process-p1($_, %flows) for .[1].lines.map({ Xmas.parse($_, :rule<input>, :actions(XmasActions)).made })) }; process-p2((:x(1..4000), :m(1..4000), :a(1..4000), :s(1..4000)).Hash, 'in', %flows); put 'part 2: ', $sum2; sub process-p1(%input, %flows) { my $fn = 'in'; loop { for %flows{$fn}.Array -> $work { given $fn { when 'A' { return %input.map(*.value).sum; } when 'R' { return 0; } } with $work<op> { when '<' { { $fn = $work<next>; last; } if %input{$work<rate>} < $work<value>; } when '>' { { $fn = $work<next>; last; } if %input{$work<rate>} > $work<value>; } } else { $fn = $work<next>; } } } } sub process-p2(%ranges is copy, $fn_, %flows) { my $fn = $fn_; for %flows{$fn}.Array -> $work { given $fn { when 'A' { $sum2 += [*] %ranges.values.map(+*); return; } when 'R' { return; } } with $work<op> { my %ranges_ = %ranges; when '<' { with %ranges_{$work<rate>} -> $rr { if $rr.min < $work<value> { %ranges_{$work<rate>} = $rr.min .. $work<value> - 1; process-p2(%ranges_, $work<next>, %flows); } } with %ranges{$work<rate>} -> $rr { $rr.max ≥ $work<value> ?? (%ranges{$work<rate>} = $work<value> .. $rr.max) !! return; } } when '>' { with %ranges_{$work<rate>} -> $rr { if $rr.max > $work<value> { %ranges_{$work<rate>} = max($rr.min, $work<value> + 1) .. $rr.max; process-p2(%ranges_, $work<next>, %flows); } } with %ranges{$work<rate>} -> $rr { $rr.min ≤ $work<value> ?? (%ranges{$work<rate>} = $rr.min .. $work<value>) !! return; } } } else { process-p2(%ranges, $work<next>, %flows); } } }
Editor Settings
Theme
Key bindings
Full width
Lines