Advertisement
musifter

AoC 2021 day 15 (Perl-faster)

Dec 15th, 2021
2,213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.44 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use List::Priority;
  7.  
  8. my @dirs = ([1,0], [0,1], [-1,0], [0,-1]);
  9.  
  10. my @grid = map { chomp; [split //] } <>;
  11. my $max = scalar( @grid ) - 1;
  12.  
  13. # Ugly building of map for part 2
  14. # Build out horizontally
  15. foreach my $y (0 .. $max) {
  16.     push( @{$grid[$y]}, map {my $i = $_; map { ($_ + $i - 1) % 9 + 1 } @{$grid[$y]}} (1 .. 4) );
  17. }
  18.  
  19. # Build out vertically
  20. foreach my $i (1 .. 4) {
  21.     foreach my $y (0 .. $max) {
  22.         push( @grid, [map { ($_ + $i - 1) % 9 + 1 } @{$grid[$y]}] );
  23.     }
  24. }
  25.  
  26. # adjust max for new map
  27. $max = scalar( @grid ) - 1;
  28.  
  29. # Same Dijkstra search as part 1
  30. my @visit = map { [(~0) x ($max + 1)] } (1 .. ($max + 1));
  31.  
  32. my $queue = new List::Priority;
  33. $queue->insert( 0, [0,0,0,-1] );
  34.  
  35. my $time = 0;
  36.  
  37. queue:
  38. while (my $state = $queue->shift) {
  39.     my ($risk, $y, $x, $back) = @$state;
  40.  
  41.     print ::stderr "Risk: $risk\r"  if ($time++ % 50000 == 0);
  42.  
  43.     if ($y == $x == $max) {
  44.         print "Part 2: $risk\n";
  45.         last queue;
  46.     }
  47.  
  48.     next queue  if ($visit[$y][$x] <= $risk);
  49.     $visit[$y][$x] = $risk;
  50.  
  51.     move:
  52.     foreach my $d (0 .. 3) {
  53.         next move  if ($d == $back);
  54.  
  55.         my $my = $y + $dirs[$d][0];
  56.         my $mx = $x + $dirs[$d][1];
  57.  
  58.         if (0 <= $my <= $max && 0 <= $mx <= $max) {
  59.             my $new_risk = $risk + $grid[$mx][$my];
  60.             $queue->insert( $new_risk, [$new_risk, $my, $mx, ($d + 2) % 4] );
  61.         }
  62.     }
  63. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement