#!/usr/bin/perl -w
use strict;

sub range
{
         my $list = shift;
         my $in_range = 0;
         my @range_list;
         my $last = $list->[0];
         my $start = $list->[0];

         my $sentinel = $list->[-1]; 
         push @$list, ( $sentinel + 2 ); # forces the machine in state 0
                                                   # makes sure the last range/element is pushed
         for my $i ( @$list )
         {
                 if( $in_range == 2 )
                 {
                         if( $i == $last + 1 )
                         {
                                 $last = $i; # go eat up the range
                         }
                         else
                         {
                                 push @range_list, "$start-$last";
                                 $in_range = 0; # rewind back to state 0
                         }
                 }
                 if( $in_range == 1 )
                 {
                         if( $i == $start + 1 )
                         {
                                 $last = $i;
                                 $in_range = 2; # range detected, shift to state 2
                         }
                         else
                         {
                                 push @range_list, $start;
                                 $in_range = 0;
                         }
                  }
                  if( $in_range == 0 )
                  {
                         $start = $i;
                         $in_range = 1; # try to look for range
                  }
         }
         join ", ", @range_list;
}

my @list = ( 1, 2, 4, 5, 6, 7, 9, 13, 24, 24, 24, 25, 26, 27, 29 );
my @list1 = ( -22, -21, -20, -15, -12, -10, -9, -8, -7, -6, -1 );

sub format_number_list {
  range([@_]);
}

my $range_str = range( \@list );

print "$range_str\n";

$range_str = range( \@list1 );

print "$range_str\n";
