$ perl -Mstrict -Mwarnings -e ' use List::Util qw{first}; my @input = qw{12 14 15 20 21}; my @range_ends = qw{19 29 39}; my (@bins, %range_index_cache); sub get_range_index { ( first { $_[0] <= $range_ends[$_] } 0 .. $#range_ends ) // @range_ends; } for (@input) { ++$bins[$range_index_cache{$_} //= get_range_index($_)]; } for (0 .. $#range_ends) { printf "%d-%d %d\n" => $_ ? $range_ends[$_ - 1] + 1 : 1, $range_ends[$_], $bins[$_] // 0; } ' 1-19 3 20-29 2 30-39 0 #### $ perl -Mstrict -Mwarnings -e ' my @input = qw{12 14 15 20 21}; my $ranges = 3; my @bins; for (@input) { ++$bins[$_ / 20]; } for (0 .. $ranges - 1) { printf "%d-%d %d\n" => $_ * 20 || 1, $_ * 20 + 19, $bins[$_] // 0; } ' 1-19 3 20-39 2 40-59 0