Advertisement
musifter

AoC day 19, Perl

Dec 19th, 2020 (edited)
1,249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.10 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use List::AllUtils  qw(true);
  7.  
  8. $/ = '';
  9.  
  10. my %Rule;
  11. my %Patt;
  12.  
  13. # Read Rules
  14. $_ = <>;
  15. foreach (split( "\n" )) {
  16.     my ($num, $str) = m#(\d+): (.*)#;
  17.  
  18.     $Rule{$num} = $str;
  19.     $Patt{$num} = $1 if ($str =~ m#([ab])#);
  20. }
  21.  
  22. # Recursive function to fill out pattern table
  23. sub recurse_rules {
  24.     my $num = shift;
  25.  
  26.     return ($Patt{$num})  if (exists $Patt{$num});
  27.  
  28.     my @tokens = split( " ", $Rule{$num} );
  29.  
  30.     my $ret = '(';
  31.     foreach my $t (@tokens) {
  32.         $ret .= ($t eq '|') ? '|' : &recurse_rules( $t );
  33.     }
  34.     $ret .= ')';
  35.  
  36.     $Patt{$num} = $ret;
  37.     return ($ret);
  38. }
  39.  
  40. # Build Pattern tables
  41. &recurse_rules( 0 );
  42.  
  43. # Load signals to test
  44. my @sig = map { split( "\n" ) } <>;
  45.  
  46. # Part 1:
  47. print "Part 1: ", (true { m#^@{[$Patt{0}]}$# } @sig), "\n";
  48.  
  49. # Part 2: New verions of these rules (only used in 0: 8 11)
  50. #   8: 42 | 42 8
  51. #   11: 42 31 | 42 11 31
  52. my $patt8  = "$Patt{42}+";
  53. my $patt11 = "(?<ELEVEN>$Patt{42}$Patt{31}|$Patt{42}(?&ELEVEN)$Patt{31})";
  54.  
  55. print "Part 2: ", (true { m#^$patt8$patt11$# } @sig), "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement