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 .. $#possibilities; 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 for ", $target - $try, " with possibilities @internal_possibilities\n"; @match = sum_to($target - $try, \@internal_so_far, \@internal_possibilities) and last INDEX; } return @match ? ( $try, @match ) : (); }