From: Jan "Yenya" Kasprzak <kas@fi.muni.cz>
Date: Thu, 16 Dec 2021 05:49:03 +0000 (+0100)
Subject: Day 16: pretty straightforward parser
X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=commitdiff_plain;h=7b38251c28fdddfa775d93e882173d4c6a9a30ab;p=aoc.git

Day 16: pretty straightforward parser
---

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;
+