Subset sum problem: Difference between revisions

→‎{{header|Perl}}: Sort hash for consistency, use new ntheory with loop exit construct
(Added Kotlin)
(→‎{{header|Perl}}: Sort hash for consistency, use new ntheory with loop exit construct)
Line 1,052:
{{libheader|ntheory}}
<lang perl>use ntheory qw/:all/;
my $print_all_combinations = 0;
 
my %pairs = (
Line 1,063 ⟶ 1,062:
mincemeat => -880, moresby => 756, mycenae => 183, plugging => -266,
smokescreen => 423, speakeasy => -745, vein => 813 );
# sort so we get the same order each time
my @names = keys(%pairs);
my @weightsnames = valuessort keys(%pairs);
my @weights = @pairs{@names}; # hash slice gives all values in same order
 
foreach my $n (1 .. @names) {
if ($print_all_combinations) {
 
foreach my $n (1 .. @names) {
forcomb {
# Remove the "lastfor, " to get all combinations
lastfor, print "Length $n: @names[@_]\n" unlessif vecsum(@weights[@_]) == 0;
} @names, $n;
}
 
} else {
 
foreach my $n (1 .. @names) {
eval {
forcomb {
if (vecsum(@weights[@_]) == 0) {
print "Length $n: @names[@_]\n";
die;
}
} @names, $n;
};
}
}</lang>
Printing just the first one found for each number of elements:
Line 1,091 ⟶ 1,076:
<pre>
Length 2: archbishop gestapo
Length 3: exorcismcentipede fiatmarkham veinmycenae
Length 4: efferentalliance pluggingbalm brutedeploy centipedemycenae
Length 5: efferentalliance exorcismbrute cobolcovariate fiatdeploy balmmincemeat
Length 6: efferentalliance exorcismarchbishop isisbalm veindeploy gestapo mycenae
Length 7: efferentalliance exorcismarchbishop isisbonnet cobol covariatedeparture gestapoexorcism deploymoresby
Length 8: efferentalliance exorcismarchbishop isisbalm speakeasybonnet covariatefiat veinflatworm escritoireisis balmlindholm
Length 9: alliance archbishop balm bonnet brute covariate eradicate mincemeat plugging
Length 9: efferent exorcism isis speakeasy cobol markham smokescreen lindholm balm
... to length 27 ...
</pre>
 
We can also use different modules for this brute force method. Assuming the same pairs/names/weights variables set and first combination only, this iterator style is a little cleaner when wanting to exit early:
<lang perl>use List::Util qw/sum/;
use Algorithm::Combinatorics qw/combinations/;
Anonymous user