Advertisement
musifter

AoC 2022 day 17 (perl pt 1)

Dec 17th, 2022 (edited)
1,452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.69 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use List::Util  qw(max all reduce);
  7.  
  8. my %Grid;
  9. my %Dirs = ('>' => [0,1], '<' => [0,-1]);
  10.  
  11. my @Blocks = ([[ 0,0], [ 0,1], [ 0,2], [ 0,3]],              # —
  12.               [[-2,1], [-1,0], [-1,1], [-1,2], [0,1]],       # ✚
  13.               [[-2,0], [-2,1], [-2,2], [-1,2], [0,2]],       # ⅃
  14.               [[-3,0], [-2,0], [-1,0], [ 0,0]],              # |
  15.               [[-1,0], [-1,1], [ 0,0], [ 0,1]]);             # ⬜
  16.  
  17. my $Num_blocks = scalar @Blocks;
  18.  
  19. my @Input = map { chomp; split // } <>;
  20. my $Input_len = scalar @Input;
  21. my $Inptr = -1;
  22.  
  23. sub vec_sum ($$) {
  24.     my ($p,$q) = @_;
  25.     return ([$p->[0] + $q->[0], $p->[1] + $q->[1]]);
  26. }
  27.  
  28. sub move_block {
  29.     my ($blk, $pos) = @_;
  30.     my $dropped;
  31.  
  32.     my @squares = map { vec_sum($pos, $_) } $Blocks[$blk]->@*;
  33.  
  34.     do {
  35.         my $move = $Input[$Inptr = ($Inptr + 1) % $Input_len];
  36.        
  37.         # Try sliding
  38.         my @try = map { vec_sum( $_, $Dirs{$move} ) } @squares;
  39.         @squares = @try if (all {0 <= $_->[1] < 7 and !$Grid{$_->[0],$_->[1]}} @try);
  40.  
  41.         # Try dropping
  42.         @try = map { vec_sum( $_, [-1,0] ) } @squares;
  43.         @squares = @try if ($dropped = all {!$Grid{$_->[0],$_->[1]}} @try);
  44.     } while ($dropped);
  45.  
  46.     # Place piece:
  47.     $Grid{$_->[0],$_->[1]} = '#' foreach (@squares);
  48.  
  49.     # Return top row of piece:
  50.     return (reduce { max($a, $b->[0]) } (0, @squares));
  51. }
  52.  
  53. #
  54. # Mainline
  55. #
  56. my $top = 0;
  57. $Grid{$top,$_} = '-' foreach (0 .. 6);
  58.  
  59. foreach my $rock (0 .. 2021) {
  60.     my $blk = $rock % $Num_blocks;
  61.     my $pos = [$top + 4 - $Blocks[$blk][0][0], 2];
  62.  
  63.     $top = max($top, &move_block( $blk, $pos ));
  64. }
  65.  
  66. print "Part 1: $top\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement