Advent of Code 2021, Day 16 Solutions

Run Settings
LanguageRaku
Language Version
Run Command
grammar Packet { regex TOP { <packet> <padding> } regex packet { <version> <body> } token version { <[01]> ** 3 } token data { <[01]> ** 4 } regex padding { '0'* } token sub-packets-length { <[01]> ** 15 } token sub-packets-number { <[01]> ** 11 } token length-header { '0' <sub-packets-length> || '1' <sub-packets-number> } proto regex body { * } token body:sym<literal> { '100' ['1' <data>]* '0' <data> } regex body:sym<sum> { '000' <length-header> <packet>+? <?{ body-match-header($<length-header>.made, $<packet>) }> } regex body:sym<prod> { '001' <length-header> <packet>+? <?{ body-match-header($<length-header>.made, $<packet>) }> } regex body:sym<min> { '010' <length-header> <packet>+? <?{ body-match-header($<length-header>.made, $<packet>) }> } regex body:sym<max> { '011' <length-header> <packet>+? <?{ body-match-header($<length-header>.made, $<packet>) }> } regex body:sym<gt> { '101' <length-header> <packet> ** 2 <?{ body-match-header($<length-header>.made, $<packet>) }> } regex body:sym<lt> { '110' <length-header> <packet> ** 2 <?{ body-match-header($<length-header>.made, $<packet>) }> } regex body:sym<eq> { '111' <length-header> <packet> ** 2 <?{ body-match-header($<length-header>.made, $<packet>) }> } sub body-match-header(Hash:D \header, Array:D \packets --> Bool:D) { header<length>.defined ?? header<length> == packets.map({ .Str.chars }).sum !! header<number> == packets.elems } } class PacketActions { method TOP($/) { make $<packet>.made } method packet($/) { make %(versum => $<version>.made + $<body>.made<versum>, value => $<body>.made<value>) } method version($/) { make $/.Str.parse-base(2) } method data($/) { make $/.Str.parse-base(2) } method sub-packets-length($/) { make $/.Str.parse-base(2) } method sub-packets-number($/) { make $/.Str.parse-base(2) } method length-header($/) { make $<sub-packets-length>.defined ?? %(length => $<sub-packets-length>.made) !! %(number => $<sub-packets-number>.made) } method body:sym<literal>($/) { make %(versum => 0, value => $<data>».made.reduce({ $^a * 16 + $^b })) } method body:sym<sum>($/) { make %(versum => $<packet>.map({ .made<versum> }).sum, value => [+] $<packet>.map({ .made<value> })) } method body:sym<prod>($/) { make %(versum => $<packet>.map({ .made<versum> }).sum, value => [*] $<packet>.map({ .made<value> })) } method body:sym<min>($/) { make %(versum => $<packet>.map({ .made<versum> }).sum, value => $<packet>.map({ .made<value> }).min) } method body:sym<max>($/) { make %(versum => $<packet>.map({ .made<versum> }).sum, value => $<packet>.map({ .made<value> }).max) } method body:sym<gt>($/) { make %(versum => $<packet>.map({ .made<versum> }).sum, value => +[>] $<packet>.map({ .made<value> })) } method body:sym<lt>($/) { make %(versum => $<packet>.map({ .made<versum> }).sum, value => +[<] $<packet>.map({ .made<value> })) } method body:sym<eq>($/) { make %(versum => $<packet>.map({ .made<versum> }).sum, value => +[==] $<packet>.map({ .made<value> })) } } sub solve(Str:D \hs) { my \ss = hs.comb».map({ $_.parse-base(16).fmt('%04b') }).join; Packet.parse(ss, :actions(PacketActions)).made } my \answer = solve($*IN.words[0]); put 'part 1: ', answer<versum>; put 'part 2: ', answer<value>;
Editor Settings
Theme
Key bindings
Full width
Lines