Alan Burlison's Work Related Ramblings

All | General | Java | NetBeans | Perl | Solaris
« Previous day (Apr 4, 2006) | Main | Next day (Apr 5, 2006) »

20060405 Wednesday April 05, 2006

A sort of perl golf challenge

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]