From 53cd8b116eca829c09801cef14a07d45f36f9e17 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Thu, 16 Dec 2021 09:32:12 +0100 Subject: [PATCH] 32.pl: cleanup --- 32.pl | 87 +++++++++++++++++++++++------------------------------------ 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/32.pl b/32.pl index 035abc7..390c25d 100755 --- a/32.pl +++ b/32.pl @@ -2,81 +2,60 @@ use v5.16; -chomp(my $packet = <>); -$packet =~ s/./sprintf("%04b", hex $&)/ge if $packet =~ /[2-9A-F]/; +chomp(my $data = <>); +# Accept also a binary string instead of hexadecimal one: +$data =~ s/./sprintf("%04b", hex $&)/ge if $data =~ /[2-9A-F]/; -sub get_b (\$$) { - my ($ppack, $bits) = @_; +sub chop_bits { + my ($bits) = @_; my $rv; - $$ppack =~ s/.{$bits}/$rv=eval"0b$&";''/e; - # say "get_b $bits=$rv"; + $data =~ s/.{$bits}/$rv = eval "0b$&"; ''/e; + # say "chop_bits($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); +sub parse { + $ver_sum += chop_bits(3); + my $type = chop_bits(3); - if ($typ == 4) { + if ($type == 4) { my $num = 0; - while (get_b($pp, 1)) { + my $more; + do { + $more = chop_bits(1); $num *= 16; - $num += get_b($pp, 4); - } - $num *= 16; - $num += get_b($pp, 4); + $num += chop_bits(4); + } while ($more); $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}//; - } + $result .= "op$type("; + if (chop_bits(1)) { + my $subparts = chop_bits(11); + parse() for 1 .. $subparts; } 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; - } + my $sublen = chop_bits(15); + my $len = length $data; + parse() while $len - length($data) < $sublen; } $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; - } -} +sub op0 { sum @_; } +sub op1 { product @_; } +sub op2 { min @_; } +sub op3 { max @_; } +sub op5 { $_[0] > $_[1] ? 1 : 0 } +sub op6 { $_[0] < $_[1] ? 1 : 0 } +sub op7 { $_[0] == $_[1] ? 1 : 0 } + +parse(); -parse($packet); +say "versions = $ver_sum"; say $result, ' = ', eval $result; -- 2.43.5