This Perl extension provides methods which may be useful in manipulating sets whose elements are consecutive integers. Suppose that you are provided with the following non-intersecting, non-overlapping sets of consecutive integers:

{ 1 .. 17 }
{ 25 .. 42 }
{ 44 .. 50 }

Suppose further that you are provided with the following lower and upper bounds to a range of consecutive integers:

lower: 12
upper: 62

Provide a set of sets which:

when joined together, would form a set of consecutive integers from the lower to the upper bound, inclusive; and

are derived from:

the sets provided;

proper subsets thereof; or

newly generated sets which fill in the gaps below, in between or above the provided sets.

Once a Set::Integer::Gapfillers object has been constructed, its segments_needed() method can be used to provide these results:

And, as an additional alternative, you may wish to have your set of sets begin or end with all the values of a given provided set, rather than a proper subset thereof containing only those values needed to populate the desired range. In that case, use the all_segments() method.

The results returned by the all_segments() method differ from those returned by the segments_needed() method only at the lower or upper ends. If, as in the above example, the lower bound of the target range of integers falls inside a provided segment, the first set returned by all_segments() will be the entire first set provided; the first set returned by segments_needed() will be a proper subset of the first set provided, starting with the requested lower bound.

Arguments: List of key-value pairs. lower and upper take integers denoting the lower and upper bounds of the range of integers desired as the result. sets takes a reference to an anonymous array whose elements are, in turn, references to anonymous arrays whose two elements are the lowest and highest numbers in a range of consecutive integers.

Note: The sets of consecutive integers supplied must be non-overlapping. Set::Integer::Gapfillers will croak if supplied with arguments such as these:

Note: Only two elements should be supplied in the anonymous arrays supplied as elements to the array reference which is the value of sets: the lowest and highest (or, first and last) elements in each array. You should not use Perl's range operator (e.g.,[ 25 .. 48 ]) in this instance.

Purpose: Generate a set of sets which (a) when joined together, would form a set of consecutive integers from the lower to the upper bound, inclusive; and (b) are derived from (i) the sets provided; (ii) proper subsets thereof; or (iii) newly generated sets which fill in the gaps below, in between or above the provided sets.

Arguments: None required. expand = 1> is optional (see FAQ).

Returns: A reference to an anonymous array whose elements are, in turn, anonymous arrays of two elements: the lowest and highest integers in a particular subset. But when the expand option is set, the return value is a reference to an anonymous array whose elements are, in turn, references to arrays each of which holds the entire range of each set needed -- not just the beginning and end points.

Purpose: Generate a set of the newly generated sets needed to fill in the gaps below, in between or above the sets provided to the constructor. The sets, like those returned by segments_needed(), are denoted by their lower and upper bounds rather than by their entire contents.

Arguments: None required. expand = 1> is optional (see FAQ).

Returns: A reference to an anonymous array whose elements are, in turn, anonymous arrays holding two elements: the lower and upper bounds of the integer ranges needed to provide gap-filling as described in 'Purpose'. When the expand option is set, the contents of those inner sets are expanded to include the full range of integers needed, not just the beginning and end points.

Purpose: Generate a set of all sets needed in order to populate a set of consecutive integers from the lower to the upper bound, inclusive. The sets generated are derived from (a) the sets provided or (b) newly generated sets which fill in the gaps below, in between or above the provided sets.

Arguments: None required. expand = 1> is optional (see FAQ).

Returns: A reference to an anonymous array whose elements are, in turn, anonymous arrays holding the sets described in 'Purpose'. When the expand option is set, the contents of those inner sets are expanded to include the full range of integers needed, not just the beginning and end points.

In an earlier implementation, Set::Integer::Gapfillers calculated its return values by supplying the constructor's sets argument with a list of references to arrays of consecutive integers -- [ 12 .. 22 ] -- rather than a list of references to two-element arrays of the lower and upper bounds of the integer ranges desired -- [ 12, 22 ]. All internal calculations were made by comparing the lower and upper bounds supplied with the arrays supplied. This proved to be a memory hog and slow.

Set::Integer::Gapfillers was then revised to require the user to supply only the beginning and end points of the provided segments. Although this complicated the logic of the internal calculations for the module author, it led to a vastly reduced memory footprint and vast speedup in producing results. It was therefore decided to make the output methods return values in the same manner, i.e., beginning and end points of ranges, rather than the entire ranges.

However, what an end-user of Set::Integer::Gapfillers might really be after is those entire ranges. Hence, the expand = 1> option is provided so that the results look like this:

This Perl extension has its origin in a question I posed on Perlmonks (http://perlmonks.org/?node_id=539350). BrowserUK's response (http://perlmonks.org/?node_id=539357) was ingenious and terse and led me to think that the solution could be modularized. However, when I realized that my original question had not fully specified my objective, I found I could no longer use BrowserUK's algorithm and had to work my own out -- so any bugs are my fault, not his!