Advertisement
musifter

AoC 2024, day 6 (Perl)

Dec 6th, 2024 (edited)
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.79 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use feature         qw(say);
  7. use List::AllUtils  qw(firstidx);
  8. use Math::Vector::Real;
  9.  
  10. my ($y,$x) = Math::Vector::Real->canonical_base(2);
  11. my @Dirs = ($y, -$x, -$y, $x);
  12.  
  13. # Read in grid, adding sentinel ~s to right and bottom
  14. my @Grid = map { chomp; [split(//), '~'] } <>;
  15. push( @Grid, [('~') x $Grid[0]->@*] );
  16.  
  17. sub grid_at ($) { my $p = shift; return ($Grid[$p->[0]][$p->[1]]) }
  18.  
  19. my $start_pos;
  20. my $face = 2;
  21. foreach my $y (0 .. $#Grid) {
  22.     my $x = firstidx { $_ eq '^' } $Grid[$y]->@*;
  23.     if ($x != -1) {
  24.         $start_pos = V($y,$x);
  25.         last;
  26.     }
  27. }
  28.  
  29. sub test_block {
  30.     my ($block, $pos, $face, $path) = @_;
  31.     my %visit;
  32.  
  33.     $Grid[$block->[0]][$block->[1]] = '#';
  34.  
  35.     while (&grid_at( $pos ) ne '~') {
  36.         my $ahead = $pos + $Dirs[$face];
  37.  
  38.         if (&grid_at( $ahead ) eq '#') {
  39.             $face = ($face + 1) % 4;
  40.         } else {
  41.             last if ($visit{$ahead}{$face} or ($path->{$ahead} and $path->{$ahead}{$face}));
  42.             $pos = $ahead;
  43.         }
  44.         $visit{$pos}{$face}++;
  45.     }
  46.  
  47.     $Grid[$block->[0]][$block->[1]] = '.';
  48.  
  49.     return (&grid_at( $pos ) ne '~');
  50. }
  51.  
  52. my %path;
  53. my %block;
  54. my $pos = $start_pos;
  55. my $count = 0;
  56.  
  57. $path{$pos}{$face}++;
  58. while (&grid_at( $pos ) ne '~') {
  59.     my $ahead = $pos + $Dirs[$face];
  60.  
  61.     print ::stderr "$count\r"  if (++$count % 500 == 0);
  62.  
  63.     if (&grid_at( $ahead ) eq '#') {
  64.         $face = ($face + 1) % 4;
  65.     } else {
  66.         if (&grid_at( $ahead ) eq '.' and !$block{$ahead} and !$path{$ahead}) {
  67.             $block{$ahead}++ if (&test_block( $ahead, $pos, $face, \%path ));
  68.         }
  69.  
  70.         $pos = $ahead;
  71.     }
  72.     $path{$pos}{$face}++;
  73. }
  74.  
  75. say "Part 1: ", (scalar keys %path) - 1;
  76. say "Part 2: ", (scalar keys %block);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement