in reply to add missing elements and remove duplicates....and some more questions.
Here's another approach. Actually, I don't recommend you use this sort of thing in the "real" world, but it may have some degree of interest. (I'm addicted to regexes.)
The main thing I'd like to do is to bring to your attention a basic approach to algorithm development: unit test-based development. Specify a set of test cases, inputs and outputs, write your function, then check that every input yields the specified output. A new test case is easily added to the test set and the whole set can be very quickly retested. The function can be quickly changed and thoroughly retested. See Test::More and friends. (Caution: The example function needs Perl version 5.10+ for regex extensions.)
c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; use Test::More 'no_plan'; use Test::NoWarnings; ;; use Data::Dump qw(dd pp); ;; use constant TEST_1 => ( [ [], [] ], [ [0], [0] ], [ [1], [1] ], [ [-1], [-1] ], [ [1, 2], [1, 2] ], [ [1, 2, 3], [1, 2, 3] ], [ [1, 1], [1] ], [ [-1, -1], [-1] ], [ [10, 10, 20, 0x47, 1, 71, 30, 45, 45], [1..71] ], [ [10, 10, -1, 20, 0x47, -5, 1, 71, -1, 30, 45, 45], [-5..71] ], [ [1, 5, 1, 5], [1..5] ], [ [6, 9, 1, 5], [1..9] ], ); ;; VECTOR: for my $ar_vector (TEST_1) { my ($ar_test, $ar_expected) = @$ar_vector; ;; my $ar_got = [ range(@$ar_test) ]; is_deeply $ar_got, $ar_expected, pp($ar_test) . ' -> ' . pp($ar_expected); } ;; ;; sub range { my $joiner = q{,}; my $s = join $joiner, sort { 0+$a <=> 0+$b } @_; ;; my $n = qr{ (?: \b | -) \d+ \b }xms; $s =~ s{ ($n) \K (?: , \1 \b)+ }''xmsg; ;; use re 'eval'; $s =~ s{ ($n) (?{ $^N }) , \K (?= ($n) (?(?{ $^R == $^N-1 }) (*F))) + } { join $joiner, $^R+1 .. $^N-1, '' }xmsge; ;; return split $joiner, $s; } " ok 1 - [] -> [] ok 2 - [0] -> [0] ok 3 - [1] -> [1] ok 4 - [-1] -> [-1] ok 5 - [1, 2] -> [1, 2] ok 6 - [1, 2, 3] -> [1, 2, 3] ok 7 - [1, 1] -> [1] ok 8 - [-1, -1] -> [-1] ok 9 - [10, 10, 20, 71, 1, 71, 30, 45, 45] -> [1 .. 71] ok 10 - [10, 10, -1, 20, 71, -5, 1, 71, -1, 30, 45, 45] -> [-5 .. 71] ok 11 - [1, 5, 1, 5] -> [1 .. 5] ok 12 - [6, 9, 1, 5] -> [1 .. 9] ok 13 - no warnings 1..13
Update: As an example of a quick-turnaround function re-write, let's say you wanted to use the slightly saner function
instead of the regex nightmare posted above. Just how many steps to completely retest?sub range { return @_ unless @_ > 1; my ($min, $max) = (sort { 0+$a <=> 0+$b } @_)[0, -1]; return $min .. $max; }
Give a man a fish: <%-{-{-{-<
|
|---|