Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use v5.32;
- use warnings;
- use List::Util qw(max min);
- # Paragraph mode, array of sections
- $/ = '';
- my @section = map {[split /\n/]} <>;
- # Read in seed intervals
- my @seeds;
- while ($section[0][0] =~ m#(\d+) (\d+)#g) {
- push( @seeds, {src => $1, len => $2} );
- }
- # Read in sections, building complete maps
- my %Map; # hash of table -> array of struct (src, dst, len) hash
- shift @section;
- foreach my $sect (@section) {
- shift(@$sect) =~ m#-(\w+) map#;
- my $type = $1;
- foreach my $line (@$sect) {
- my ($dst, $src, $len) = split( ' ', $line );
- push( $Map{$type}->@*, {src => $src, dst => $dst, len => $len} );
- }
- $Map{$type}->@* = sort { $a->{src} <=> $b->{src} } $Map{$type}->@*;
- # Add missing identity maps:
- my $curr = 0;
- my @ident;
- foreach my $rule ($Map{$type}->@*) {
- if ($rule->{src} > $curr) {
- push( @ident, {src => $curr, dst => $curr, len => $rule->{src} - $curr} );
- }
- $curr = $rule->{src} + $rule->{len};
- }
- if ($curr < 2 ** 32) {
- push( @ident, {src => $curr, dst => $curr, len => 2 ** 32 - $curr} );
- }
- push( $Map{$type}->@*, @ident );
- }
- # Returns insection, len <= 0 if none
- sub intersect {
- my ($a, $b) = @_;
- my $start = max( $a->{src}, $b->{src} );
- my $end = min( $a->{src} + $a->{len}, $b->{src} + $b->{len} );
- return( {src => $start, len => $end - $start} );
- }
- my @order = qw(soil fertilizer water light temperature humidity location);
- # Transform seeds through maps:
- foreach my $type (@order) {
- my @next;
- foreach my $rule ($Map{$type}->@*) {
- foreach my $range (@seeds) {
- my $inter = &intersect( $range, $rule );
- if ($inter->{len} > 0) {
- push( @next, {src => $rule->{dst} + ($inter->{src} - $rule->{src}),
- len => $inter->{len}} );
- }
- }
- }
- @seeds = @next;
- }
- say "Part 2: ", min map { $_->{src} } @seeds;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement