Search code examples
arraysperlintervals

How to obtain the complement intervals from an array of intervals?


The easiest way to explain my question is with an example.

I have an array in Perl with a set of intervals, and I need to obtain the complementary intervals, in other words, the anti-image of that set. From:

@ary1 = qw(23-44 85-127 168-209)

Printed intervals: 23-44, 85-127, 168-209.

Transform it to:

...-22, 45-84, 128-167, 210-...


Solution

  • If the intervals are already sorted and don't overlap:

    #!/usr/bin/perl
    use warnings;
    use strict;
    
    use List::MoreUtils qw{ natatime };
    
    my @ary1 = qw(23-44 85-127 168-209);
    
    my $diff = 1;
    my $pair = natatime 2, '...', 
                           map({ map { $diff *= -1; $_ + $diff }
                                     split /-/
                               } @ary1),
                           '...';
    my @compl;
    while (my ($from, $to) = $pair->()) {
        push @compl, "$from-$to";
    }
    
    print "@compl\n";
    

    Output

    ...-22 45-84 128-167 210-...