From 7b38251c28fdddfa775d93e882173d4c6a9a30ab Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Thu, 16 Dec 2021 06:49:03 +0100 Subject: [PATCH] Day 16: pretty straightforward parser --- 31.pl | 60 +++++++++++++++++++++++++++++++++++++++++++ 32.pl | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100755 31.pl create mode 100755 32.pl diff --git a/31.pl b/31.pl new file mode 100755 index 0000000..9f8f753 --- /dev/null +++ b/31.pl @@ -0,0 +1,60 @@ +#!/usr/bin/perl -w + +use v5.16; + +chomp(my $packet = <>); +$packet =~ s/./sprintf("%04b", hex $&)/ge if $packet =~ /[2-9A-F]/; + +sub get_b (\$$) { + my ($ppack, $bits) = @_; + my $rv; + $$ppack =~ s/.{$bits}/$rv=eval"0b$&";''/e; + return $rv; +} + +my $ver_sum; +my $result; +sub parse { + my $pp = shift; + + my $l = length $pp; + my $ver = get_b($pp, 3); + $ver_sum += $ver; + my $typ = get_b($pp, 3); + if ($typ == 4) { + my $num = 0; + while (get_b($pp, 1)) { + $num *= 16; + $num += get_b($pp, 4); + } + $num *= 16; + $num += get_b($pp, 4); + $result .= "$num,"; + } else { + $result .= "op($typ,"; + my $li = get_b($pp, 1); + if ($li) { + my $subp = get_b($pp, 11); + for (1 .. $subp) { + my $l1 = parse($pp); + $pp =~ s/.{$l1}//; + } + } else { + my $subl = get_b($pp, 15); + my $s = substr($pp, 0, $subl); + $pp =~ s/.{$subl}//; + while ($subl) { + my $l1 = parse($s); + $s =~ s/.{$l1}//; + $subl -= $l1; + } + } + $result .= ")"; + } + return $l - length($pp); +} + +parse($packet); +say $result; +say $ver_sum; + diff --git a/32.pl b/32.pl new file mode 100755 index 0000000..035abc7 --- /dev/null +++ b/32.pl @@ -0,0 +1,82 @@ +#!/usr/bin/perl -w + +use v5.16; + +chomp(my $packet = <>); +$packet =~ s/./sprintf("%04b", hex $&)/ge if $packet =~ /[2-9A-F]/; + +sub get_b (\$$) { + my ($ppack, $bits) = @_; + my $rv; + $$ppack =~ s/.{$bits}/$rv=eval"0b$&";''/e; + # say "get_b $bits=$rv"; + return $rv; +} + +my $ver_sum; +my $result; +sub parse { + my $pp = shift; + + my $l = length $pp; + my $ver = get_b($pp, 3); + $ver_sum += $ver; + my $typ = get_b($pp, 3); + + if ($typ == 4) { + my $num = 0; + while (get_b($pp, 1)) { + $num *= 16; + $num += get_b($pp, 4); + } + $num *= 16; + $num += get_b($pp, 4); + $result .= "$num,"; + } else { + $result .= "op($typ,"; + my $li = get_b($pp, 1); + if ($li) { + my $subp = get_b($pp, 11); + for (1 .. $subp) { + my $l1 = parse($pp); + $pp =~ s/.{$l1}//; + } + } else { + my $subl = get_b($pp, 15); + my $s = substr($pp, 0, $subl); + $pp =~ s/.{$subl}//; + while ($subl) { + my $l1 = parse($s); + $s =~ s/.{$l1}//; + $subl -= $l1; + } + } + $result .= "),"; + } + return $l - length($pp); +} + +use List::Util qw(sum product min max); + +sub op { + my ($id, @rest) = @_; + if ($id == 0) { + return sum @rest; + } elsif ($id == 1) { + return product @rest; + } elsif ($id == 2) { + return min @rest; + } elsif ($id == 3) { + return max @rest; + } elsif ($id == 5) { + return $rest[0] > $rest[1] ? 1 : 0; + } elsif ($id == 6) { + return $rest[0] < $rest[1] ? 1 : 0; + } elsif ($id == 7) { + return $rest[0] == $rest[1] ? 1 : 0; + } +} + +parse($packet); +say $result, ' = ', eval $result; + -- 2.43.5