#!/usr/bin/perl my @data = ( [ 2, 8 ], [ 1, 3 ], [ 4, 6 ], [ 7, 10 ], [ 8, 20 ], ); foreach my $pair (@data) { @{$pair}[1,0] = @{$pair}[1,0] if $pair->[0] > $pair->[1]; $pair->[2] = $pair->[1] - $pair->[0]; } @data = sort { $a->[2] cmp $b->[2] || $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @data; my @good; PAIR: foreach my $pair (@data) { my @check; foreach my $i (0 .. $#good) { my $good = $good[$i]; if ( ($good->[0] <= $pair->[0] && $pair->[0] < $good->[1]) || ($good->[0] < $pair->[1] && $pair->[1] <= $good->[1]) || ($pair->[0] <= $good->[0] && $good->[0] < $pair->[1]) || ($pair->[0] < $good->[1] && $good->[1] <= $pair->[1]) ) { push @check, [ $good, $i, ]; } } unless (@check) { push @good, $pair; next PAIR; } my $max = 0; $max += $_->[2] for map { $_->[0] } @check; next PAIR if $max > $pair->[2]; splice @good, $_, 1 for sort { $b <=> $a } map { $_->[1] } @check; push @good, $pair; } @good = sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @good; print "$_->[0] ... $_->[1] ($_->[2])\n" for @good; my $cover = 0; $cover += $_->[2] for @good; print "Total coverage is $cover\n";