-----Original Message-----
From: Janek Schleicher [mailto:[EMAIL PROTECTED]] 
Sent: 18 September 2002 18:32
To: [EMAIL PROTECTED]
Subject: RE: lots of numbers...


> You meant my $iterations = int( scalar @numbers / 3 );
> (However, the scalar cast isn't necessary)
> 
> my $iterations = int(@numbers/3);

Thanks for the correction! I miss my old 'div' operator for integer
division from languages past 8-)

> Or shorter
> my @groups = map { [pop(@numbers), shift(@numbers)] } ( 1 ..
$iterations );

also nice.

> But could it be, we missed the simplest, but acceptable algorithm:
>
> my @number = sort {$a <=> $b} @ARGV;
> 
> use List::Util qw/sum/;
> my @group;
> my $sum = sum @number;   # @number is already sorted
> my $avg = 3 * $sum / @number;  # wanted avg for each group
> while (@number >= 3) {
>    my $diff_to_avg = $avg - sum (my ($min,$max) = (shift @number, pop
@number));
> 
>    my $i = 0;      # index of the number nearest to the missing gap
for the wanted avg
>    foreach (1..$#number) {  # perhaps a binary search or smth else
will be quicker
>       $i = $_ if abs($diff_to_avg-$number[$_]) <
abs($diff_to_avg-$number[$i]);
>    }
> 
>    push @group, [$min, splice(@number, $i, 1), $max];
> }
> 
> push @group, \@number if @number;   # if there are some numbers left
> 
> foreach (@group) {
>    print join " ", @$_, "avg", (sum(@$_) / @$_);
>    print "\n";
> }

mmm - looks like a more complex approach to me?

The point of the first approach was to create approximate groups using
the smallest and largest values in a quick first pass. The bulk of the
work is easily performed. The second and final pass using the sorted
partial groups and the sorted remaining values will always associate the
best available value with the right partial group.

I think this would also be easier to extend to groups of more than three
numbers - you just extend the initial approximation pass to group more
numbers from either end. It gets a little more interesting when the
desired number of elements in a group is even, as you cant just blindly
grab both ends.

Using a sort feels simpler than calculating a target average and
iterating through all remaining numbers to see which value will bring
the partial group closest to the desired target. Remember that @numbers
is already sorted. I would guess that the 'calc a target and search for
best fit' algorithm actually does more work as coded above, consider
that it creates one partial group, and then searches through all
remaining numbers for the best fit. It then creates a second partial
group, and searches through all remaining numbers for the best fit, etc
etc etc.

Nighty nite!


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to