]> www.fi.muni.cz Git - aoc2021.git/blob - 31.pl
Day 25: pretty straightforward
[aoc2021.git] / 31.pl
1 #!/usr/bin/perl -w
2
3 use v5.16;
4
5 chomp(my $packet = <>);
6 $packet =~ s/./sprintf("%04b", hex $&)/ge if $packet =~ /[2-9A-F]/;
7
8 sub get_b (\$$) {
9         my ($ppack, $bits) = @_;
10         my $rv;
11         $$ppack =~ s/.{$bits}/$rv=eval"0b$&";''/e;
12         return $rv;
13 }
14
15 my $ver_sum;
16 my $result;
17 sub parse {
18         my $pp = shift;
19
20         my $l = length $pp;
21         my $ver = get_b($pp, 3);
22         $ver_sum += $ver;
23         my $typ = get_b($pp, 3);
24         if ($typ == 4) {
25                 my $num = 0;
26                 while (get_b($pp, 1)) {
27                         $num *= 16;
28                         $num += get_b($pp, 4);
29                 }
30                 $num *= 16;
31                 $num += get_b($pp, 4);
32                 $result .= "$num,";
33         } else {
34                 $result .= "op($typ,";
35                 my $li = get_b($pp, 1);
36                 if ($li) {
37                         my $subp = get_b($pp, 11);
38                         for (1 .. $subp) {
39                                 my $l1 = parse($pp);
40                                 $pp =~ s/.{$l1}//;
41                         }
42                 } else {
43                         my $subl = get_b($pp, 15);
44                         my $s = substr($pp, 0, $subl);
45                         $pp =~ s/.{$subl}//;
46                         while ($subl) {
47                                 my $l1 = parse($s);
48                                 $s =~ s/.{$l1}//;
49                                 $subl -= $l1;
50                         }
51                 }
52                 $result .= ")";
53         }
54         return $l - length($pp);
55 }
56
57 parse($packet);
58 say $result;
59 say $ver_sum;
60