my $length = 87688; my @ranges; while(<>){ chomp; my @range = split / /; push @ranges,[@range]; } # Using Schwartzian transform, sort the ranges from the # longest to the shortest @ranges = map { [$_->[1],$_->[2]] } sort { $b->[0] <=> $a->[0] } map { my $remainder = $_->[1] - $_->[0]; $remainder += $length if $remainder < 0; [$remainder,$_->[0],$_->[1]] } @ranges; # checks that a subrange is included in a wider range sub included { my($o0,$o1,$i0,$i1) = @_; if ($o0 <= $o1){ return ($i0 <= $i1 and $i0 >= $o0 and $i1 <= $o1) } else { # outer range is circular return ($i1 <= $o1 or $i0 >= $o0) } } # included my @ranges_kept; while (my $range = pop @ranges) { push @ranges_kept,$range unless grep included(@$_,@$range),@ranges; } warn scalar @ranges_kept," ranges kept.\n"; print $_->[0],' ',$_->[1],"\n" foreach (@ranges_kept);