#!/usr/bin/perl use strict; use warnings; use diagnostics; use List::Util qw(min); my $opt_x = 0; # Original code allows hex or decimal my @list = (1, 2, 3, 6, 9, 10, 13, 22, 20, 19, 15, 21); my %Count; $Count{$_}++ foreach @list; my $number; foreach $number (sort numerically keys(%Count)) { my $count = $Count{$number}; if ($count > 1) { printf "Token value %d occurs %d times.\n", $number, $count if (!$opt_x); printf "Token value 0x%x occurs %d times.\n", $number, $count if ( $opt_x); } } # Print a list of the form: # 100,102,104,108-110,112-115,119 my $expected = min(@list); my $in_list=0; my $list_start=0; my $comma=""; foreach $number (sort numerically keys(%Count)) { if (($number == $expected) && ($in_list)) { # Accumulate list $in_list++; } elsif (($number == $expected) && ($in_list == 0)) { $list_start=$number; $in_list = 1; } elsif ($in_list > 1) # not expected { printf "%s%d-%d", $comma, $list_start, $expected-1 if (!$opt_x); printf "%s0x%x-0x%x", $comma, $list_start, $expected-1 if ( $opt_x); $comma = ","; $list_start = $number; $in_list = 1; } else # in_list == 1 and not expected { printf "%s%d", $comma, $list_start if (!$opt_x); printf "%s0x%x", $comma, $list_start if ( $opt_x); $comma = ","; $list_start = $number; $in_list = 1; } $expected = $number + 1; } if ($in_list > 1) # Terminate { printf "%s%d-%d", $comma, $list_start, $expected-1 if (!$opt_x); printf "%s0x%x-0x%x", $comma, $list_start, $expected-1 if ( $opt_x); } elsif ($in_list) { printf "%s%d", $comma, $list_start if (!$opt_x); printf "%s0x%x", $comma, $list_start if ( $opt_x); } else { printf "%s%d", $comma, $number if (!$opt_x); printf "%s0x%x", $comma, $number if ( $opt_x); } print "\n"; sub numerically { return $a <=> $b; } exit 0;