Advertisement
musifter

AoC day 23 (pt2), Perl

Dec 23rd, 2020
2,136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.20 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. $| = 1;
  7.  
  8. my @ring;
  9. my ($curr, $prev);
  10.  
  11. # Read in file, building ring
  12. chomp( my $input = <> );
  13. foreach (split( //, $input )) {
  14.     $_ = int($_);
  15.     $curr //= $_;
  16.     $ring[$prev] = $_  if (defined $prev);
  17.     $prev = $_;
  18. }
  19.  
  20. # add in remaining cups:
  21. foreach my $i (10 .. 1_000_000) {
  22.     $ring[$prev] = $i;
  23.     $prev = $i;
  24. }
  25. $ring[1_000_000] = $curr;
  26.  
  27. foreach my $t (1 .. 10_000_000) {
  28.     print "Turn: $t\r"  if ($t % 100000 == 0);
  29.  
  30.     # Advance ptr marking cups (cup 0 doesn't exist, marked as "grabbed" too)
  31.     my $ptr = $curr;
  32.     my %grab = (0 => 1);
  33.     foreach (1 .. 3) {
  34.         $ptr = $ring[$ptr];
  35.         $grab{$ptr} = 1;
  36.     }
  37.  
  38.     # calculate destination
  39.     my $dest = $curr - 1;
  40.     $dest = ($dest - 1) % 1_000_001  while (exists $grab{$dest});
  41.  
  42.     # relink ring
  43.     my $old = $ring[$curr];         # save ptr from curr to start of block
  44.     $ring[$curr] = $ring[$ptr];     # link curr to after block
  45.     $ring[$ptr]  = $ring[$dest];    # link last of block to after dest
  46.     $ring[$dest] = $old;            # link dest to start of block
  47.  
  48.     $curr = $ring[$curr];
  49. }
  50.  
  51. print "\nPart 2: ", $ring[1] * $ring[$ring[1]], "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement