Not sure if this is any use but is does give the expected output. It loops through the sorted list working out the effect of adding each to 'current group average'. If change is greater than the value 'diff' it starts a new group
#!perl
use strict;
my @data = (10,7,5,10,50,70,75,72,79,80);
my @arr = sort {$a<=>$b} @data;
my $diff = 2; # group closeness
my @avg; #[count,sum]
my @grp;
my $g=0;
for my $i (0..$#arr){
my $val = $arr[$i];
#print "value $val\n";
if ($i == 0){
push @{$grp[$g]},$val;
$avg[$g] = [1,$val];
} else {
#work out new average with this element
my ($n,$sum) = @{$avg[$g]};
#print "count $n sum $sum\n";
my $avg = $sum/$n;
my $new_avg = ($sum+$val)/($n+1);
if (abs($new_avg - $avg) < $diff){
# join group
push @{$grp[$g]},$val;
$avg[$g] = [$n+1,$sum+$val];
} else {
# start new group
++$g;
push @{$grp[$g]},$val;
$avg[$g] = [1,$val];
}
}
}
for (@grp) {
print join ',',@$_,"\n";
}
POJ |