Advertisement
musifter

AoC 2021 day 4 (Perl)

Dec 4th, 2021 (edited)
1,782
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.29 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use Trim            qw(trim);
  7. use List::AllUtils  qw(all sum);
  8.  
  9. $/ = '';
  10.  
  11. # make list of winning lines
  12. my @poss_wins;
  13. foreach my $i (0 .. 4) {
  14.     push( @poss_wins, [map { 5 * $i + $_ } (0 .. 4)] ); # rows
  15.     push( @poss_wins, [map { 5 * $_ + $i } (0 .. 4)] ); # cols
  16. }
  17.  
  18. # first line is list of calls
  19. my @calls = split /,/, <>;
  20.  
  21. # remaining paragraphs are the cards
  22. my @cards;
  23. while (<>)  {
  24.     push( @cards, [split /\s+/, trim] );
  25. }
  26.  
  27. my (%called, $part1, $part2);
  28.  
  29. call:
  30. foreach my $call (@calls) {
  31.     $called{$call}++;   # mark number as called
  32.  
  33.     card:
  34.     for (my $i = $#cards; $i >= 0; $i--) {
  35.         my $card = $cards[$i];
  36.  
  37.         foreach my $line (@poss_wins) {
  38.             if (all {exists $called{ $card->[$_] }} @$line) {
  39.                 # Win! Score part1 if we haven't already.
  40.                 $part1 //= $call * (sum grep {!exists $called{$_}} @$card);
  41.  
  42.                 if (@cards == 1) {
  43.                     $part2 = $call * (sum grep {!exists $called{$_}} @$card);
  44.                     last call;
  45.                 }
  46.  
  47.                 # remove winning card
  48.                 splice( @cards, $i, 1 );
  49.                 next card;
  50.             }
  51.         }
  52.     }
  53. }
  54.  
  55. print "Part 1: $part1\n";
  56. print "Part 2: $part2\n";
  57.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement