Advertisement
musifter

AoC 2023 day 5 part 2 (Perl)

Dec 5th, 2023
977
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.02 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use v5.32;
  4. use warnings;
  5.  
  6. use List::Util      qw(max min);
  7.  
  8. # Paragraph mode, array of sections
  9. $/ = '';
  10. my @section = map {[split /\n/]} <>;
  11.  
  12. # Read in seed intervals
  13. my @seeds;
  14. while ($section[0][0] =~ m#(\d+) (\d+)#g) {
  15.     push( @seeds, {src => $1, len => $2} );
  16. }
  17.  
  18. # Read in sections, building complete maps
  19. my %Map;        # hash of table -> array of struct (src, dst, len) hash
  20.  
  21. shift @section;
  22. foreach my $sect (@section) {
  23.     shift(@$sect) =~ m#-(\w+) map#;
  24.     my $type = $1;
  25.  
  26.     foreach my $line (@$sect) {
  27.         my ($dst, $src, $len) = split( ' ', $line );
  28.         push( $Map{$type}->@*, {src => $src, dst => $dst, len => $len} );
  29.     }
  30.  
  31.     $Map{$type}->@* = sort { $a->{src} <=> $b->{src} } $Map{$type}->@*;
  32.  
  33.     # Add missing identity maps:
  34.     my $curr = 0;
  35.     my @ident;
  36.     foreach my $rule ($Map{$type}->@*) {
  37.         if ($rule->{src} > $curr) {
  38.             push( @ident, {src => $curr, dst => $curr, len => $rule->{src} - $curr} );
  39.         }
  40.         $curr = $rule->{src} + $rule->{len};
  41.     }
  42.  
  43.     if ($curr < 2 ** 32) {
  44.         push( @ident, {src => $curr, dst => $curr, len => 2 ** 32 - $curr} );
  45.     }
  46.  
  47.     push( $Map{$type}->@*, @ident );
  48. }
  49.  
  50. # Returns insection, len <= 0 if none
  51. sub intersect {
  52.     my ($a, $b) = @_;
  53.     my $start = max( $a->{src}, $b->{src} );
  54.     my $end   = min( $a->{src} + $a->{len}, $b->{src} + $b->{len} );
  55.  
  56.     return( {src => $start, len => $end - $start} );
  57. }
  58.  
  59. my @order = qw(soil fertilizer water light temperature humidity location);
  60.  
  61. # Transform seeds through maps:
  62. foreach my $type (@order) {
  63.     my @next;
  64.     foreach my $rule ($Map{$type}->@*) {
  65.         foreach my $range (@seeds) {
  66.             my $inter = &intersect( $range, $rule );
  67.             if ($inter->{len} > 0) {
  68.                 push( @next, {src => $rule->{dst} + ($inter->{src} - $rule->{src}),
  69.                               len => $inter->{len}} );
  70.             }
  71.         }
  72.     }
  73.     @seeds = @next;
  74. }
  75.  
  76. say "Part 2: ", min map { $_->{src} } @seeds;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement