Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use Trim qw(trim);
- use List::AllUtils qw(all sum);
- $/ = '';
- # make list of winning lines
- my @poss_wins;
- foreach my $i (0 .. 4) {
- push( @poss_wins, [map { 5 * $i + $_ } (0 .. 4)] ); # rows
- push( @poss_wins, [map { 5 * $_ + $i } (0 .. 4)] ); # cols
- }
- # first line is list of calls
- my @calls = split /,/, <>;
- # remaining paragraphs are the cards
- my @cards;
- while (<>) {
- push( @cards, [split /\s+/, trim] );
- }
- my (%called, $part1, $part2);
- call:
- foreach my $call (@calls) {
- $called{$call}++; # mark number as called
- card:
- for (my $i = $#cards; $i >= 0; $i--) {
- my $card = $cards[$i];
- foreach my $line (@poss_wins) {
- if (all {exists $called{ $card->[$_] }} @$line) {
- # Win! Score part1 if we haven't already.
- $part1 //= $call * (sum grep {!exists $called{$_}} @$card);
- if (@cards == 1) {
- $part2 = $call * (sum grep {!exists $called{$_}} @$card);
- last call;
- }
- # remove winning card
- splice( @cards, $i, 1 );
- next card;
- }
- }
- }
- }
- print "Part 1: $part1\n";
- print "Part 2: $part2\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement