Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use feature qw(say);
- use List::Util qw(reduce max min);
- # Paragraph mode, array of sections
- $/ = '';
- my ($first, $second) = map {[split /\n/]} <>;
- sub intersect {
- my ($a, $b) = @_;
- return ([max( $a->[0], $b->[0] ), min( $a->[1], $b->[1] )]);
- }
- my @ranges = map { [split /-/] } @$first;
- say "Part 1: ", scalar grep {my $food = $_; grep {$_->[0] <= $food <= $_->[1]} @ranges} @$second;
- for (my $i = 1; $i < @ranges; $i++) {
- for (my $j = 0; $j < $i; $j++) {
- my $inter = &intersect( $ranges[$i], $ranges[$j] );
- next if ($inter->[0] > $inter->[1]); # No intersection
- if ($inter->[0] == $ranges[$i][0] and $inter->[1] == $ranges[$i][1]) {
- # $i range is completely within $j range, remove $i
- $ranges[$i] = [-1,-2];
- } elsif ($inter->[0] == $ranges[$j][0] and $inter->[1] == $ranges[$j][1]) {
- # range $j is completely within $i range, remove $j
- $ranges[$j] = [-1,-2];
- } elsif ($inter->[0] == $ranges[$i][0]) {
- # $i range starts in the $j range, trim
- $ranges[$i][0] = $inter->[1] + 1;
- } elsif ($inter->[1] == $ranges[$i][1]) {
- # $i range ends in the $j range, trim
- $ranges[$i][1] = $inter->[0] - 1;
- }
- last if ($ranges[$i][0] > $ranges[$i][1]); # $i range is now empty
- }
- }
- # Filter valid ranges
- @ranges = grep { $_->[0] <= $_->[1] } @ranges;
- say "Part 2: ", reduce { $a + $b->[1] - $b->[0] + 1 } (0, @ranges);
Advertisement
Add Comment
Please, Sign In to add comment