Wednesday April 05, 2006
I've been reviewing some perl code code that is due to go back into Solaris shortly, and one of the routines takes a sorted array of integers and returns a string with contiguous ranges of numbers collapsed and other numbers comma-separated. For example, given an array containing 1, 3, 4, 5, 8, 9, 10, 12 the routine would return the string "1, 3-5, 8-10, 12". The routine iterates over the array looking for and collapsing sequences of numbers. It's 30 lines long, but always being one for taking up a pointless challenge I wondered if I could make it any shorter. Here's what I came up with:
sub collapse
{
my $str = join(', ', @_);
while ($str =~ s{\b(\d+), ((??{ $1 + 1 }))\b}{$1-$2}g) {}
$str =~ s{-(?:\d+-)+}{-}g;
return ($str);
}
Now I know that under the proper perl golf rules I could shorten that down by removing whitespace, using implicit assignment and matches against $_ and so forth but I'm more interested in seeing if anyone can come up with a conceptually shorter solution (i.e. one that I can still read ;-). It occured to me that you might be able to do something smart with a recursive regexp, but the requirement to use $1 + 1 to spot a sequence kept stymieing me. However I'm sure some other perl saddo out there will come up with something even shorter and far smarter. Anyone? ;-)
Posted by alanbur
( Apr 05 2006, 10:20:31 PM BST )
Permalink
Comments [9]