in reply to Re: Divide array of integers into most similar value halves
in thread Divide array of integers into most similar value halves
The algorithm I used to find that match is based on my imperfect recall of the one from Dominus's book mentioned by moritz. I'm sure it can be made much more elegant (for example, by not hard-wiring @list; and, less trivially, by not passing in $so_far_ref—I was just using it to print the diagnostics), but I think that this works:
use List::Util qw/first sum/; use strict; use warnings 'all'; my @list = (62, 83, 121, 281, 486, 734, 771, 854, 885, 1003); my $sum = sum(@list)/2; print "Trying for $sum with possibilities @list\n"; my @match = sum_to($sum, [], \@list); print @match ? "MATCH @match\n" : "No match\n"; sub sum_to { my ( $target, $so_far_ref, $possibilities_ref ) = @_; my @so_far = @$so_far_ref; my @possibilities = @$possibilities_ref; local $_; my $exact = first { $_ == $target } @possibilities; return $exact if $exact; local $_; my @indices = grep { $possibilities[$_] <= $target } 0 .. $#po +ssibilities; unless ( @indices ) { print "That branch didn't work.\n"; return; } my ( $sum, $try, @match ); INDEX: for my $index ( @indices ) { my @internal_possibilities = @possibilities; my @internal_so_far = @so_far; $try = splice @internal_possibilities, $index, 1; push @internal_so_far, $try; print "Guessed @internal_so_far; recursively trying fo +r ", $target - $try, " with possibilities @internal_possibilities\n"; @match = sum_to($target - $try, \@internal_so_far, \@i +nternal_possibilities) and last INDEX; } return @match ? ( $try, @match ) : (); }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Divide array of integers into most similar value halves
by FunkyMonk (Bishop) on Sep 01, 2008 at 22:29 UTC | |
|
Re^3: Divide array of integers into most similar value halves
by Pepe (Sexton) on Sep 02, 2008 at 02:57 UTC |