Advertisement
musifter

AoC 2024, day 9, part 2 (Perl)

Dec 9th, 2024 (edited)
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.20 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use feature         qw(say);
  7.  
  8. my @input = map { chomp; split // } <>;
  9.  
  10. # Read in disk
  11. my @disk;
  12.  
  13. my $id = 0;
  14. while (@input) {
  15.     my $size = shift @input;
  16.     my $gap  = shift @input;
  17.  
  18.     push( @disk, {id => $id++, size => int $size} );
  19.     push( @disk, {id => -1,    size => int $gap } )   if ($gap);
  20. }
  21.  
  22. # Defragment disk
  23. my $idx = $#disk;
  24. for (my $file_id = $id - 1; $file_id > 0; $file_id--) {
  25.     $idx-- while ($idx >= 0 and $disk[$idx]{id} != $file_id);
  26.  
  27.     my $span = 0;
  28.     $span++ while ($span < $idx and ($disk[$span]{id} != -1
  29.                                     or $disk[$span]{size} < $disk[$idx]{size}));
  30.  
  31.     next if ($span >= $idx);
  32.  
  33.     my %copy = $disk[$idx]->%*;
  34.     $disk[$idx]{id} = -1;
  35.  
  36.     splice( @disk, $span, 1, (\%copy, {size => $disk[$span]{size} - $disk[$idx]{size},
  37.                                          id => -1}) );
  38. }
  39.  
  40. # Calculate checksum
  41. my $part2 = 0;
  42. my $pos = 0;
  43. foreach my $b (@disk) {
  44.     if ($b->{id} != -1 and $b->{size} > 0) {
  45.         for (my $i = 0; $i < $b->{size}; $i++) {
  46.             $part2 += $b->{id} * ($pos + $i);
  47.         }
  48.     }
  49.     $pos += $b->{size};
  50. }
  51. say "Part 2: $part2";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement