Advertisement
musifter

AoC 2021 day 21 part 2 (Perl)

Dec 21st, 2021
1,818
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.47 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use List::Util  qw(max);
  7.  
  8. my @roll3d3 = (1, 3, 6, 7, 6, 3, 1);
  9.  
  10. my @Play;   # an array (player) of 2D arrays of positions x scores => num games
  11.  
  12. while (<>) {
  13.     my ($play, $pos) = m#Player (\d+) starting position: (\d+)#;
  14.     $Play[$play-1][$pos][0] = 1;
  15. }
  16.  
  17. my @Active = (1,1);         # number of active games for player
  18. my @Wins   = (0,0);         # number of winning universes accumulated
  19. my $p = 1;                  # current active player
  20.  
  21. while (1) {
  22.     my @next;               # 2D array of positions x scores => num games
  23.     my $act = 0;            # count of total active games for this player this turn
  24.  
  25.     $p = !$p;               # change active player
  26.  
  27.     foreach my $pos (1 .. 10) {
  28.         foreach my $score (0 .. 20) {
  29.             next if (!$Play[$p][$pos][$score]);
  30.  
  31.             # spread 3d3 roll across the multiverse
  32.             my $i = ($pos + 2) % 10 + 1;
  33.             foreach my $games (@roll3d3) {
  34.                 if ($score + $i >= 21) {
  35.                     $Wins[$p] += $Play[$p][$pos][$score] * $games * $Active[!$p];
  36.                 } else {
  37.                     $next[$i][$score + $i] += $Play[$p][$pos][$score] * $games;
  38.                     $act += $Play[$p][$pos][$score] * $games;
  39.                 }
  40.  
  41.                 $i = $i % 10 + 1;
  42.             }
  43.         }
  44.     }
  45.  
  46.     $Play[$p] = \@next;
  47.     $Active[$p] = $act;
  48.  
  49.     last if ($act == 0);
  50. }
  51.  
  52. print "Part 2: ", max(@Wins), "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement