#!/usr/bin/perl -w # Author: Chris Ball # Function: Provide a 'compact list' for an array of numbers. # Also at: http://printf.net/perl/compact.pl my @approx = @ARGV; my ($i, $inrange, $start, $end, $more); use strict; # Overview: # - Loop through the array. # - If the element after current matches (cur+1): # - Extend a range if we're in one. # - Set up a range if we aren't. # - If the element after current _isn't_ (cur+1): # - Mark/print the end of a range, or # - Print a number on its own if we weren't in a range. # - If the element after current just doesn't exist at all: # - Finish off a range or number tidily. map { # Loop through the array, using $_. my $cur = $approx[$_]; my $next = $approx[$_+1] if defined $approx[$_+1]; if ($next) { # Is there an array element after this one? if ($next != ($cur + 1)) { # If the next element _isn't_ current+1.. if ($inrange) { # If we're in a range, it needs to be finished. print "$start-$end,"; $inrange = 0; } else { # We're not in a range. print "$cur,"; } } else { # If the next array element is cur+1. if ($inrange) { # If we're already in a range, extend it by 1. $end++; } if (not $inrange) { # We're not in a range. Set start/end/inrange. $start = $approx[$_]; $end = $approx[$_+1]; $inrange = 1; } } } else { # It's the last element. Make things look tidy. if ($inrange) { print "$start-$end\n"; } else { print "$cur\n"; } } } 0..$#approx # -- end.