Subset sum problem: Difference between revisions

m
(Show a non-brute-force Mathematica solution.)
m (→‎{{header|Wren}}: Minor tidy)
 
(48 intermediate revisions by 23 users not shown)
Line 1:
{{draft task|Discrete math}}
 
;Task:
Implement a function/procedure/method/subroutine that takes a set/array/list/stream/table/collection of words with integer weights, and identifies a non-empty subset of them whose weights sum to zero (cf. the Dropbox [http://www.dropbox.com/jobs/challenges Diet] candidate screening exercise and the [[wp:Subset sum problem|Subset sum problem]] Wikipedia article).
 
 
For example, for this set of weighted words, one solution would be the set of words {elysee, efferent, deploy, departure, centipede, bonnet, balm, archbishop}, because
;For example:
their respective weights of -326, 54, 44, 952, -658, 452, 397, and -915 sum to zero.
This set of weighted words, one solution would be the set of words:
|
:::*   {elysee,   efferent,   deploy,   departure,   centipede,   bonnet,   balm,   archbishop}
{| style="text-align: left; width: 40%;" border="4" cellpadding="2" cellspacing="2"
because their respective weights of:
|+ Table of weighted words
:::*   -326,   54,   44,   952,   -658,   452,   397,   and   -915
sum to zero.
 
:::::: {| style="text-align: left; width: 40%;" border="5" cellpadding="2" cellspacing="2"
|+             Table of weighted words
|- style="background-color: rgb(255, 204, 255);"
! word !! weight
Line 73 ⟶ 79:
| vein || 813
|}
 
 
Another solution would be the set of words {flatworm, gestapo, infra, isis, lindholm, plugging, smokescreen, speakeasy}, because their respective weights of 503, 915, -847, -982, 999, -266, 423, and -745 also sum to zero.
 
You may assume the weights range from -1000 to 1000.
You may assume the weights range from -1000 to 1000. If there are multiple solutions, only one needs to be found. Use any algorithm you want and demonstrate it on a set of at least 30 weighted words with the results shown in a human readable form. Note that an implementation that depends on enumerating all possible subsets is likely to be infeasible.
 
If there are multiple solutions, only one needs to be found.
 
Use any algorithm you want and demonstrate it on a set of at least 30 weighted words with the results shown in a human readable form.
 
Note that an implementation that depends on enumerating all possible subsets is likely to be infeasible.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V words = [
‘alliance’ = -624, ‘archbishop’ = -925, ‘balm’ = 397,
‘bonnet’ = 452, ‘brute’ = 870, ‘centipede’ = -658,
‘cobol’ = 362, ‘covariate’ = 590, ‘departure’ = 952,
‘deploy’ = 44, ‘diophantine’ = 645, ‘efferent’ = 54,
‘elysee’ = -326, ‘eradicate’ = 376, ‘escritoire’ = 856,
‘exorcism’ = -983, ‘fiat’ = 170, ‘filmy’ = -874,
‘flatworm’ = 503, ‘gestapo’ = 915, ‘infra’ = -847,
‘isis’ = -982, ‘lindholm’ = 999, ‘markham’ = 475,
‘mincemeat’ = -880, ‘moresby’ = 756, ‘mycenae’ = 183,
‘plugging’ = -266, ‘smokescreen’ = 423, ‘speakeasy’ = -745,
‘vein’ = 813
]
 
V neg = 0
V pos = 0
L(w, v) words
I v > 0
pos += v
E
neg += v
 
V sums = [[String]()] * (pos - neg + 1)
 
L(w, v) words
V s = copy(sums)
I s[v - neg].empty
s[v - neg] = [w]
 
L(w2) sums
V i = L.index
I !w2.empty & s[i + v].empty
s[i + v] = w2 [+] [w]
 
sums = s
I !s[-neg].empty
L(x) s[-neg]
print(x‘ ’words[x])
L.break</syntaxhighlight>
 
{{out}}
<pre>
alliance -624
archbishop -925
balm 397
bonnet 452
centipede -658
cobol 362
departure 952
deploy 44
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE PTR="CARD"
DEFINE PAIR_SIZE="4"
 
TYPE Pair=[PTR word INT weight]
 
BYTE ARRAY pairs(200)
BYTE count=[0]
 
PTR FUNC GetPairAddr(INT index)
RETURN (pairs+index*PAIR_SIZE)
 
PROC PrintWords(BYTE ARRAY indices BYTE len)
Pair POINTER p
BYTE i
 
FOR i=0 TO len-1
DO
IF i>0 THEN Put(' ) FI
p=GetPairAddr(indices(i))
Print(p.word)
OD
PutE()
RETURN
 
PROC Append(CHAR ARRAY wrd INT wght)
Pair POINTER dst
 
dst=GetPairAddr(count)
dst.word=wrd
dst.weight=wght
count==+1
RETURN
 
PROC Init()
Append("alliance",-624) Append("archbishop",-915)
Append("balm",397) Append("bonnet",452)
Append("brute",870) Append("centipede",-658)
Append("cobol",362) Append("covariate",590)
Append("departure",952) Append("deploy",44)
Append("diophantine",645) Append("efferent",54)
Append("elysee",-326) Append("eradicate",376)
Append("escritoire",856) Append("exorcism",-983)
Append("fiat",170) Append("filmy",-874)
Append("flatworm",503) Append("gestapo",915)
Append("infra",-847) Append("isis",-982)
Append("lindholm",999) Append("markham",475)
Append("mincemeat",-880) Append("moresby",756)
Append("mycenae",183) Append("plugging",-266)
Append("smokescreen",423) Append("speakeasy",-745)
Append("vein",813)
RETURN
 
INT FUNC Sum(BYTE ARRAY indices BYTE len)
Pair POINTER p
INT sum
BYTE i
 
sum=0
FOR i=0 TO len-1
DO
p=GetPairAddr(indices(i))
sum==+p.weight
OD
RETURN (sum)
 
BYTE FUNC NextSubset(BYTE ARRAY indices BYTE len)
INT i,j
 
i=len-1
WHILE i>=0
DO
IF indices(i)#i+count-len THEN
indices(i)==+1
FOR j=i+1 TO len-1
DO
indices(j)=indices(j-1)+1
OD
RETURN (1)
FI
i==-1
OD
RETURN (0)
 
PROC Test(INT len)
BYTE ARRAY indices(100)
BYTE i
 
PrintF("%I: ",len)
FOR i=0 TO len-1
DO
indices(i)=i
OD
DO
IF Sum(indices,len)=0 THEN
PrintWords(indices,len) PutE()
RETURN
FI
IF NextSubset(indices,len)=0 THEN
PrintE("no subset") PutE()
RETURN
FI
OD
RETURN
 
PROC Main()
Init()
Test(2)
Test(3)
Test(4)
Test(5)
Test(10)
Test(27)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Subset_sum_problem.png Screenshot from Atari 8-bit computer]
<pre>
2: archbishop gestapo
 
3: centipede markham mycenae
 
4: alliance balm deploy mycenae
 
5: alliance brute covariate deploy mincemeat
 
10: alliance archbishop balm bonnet brute centipede cobol departure deploy mincemeat
 
27: alliance archbishop balm bonnet brute centipede covariate departure deploy efferent elysee eradicate escritoire exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging smokescreen speakeasy
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure SubsetSum is
Line 134 ⟶ 333:
end loop;
end loop;
end SubsetSum;</langsyntaxhighlight>
{{out}}
<pre>2: archbishop gestapo
Line 164 ⟶ 363:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
 
typedef struct { void* data; int weight; } item;
char *word;
int weight;
} item_t;
 
item_t items[] = {
uint64_t subsum(item *x, int n)
{"alliance", -624},
{
{"archbishop", -915},
int i, j, w, from, to, step, pos = 0, neg = 0;
{"balm", 397},
uint64_t bit, *buf;
{"bonnet", 452},
{"brute", 870},
{"centipede", -658},
{"cobol", 362},
{"covariate", 590},
{"departure", 952},
{"deploy", 44},
{"diophantine", 645},
{"efferent", 54},
{"elysee", -326},
{"eradicate", 376},
{"escritoire", 856},
{"exorcism", -983},
{"fiat", 170},
{"filmy", -874},
{"flatworm", 503},
{"gestapo", 915},
{"infra", -847},
{"isis", -982},
{"lindholm", 999},
{"markham", 475},
{"mincemeat", -880},
{"moresby", 756},
{"mycenae", 183},
{"plugging", -266},
{"smokescreen", 423},
{"speakeasy", -745},
{"vein", 813},
};
 
forint (in = 0;sizeof i(items) </ n;sizeof i++(item_t);
int *set;
if (x[i].weight >= 0) pos += x[i].weight;
else neg += x[i].weight;
 
void subsum (int i, int weight) {
buf = calloc(pos - neg + 1, sizeof(uint64_t));
int j;
buf -= neg;
if (i && !weight) {
for (j = 0; j < i; j++) {
item_t item = items[set[j]];
printf("%s%s", j ? " " : "", items[set[j]].word);
}
printf("\n");
}
for (j = i ? set[i - 1] + 1: 0; j < n; j++) {
set[i] = j;
subsum(i + 1, weight + items[j].weight);
}
}
 
int main () {
for (i = 0; i < n; i++) {
set = malloc(n * sizeof (int));
w = x[i].weight;
subsum(0, 0);
bit = (uint64_t)1 << i;
return 0;
}</syntaxhighlight>
 
{{output}}<pre>alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism fiat filmy flatworm mincemeat plugging speakeasy
if (w < 0) from = neg, to = pos + 1, step = 1;
...</pre>
else from = pos, to = neg - 1, step = -1;
 
=={{header|C sharp|C#}}==
for (j = from; j != to; j += step)
{{trans|Java}}
if (buf[j]) buf[j + w] = buf[j] | bit;
<syntaxhighlight lang="csharp">using System;
buf[w] = bit;
using System.Collections.Generic;
 
namespace SubsetSum {
if (buf[0]) break;
class Item {
}
public Item(string word, int weight) {
Word = word;
Weight = weight;
}
 
public string Word { get; set; }
bit = buf[0];
public int Weight { get; set; }
free(buf + neg);
 
public override string ToString() {
return bit;
return string.Format("({0}, {1})", Word, Weight);
}
}
}
 
class Program {
int main(void)
private static readonly List<Item> items = new List<Item>() {
{
new Item("alliance", -624),
item em[] = {
{"alliance", -624}, { new Item("archbishop", -915}, {"balm", 397}),
new Item("balm", 397),
{"bonnet", 452}, {"brute", 870}, {"centipede", -658},
new Item("bonnet", 452),
{"cobol", 362}, {"covariate", 590}, {"departure", 952},
new Item("brute", 870),
{"deploy", 44}, {"diophantine", 645}, {"efferent", 54},
new Item("centipede", -658),
{"elysee", -326}, {"eradicate", 376}, {"escritoire", 856},
new Item("cobol", 362),
{"exorcism", -983}, {"fiat", 170}, {"filmy", -874},
new Item("covariate", 590),
{"flatworm", 503}, {"gestapo", 915}, {"infra", -847},
new Item("departure", 952),
{"isis", -982}, {"lindholm", 999}, {"markham", 475},
new Item("deploy", 44),
{"mincemeat", -880}, {"moresby", 756}, {"mycenae", 183},
new Item("diophantine", 645),
{"plugging", -266}, {"smokescreen", 423}, {"speakeasy", -745},
new Item("efferent", 54),
{"vein", 813}
new Item("elysee", -326),
};
new Item("eradicate", 376),
new Item("escritoire", 856),
new Item("exorcism", -983),
new Item("fiat", 170),
new Item("filmy", -874),
new Item("flatworm", 503),
new Item("gestapo", 915),
new Item("infra", -847),
new Item("isis", -982),
new Item("lindholm", 999),
new Item("markham", 475),
new Item("mincemeat", -880),
new Item("moresby", 756),
new Item("mycenae", 183),
new Item("plugging", -266),
new Item("smokescreen", 423),
new Item("speakeasy", -745),
new Item("vein", 813),
};
 
private static readonly int n = items.Count;
uint64_t i, v, ret = subsum(em, sizeof(em)/sizeof(em[0]));
private static readonly int LIMIT = 5;
if (!ret) {
puts("no zero sums\n");
return 1;
}
 
private static int[] indices = new int[n];
puts("Found zero sum:");
private static int count = 0;
for (i = 0; i < 64; i++) {
v = (uint64_t)1 << i;
if (ret & v)
printf("%2llu | %5d %s\n", i, em[i].weight, (char*)em[i].data);
}
 
private static void ZeroSum(int i, int w) {
return 0;
if (i != 0 && w == 0) {
}</lang>{{out}}
for (int j = 0; j < i; j++) {
Found zero sum:
Console.Write("{0} ", items[indices[j]]);
1 | -915 archbishop
2 | 397 balm }
Console.WriteLine("\n");
3 | 452 bonnet
if (count < LIMIT) count++;
5 | -658 centipede
8 | 952 departure else return;
9 | 44 deploy }
int k = (i != 0) ? indices[i - 1] + 1 : 0;
11 | 54 efferent
for (int j = k; j < n; j++) {
12 | -326 elysee
indices[i] = j;
ZeroSum(i + 1, w + items[j].Weight);
if (count == LIMIT) return;
}
}
 
static void Main(string[] args) {
Code for listing ''all'' zero sum sets. It's pretty fast for this example, takes seconds even if printing all 300k+ combinations is enabled.
Console.WriteLine("The weights of the following {0} subsets add up to zero:\n", LIMIT);
<lang c>#include <stdio.h>
ZeroSum(0, 0);
#include <stdlib.h>
}
}
}</syntaxhighlight>
{{out}}
<pre>The weights of the following 5 subsets add up to zero:
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (escritoire, 856) (exorcism, -983) (fiat, 170) (filmy, -874) (flatworm, 503) (mincemeat, -880) (plugging, -266) (speakeasy, -745)
typedef struct { const char* data; int weight; } item;
typedef struct { int sum; unsigned int mask; } sum_t;
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (escritoire, 856) (exorcism, -983) (infra, -847) (isis, -982) (mincemeat, -880) (moresby, 756) (mycenae, 183) (smokescreen, 423) (speakeasy, -745)
item em[] = {
{"alliance", -624}, {"archbishop", -915}, {"balm", 397},
{"bonnet", 452}, {"brute", 870}, {"centipede", -658},
{"cobol", 362}, {"covariate", 590}, {"departure", 952},
{"deploy", 44}, {"diophantine", 645}, {"efferent", 54},
{"elysee", -326}, {"eradicate", 376}, {"escritoire", 856},
{"exorcism", -983}, {"fiat", 170}, {"filmy", -874},
{"flatworm", 503}, {"gestapo", 915}, {"infra", -847},
{"isis", -982}, {"lindholm", 999}, {"markham", 475},
{"mincemeat", -880}, {"moresby", 756}, {"mycenae", 183},
{"plugging", -266}, {"smokescreen", 423}, {"speakeasy", -745},
{"vein", 813}
};
#define N (sizeof(em)/sizeof(em[0]))
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (escritoire, 856) (fiat, 170) (infra, -847) (isis, -982) (markham, 475) (mincemeat, -880) (plugging, -266) (speakeasy, -745)
int cmp_sums(const void *a, const void *b)
{
return ((const sum_t*)a)->sum - ((const sum_t*)b)->sum;
}
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (exorcism, -983) (fiat, 170) (infra, -847) (isis, -982) (mincemeat, -880) (moresby, 756) (plugging, -266) (vein, 813)
sum_t *mksums(const item *p, int n, int shift)
{
sum_t *r = malloc(sizeof(*r) * (1 << n));
int i;
for (i = 0; i < n; i++)
r[1<<i].sum = p[i].weight;
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (exorcism, -983) (fiat, 170) (infra, -847) (isis, -982) (smokescreen, 423)</pre>
r[0].mask = 0, r[0].sum = 0;
 
=={{header|C++}}==
for (i = 1; i < 1<<n; i++) {
{{trans|C#}}
unsigned int b = i & -(int)i;
<syntaxhighlight lang="cpp">#include <iostream>
r[i].mask = i << shift;
#include <vector>
r[i].sum = r[i & ~b].sum + r[b].sum;
}
 
std::ostream& operator<<(std::ostream& out, const std::string& str) {
qsort(r, 1<<n, sizeof(*r), cmp_sums);
return rout << str.c_str();
}
 
std::vector<std::pair<std::string, int>> items{
int main(void)
{"alliance", -624},
{
{"archbishop", -915},
int n1 = N / 2, n2 = N - n1, i, j, i1, j1, sols = 0;
{"balm", 397},
#define SHOW_ALL 1
{"bonnet", 452},
#define N1 (1 << n1)
{"brute", 870},
#define N2 (1 << n2)
{"centipede", -658},
sum_t *l = mksums(em, n1, 0),
{"cobol", 362},
*r = mksums(em + n1, n2, n1);
{"covariate", 590},
{"departure", 952},
{"deploy", 44},
{"diophantine", 645},
{"efferent", 54},
{"elysee", -326},
{"eradicate", 376},
{"escritoire", 856},
{"exorcism", -983},
{"fiat", 170},
{"filmy", -874},
{"flatworm", 503},
{"gestapo", 915},
{"infra", -847},
{"isis", -982},
{"lindholm", 999},
{"markham", 475},
{"mincemeat", -880},
{"moresby", 756},
{"mycenae", 183},
{"plugging", -266},
{"smokescreen", 423},
{"speakeasy", -745},
{"vein", 813},
};
 
std::vector<int> indices;
void showmask(unsigned int mask)
int count = 0;
{
unsignedconst int mLIMIT = 5;
for (m = 0; (1<<m) <= mask; m++) {
if (mask & (1<<m))
printf("(%s,%d) ", em[m].data, em[m].weight);
}
if (mask) puts("");
}
 
void subsum(int i, int weight) {
int printlist() {
int x, y, s =if (i1i -!= i)0 *&& (jweight -== j10); {
for (int j = 0; j < i; ++j) {
if (!l[i].sum) s--;
auto item = items[indices[j]];
 
std::cout << (j ? " " : "") << item.first;
if (SHOW_ALL)
for (x = i; x < i1; x++) }
std::cout << '\n';
for (y = j; y > j1; y--)
if (count < LIMIT) count++;
showmask(l[x].mask | r[y].mask);
else return;
return s;
}
}
int k = (i != 0) ? indices[i - 1] + 1 : 0;
for (int j = k; j < items.size(); ++j) {
indices[i] = j;
subsum(i + 1, weight + items[j].second);
if (count == LIMIT) return;
}
}
 
int main() {
i = 0, j = N2 - 1;
indices.resize(items.size());
while (1) {
subsum(0, 0);
while (l[i].sum + r[j].sum) {
return 0;
while (i < N1 && l[i].sum + r[j].sum < 0) i++;
}</syntaxhighlight>
while (j >= 0 && l[i].sum + r[j].sum > 0) j--;
{{out}}
if (i >= N1 || j < 0) break;
<pre>alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism fiat filmy flatworm mincemeat plugging speakeasy
}
alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism infra isis mincemeat moresby mycenae smokescreen speakeasy
if (i >= N1 || j < 0) break;
alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire fiat infra isis markham mincemeat plugging speakeasy
 
alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism fiat infra isis mincemeat moresby plugging vein
for (i1 = i + 1; i1 < N1 && l[i1].sum == l[i].sum; i1++);
alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism fiat infra isis smokescreen</pre>
for (j1 = j - 1; j1 >= 0 && r[j1].sum == r[j].sum; j1--);
 
sols += printlist();
 
i = i1, j = j1;
}
printf("zero sums: %d\n", sols);
 
return 0;
}</lang>
 
=={{header|D}}==
A simple brute-force solution. This used the module of the third D solution of the Combinations Task.
{{trans|Ruby}}
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.algorithm, std.typecons, combinations3;
 
Line 367 ⟶ 632:
comb.map!q{ a[0] });
"No solution found.".writeln;
}</langsyntaxhighlight>
{{out}}
<pre>A subset of length 2: archbishop, gestapo</pre>
Line 374 ⟶ 639:
This version prints all the 349_167 solutions in about 1.8 seconds and counts them in about 0.05 seconds.
{{trans|C}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm;
 
enum showAllSolutions = true;
Line 470 ⟶ 735:
 
writeln("Zero sums: ", sols);
}</langsyntaxhighlight>
{{out}}
<pre>Zero sums: 349167</pre>
 
=={{header|EchoLisp}}==
===Dynamic programming===
We use the Pseudo-polynomial time dynamic programming solution, found in the [[wp:Subset sum problem|Subset sum problem]] Wikipedia article. If A and B are the min and max possible sums, the time and memory needed are '''O((B-A)*N)'''. '''Q''' is an array such as Q(i,s) = true if there is a nonempty subset of x0, ..., xi which sums to s.
<syntaxhighlight lang="scheme">
;; 0 <= i < N , A <= s < B , -A = abs(A)
;; mapping two dims Q(i,s) to one-dim Q(qidx(i,s)) :
 
(define-syntax-rule (qidx i s) (+ i (* (+ s -A) N)))
 
;; filling the Q array with true/false values
;; Q(i, s) := Q(i − 1, s) or (xi == s) or Q(i − 1, s − xi), for A ≤ s < B.
 
(define (fillQ xs (ds))
(define N (length xs))
(define A (apply + (filter negative? xs)))
(define B (1+ (apply + (filter positive? xs))))
(define -A (abs A))
(define Q (make-vector (* N (- B A))))
(set! xs (list->vector xs))
(printf "Q[%d] allocated." (vector-length Q))
(for ((s (in-range A B)))
(vector-set! Q (qidx 0 s ) (= [xs 0] s)))
(for* ([i (in-range 1 N)]
[s (in-range A B)])
(set! ds (- s [xs i]))
(vector-set! Q (qidx i s)
(or
[Q (qidx (1- i) s)]
(= [xs i] s)
(and (>= ds A) (< ds B) [Q (qidx (1- i) ds )])))
;; stop on first zero-sum found
#:break (and (zero? s) [Q (qidx i s)]) => (solQ Q xs i s -A N)
))
;; backtracking to get the list of i's such as sum([xs i]) = 0
;; start from q[i,0] === true
 
(define (solQ Q xs i s -A N (sol null))
(cond
(( = s [xs i]) (cons i sol))
([Q (qidx (1- i ) s)] (solQ Q xs (1- i) s -A N sol))
(else (solQ Q xs (1- i) (- s [xs i]) -A N (cons i sol)))))
(define (task input)
(map (lambda(i) (first (list-ref input i))) (fillQ (map rest input))))
 
</syntaxhighlight>
{{out}}
<pre>
(define input
'({"alliance" . -624}
{"archbishop" . -915}
{"balm" . 397}
{"bonnet" . 452}
{"brute" . 870}
{"centipede" . -658}
{"cobol" . 362}
{"covariate" . 590}
{"departure" . 952}
{"deploy" . 44}
{"diophantine" . 645}
{"efferent" . 54}
{"elysee" . -326}
{"eradicate" . 376}
{"escritoire" . 856}
{"exorcism" . -983}
{"fiat" . 170}
{"filmy" . -874}
{"flatworm" . 503}
{"gestapo" . 915}
{"infra" . -847}
{"isis" . -982}
{"lindholm" . 999}
{"markham" . 475}
{"mincemeat" . -880}
{"moresby" . 756}
{"mycenae" . 183}
{"plugging" . -266}
{"smokescreen" . 423}
{"speakeasy" . -745}
{"vein" . 813}))
(task input)
Q[587016] allocated.
→ ("archbishop" "balm" "bonnet" "centipede" "cobol" "covariate"
"deploy" "efferent" "elysee")
 
;; using Haskell test data
(define items
'[-61 1 32 373 311 249 311 32 -92 -185 -433
-402 -247 156 125 249 32 -464 -278 218 32 -123
-216 373 -185 -402 156 -402 -61 -31 902 ])
(map (lambda(i) (list-ref items i)) (fillQ items))
 
Q[221185] allocated.
→ (-61 32 373 311 249 311 32 -92 -185 -433 -402 -247 156 125 249 32 -
464 -278 218 32 -123 -216 373 -185 -402 156 -402 -61 902)
</pre>
===Brute force===
We use the '''powerset''' procrastinator which gives in sequence all subsets of the input list.
<syntaxhighlight lang="scheme">
(lib 'sequences) ;; for powerset
 
(define (sum0? xs)
(zero? (apply + (map rest xs))))
 
;; filter the powerset and
;; take first 5 solutions
(for-each writeln (take (filter sum0? (powerset input)) 5))
 
() ;; empty
 
(("archbishop" . -915) ("balm" . 397) ("bonnet" . 452)
("centipede" . -658) ("cobol" . 362) ("covariate" . 590)
("deploy" . 44) ("efferent" . 54) ("elysee" . -326))
(("archbishop" . -915) ("balm" . 397) ("bonnet" . 452)
("centipede" . -658) ("departure" . 952) ("deploy" . 44)
("efferent" . 54) ("elysee" . -326))
 
(("alliance" . -624) ("brute" . 870) ("centipede" . -658)
("cobol" . 362) ("elysee" . -326) ("eradicate" . 376))
(("alliance" . -624) ("archbishop" . -915) ("bonnet" . 452)
("centipede" . -658) ("cobol" . 362) ("covariate" . 590)
("deploy" . 44) ("diophantine" . 645) ("efferent" . 54)
("elysee" . -326) ("eradicate" . 376))
</syntaxhighlight>
 
=={{header|FunL}}==
<langsyntaxhighlight lang="funl">def subsetSum( s, w, v ) =
def sumset( a ) = foldl1( (+), map(w, a) )
Line 519 ⟶ 919:
 
for i <- 0..5
println( i, subsetSum(s, snd, i).get() )</langsyntaxhighlight>
 
{{out}}
Line 533 ⟶ 933:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 599 ⟶ 999:
}
fmt.Println("no subset sums to 0")
}</langsyntaxhighlight>
{{out}}
<pre>
Line 615 ⟶ 1,015:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">combinations :: Int -> [a] -> [[a]]
combinations 0 _ = [[]]
combinations _ [] = []
Line 646 ⟶ 1,046:
W "vein" 813]
 
main = print $ map word $ head $ solver items</langsyntaxhighlight>
{{out}}
<pre>["archbishop","gestapo"]</pre>
 
NoneNon bruteforcebrute-force: the list of numbers used here are different, and difficult for a bruteforce method.
<syntaxhighlight lang ="haskell">subsum w:: =Int snd.head.filter-> ((==w).fst).(++[(w,[Int])]).foldl s-> [(0,[])Int]
subsum w =
where
s a xsnd =. mergehead a. $filter map((== fw) a. wherefst) f. (a++ [(w,l [])]) =. foldl s [(a+x0, l++[x])]
where
s a x = merge a $ map f a
-- keep list of sums sorted and unique
where
merge [] a = a
f (a, l) = (a + x, l ++ [x])
merge a [] = a
merge a@((av,al):as) b@((bv,bl):bs)
-- Keep list of sums sorted and unique.
| av < bv = (av,al):merge as b
merge [] a = a
| av == bv = (bv,bl):merge as bs
| otherwise = (bv,bl): merge a bs[] = a
merge a@((av, al):as) b@((bv, bl):bs)
| av < bv = (av, al) : merge as b
| av == bv = (bv, bl) : merge as bs
| otherwise = (bv, bl) : merge a bs
items :: [Int]
items = [-61, 1, 32, 373, 311, 249, 311, 32, -92, -185, -433,
-402, -247, 156, 125, 249, 32, -464, -278, 218, 32, -123,
-216, 373, -185, -402, 156, -402, -61, -31, 902 ]
 
main :: IO ()
main = print $ subsum 0 items</lang>
main = print $ subsum 0 items</syntaxhighlight>
{{out}}
<pre>[-61,32,373,311,249,311,32,-92,-185,-433,-402,-247,156,125,249,32,-464,-278,218,32,-123,-216,373,-185,-402,156,-402,-61,902]</pre>
<pre>
[-61,32,373,311,249,311,32,-92,-185,-433,-402,-247,156,125,249,32,-464,-278,218,32,-123,-216,373,-185,-402,156,-402,-61,902]
</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
{{trans|Ruby}}
<langsyntaxhighlight Iconlang="icon">link printf,lists
 
procedure main()
Line 720 ⟶ 1,124:
 
return T
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 758 ⟶ 1,162:
No zero-sum subsets of length 31</pre>
 
=={{header|MathematicaJ}}==
 
<lang Mathematica>a = {{"alliance", -624}, {"archbishop", -915}, {"balm", 397}, {"bonnet", 452},
Task data:
 
<syntaxhighlight lang="j">text=:0 :0
alliance -624
archbishop -915
balm 397
bonnet 452
brute 870
centipede -658
cobol 362
covariate 590
departure 952
deploy 44
diophantine 645
efferent 54
elysee -326
eradicate 376
escritoire 856
exorcism -983
fiat 170
filmy -874
flatworm 503
gestapo 915
infra -847
isis -982
lindholm 999
markham 475
mincemeat -880
moresby 756
mycenae 183
plugging -266
smokescreen 423
speakeasy -745
vein 813
)
 
words=:{.@;:;._2 text
numbs=:+/|:0&".;._2 text</syntaxhighlight>
 
Implementation:
 
<syntaxhighlight lang="j">wsum0=:4 :0
p=:(#~ 0&<)y
n=:(#~ 0&>)y
poss=: +/@#~2#.inv 2 i.@^#
P=:poss p
N=:poss -n
choose=:(1{I.P e. N){P
keep=: [ #~ #&2@#@[ #: choose i.~ ]
;:inv words #~y e. (p keep P),n keep N
)</syntaxhighlight>
 
Task example:
 
<syntaxhighlight lang="j"> words wsum0 numbs
centipede markham mycenae</syntaxhighlight>
 
Note also that there are over 300,000 valid solutions here. More than can be comfortably displayed:
 
<syntaxhighlight lang="j"> Ps=: </.~ /:~ (I.P e. N){P
Ns=: </.~ /:~ (I.N e. P){N
+/#@,@{"1 Ps,.Ns
349168</syntaxhighlight>
 
(One of those is the empty solution, but the rest of them are valid.)
 
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">public class SubsetSum {
private static class Item {
private String word;
private int weight;
 
public Item(String word, int weight) {
this.word = word;
this.weight = weight;
}
 
@Override
public String toString() {
return String.format("(%s, %d)", word, weight);
}
}
 
private static Item[] items = new Item[]{
new Item("alliance", -624),
new Item("archbishop", -915),
new Item("balm", 397),
new Item("bonnet", 452),
new Item("brute", 870),
new Item("centipede", -658),
new Item("cobol", 362),
new Item("covariate", 590),
new Item("departure", 952),
new Item("deploy", 44),
new Item("diophantine", 645),
new Item("efferent", 54),
new Item("elysee", -326),
new Item("eradicate", 376),
new Item("escritoire", 856),
new Item("exorcism", -983),
new Item("fiat", 170),
new Item("filmy", -874),
new Item("flatworm", 503),
new Item("gestapo", 915),
new Item("infra", -847),
new Item("isis", -982),
new Item("lindholm", 999),
new Item("markham", 475),
new Item("mincemeat", -880),
new Item("moresby", 756),
new Item("mycenae", 183),
new Item("plugging", -266),
new Item("smokescreen", 423),
new Item("speakeasy", -745),
new Item("vein", 813),
};
 
private static final int n = items.length;
private static final int[] indices = new int[n];
private static int count = 0;
 
private static final int LIMIT = 5;
 
private static void zeroSum(int i, int w) {
if (i != 0 && w == 0) {
for (int j = 0; j < i; ++j) {
System.out.printf("%s ", items[indices[j]]);
}
System.out.println("\n");
if (count < LIMIT) count++;
else return;
}
int k = (i != 0) ? indices[i - 1] + 1 : 0;
for (int j = k; j < n; ++j) {
indices[i] = j;
zeroSum(i + 1, w + items[j].weight);
if (count == LIMIT) return;
}
}
 
public static void main(String[] args) {
System.out.printf("The weights of the following %d subsets add up to zero:\n\n", LIMIT);
zeroSum(0, 0);
}
}</syntaxhighlight>
{{out}}
<pre>The weights of the following 5 subsets add up to zero:
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (escritoire, 856) (exorcism, -983) (fiat, 170) (filmy, -874) (flatworm, 503) (mincemeat, -880) (plugging, -266) (speakeasy, -745)
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (escritoire, 856) (exorcism, -983) (infra, -847) (isis, -982) (mincemeat, -880) (moresby, 756) (mycenae, 183) (smokescreen, 423) (speakeasy, -745)
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (escritoire, 856) (fiat, 170) (infra, -847) (isis, -982) (markham, 475) (mincemeat, -880) (plugging, -266) (speakeasy, -745)
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (exorcism, -983) (fiat, 170) (infra, -847) (isis, -982) (mincemeat, -880) (moresby, 756) (plugging, -266) (vein, 813)
 
(alliance, -624) (archbishop, -915) (balm, 397) (bonnet, 452) (brute, 870) (centipede, -658) (cobol, 362) (covariate, 590) (departure, 952) (deploy, 44) (diophantine, 645) (efferent, 54) (elysee, -326) (eradicate, 376) (exorcism, -983) (fiat, 170) (infra, -847) (isis, -982) (smokescreen, 423)</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq''' (provided `keys_unsorted` is replaced by `keys`)
<syntaxhighlight lang="jq">
# Input: an array of n elements, each of which is either in or out
# Output: a stream of the 2^n possible selections
def selections:
# map( [null, .] ) | combinations | map(select(.));
if length == 0
then .
else .[0] as $x
| .[1:] | selections | ., ([$x] + .)
end ;
 
# input: a JSON object giving the weights
def zero_sums:
def sum($dict; $sum):
map( $dict[.] ) | add == $sum;
. as $dict
| keys_unsorted | selections | select( sum($dict; 0));
</syntaxhighlight>
'''An Example'''
<syntaxhighlight lang="jq">def weights:
{
"alliance": -624,
"archbishop": -915,
"balm": 397,
"bonnet": 452,
"brute": 870,
"centipede": -658,
"cobol": 362,
"covariate": 590,
"departure": 952,
"deploy": 44,
"diophantine": 645,
"efferent": 54,
"elysee": -326,
"eradicate": 376,
"escritoire": 856,
"exorcism": -983,
"fiat": 170,
"filmy": -874,
"flatworm": 503,
"gestapo": 915,
"infra": -847,
"isis": -982,
"lindholm": 999,
"markham": 475,
"mincemeat": -880,
"moresby": 756,
"mycenae": 183,
"plugging": -266,
"smokescreen": 423,
"speakeasy": -745,
"vein": 813
};
 
weights | first(zero_sums)</syntaxhighlight>
{{out}}
<pre>
[
"archbishop",
"balm",
"bonnet",
"centipede",
"cobol",
"covariate",
"deploy",
"efferent",
"elysee"
]
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Combinatorics
 
const pairs = [
"alliance" => -624, "archbishop" => -915, "balm" => 397, "bonnet" => 452,
"brute" => 870, "centipede" => -658, "cobol" => 362, "covariate" => 590,
"departure" => 952, "deploy" => 44, "diophantine" => 645, "efferent" => 54,
"elysee" => -326, "eradicate" => 376, "escritoire" => 856, "exorcism" => -983,
"fiat" => 170, "filmy" => -874, "flatworm" => 503, "gestapo" => 915,
"infra" => -847, "isis" => -982, "lindholm" => 999, "markham" => 475,
"mincemeat" => -880, "moresby" => 756, "mycenae" => 183, "plugging" => -266,
"smokescreen" => 423, "speakeasy" => -745, "vein" => 813]
const weights = [v for (k, v) in pairs]
const weightkeyed = Dict(Pair(v, k) for (k, v) in pairs)
 
function zerosums()
total = 0
for i in 1:length(weights)
print("\nFor length $i: ")
sets = [a for a in combinations(weights, i) if sum(a) == 0]
if (n = length(sets)) == 0
print("None")
else
total += n
print("$n sets, example: ", map(x -> weightkeyed[x], rand(sets)))
end
end
println("\n\nGrand total sets: $total")
end
 
zerosums()
</syntaxhighlight>{{out}}
<pre>
For length 1: None
For length 2: 1 sets, example: ["archbishop", "gestapo"]
For length 3: 2 sets, example: ["centipede", "markham", "mycenae"]
For length 4: 9 sets, example: ["balm", "efferent", "filmy", "smokescreen"]
For length 5: 48 sets, example: ["departure", "elysee", "lindholm", "mincemeat", "speakeasy"]
For length 6: 178 sets, example: ["alliance", "bonnet", "centipede", "isis", "lindholm", "vein"]
For length 7: 629 sets, example: ["balm", "brute", "cobol", "deploy", "filmy", "isis", "mycenae"]
For length 8: 1634 sets, example: ["alliance", "brute", "centipede", "departure", "mincemeat", "mycenae", "plugging", "smokescreen"]
For length 9: 4040 sets, example: ["alliance", "brute", "deploy", "efferent", "elysee", "fiat", "filmy", "flatworm", "mycenae"]
For length 10: 8673 sets, example: ["archbishop", "brute", "escritoire", "filmy", "gestapo", "isis", "lindholm", "mincemeat", "moresby", "speakeasy"]
For length 11: 15680 sets, example: ["cobol", "covariate", "deploy", "efferent", "elysee", "eradicate", "exorcism", "filmy", "flatworm", "lindholm", "speakeasy"]
For length 12: 25492 sets, example: ["alliance", "balm", "diophantine", "efferent", "eradicate", "fiat", "filmy", "flatworm", "infra", "isis", "lindholm", "mycenae"]
For length 13: 35940 sets, example: ["alliance", "archbishop", "bonnet", "departure", "deploy", "efferent", "fiat", "filmy", "gestapo", "infra", "moresby", "mycenae", "plugging"]
For length 14: 44920 sets, example: ["archbishop", "centipede", "cobol", "covariate", "deploy", "efferent", "eradicate", "escritoire", "fiat", "gestapo", "isis", "mincemeat", "speakeasy", "vein"]
For length 15: 49368 sets, example: ["alliance", "archbishop", "bonnet", "covariate", "departure", "diophantine", "efferent", "elysee", "eradicate", "escritoire", "isis", "mincemeat", "plugging", "speakeasy", "vein"]
For length 16: 47835 sets, example: ["alliance", "archbishop", "balm", "bonnet", "centipede", "cobol", "covariate", "departure", "elysee", "flatworm", "infra", "isis", "moresby", "mycenae", "plugging", "smokescreen"]
For length 17: 40960 sets, example: ["balm", "bonnet", "centipede", "cobol", "covariate", "departure", "deploy", "diophantine", "efferent", "elysee", "eradicate", "fiat", "filmy", "isis", "mincemeat", "smokescreen", "speakeasy"]
For length 18: 31139 sets, example: ["balm", "bonnet", "centipede", "covariate", "departure", "deploy", "diophantine", "efferent", "elysee", "eradicate", "exorcism", "gestapo", "infra", "isis", "mincemeat", "mycenae", "speakeasy", "vein"]
For length 19: 20530 sets, example: ["alliance", "archbishop", "balm", "bonnet", "departure", "deploy", "elysee", "exorcism", "fiat", "gestapo", "infra", "isis", "lindholm", "markham", "mincemeat", "mycenae", "plugging", "smokescreen", "vein"]
For length 20: 11926 sets, example: ["archbishop", "bonnet", "brute", "centipede", "cobol", "deploy", "diophantine", "elysee", "eradicate", "exorcism", "fiat", "isis", "lindholm", "markham", "mincemeat", "moresby", "mycenae", "plugging", "smokescreen", "speakeasy"]
For length 21: 6089 sets, example: ["alliance", "balm", "bonnet", "brute", "centipede", "cobol", "covariate", "departure", "deploy", "elysee", "escritoire", "exorcism", "filmy", "flatworm", "infra", "isis", "markham", "mincemeat", "moresby", "mycenae", "plugging"]
For length 22: 2688 sets, example: ["archbishop", "balm", "bonnet", "brute", "centipede", "covariate", "deploy", "diophantine", "elysee", "eradicate", "exorcism", "filmy", "flatworm", "gestapo", "isis", "markham", "mincemeat", "moresby", "mycenae", "plugging", "smokescreen", "speakeasy"]
For length 23: 956 sets, example: ["alliance", "archbishop", "balm", "brute", "centipede", "cobol", "departure", "deploy", "efferent", "elysee", "eradicate", "escritoire", "exorcism", "fiat", "gestapo", "infra", "isis", "lindholm", "markham", "mincemeat", "moresby", "plugging", "speakeasy"]
For length 24: 341 sets, example: ["alliance", "archbishop", "balm", "brute", "centipede", "cobol", "covariate", "departure", "deploy", "diophantine", "efferent", "elysee", "eradicate", "escritoire", "exorcism", "infra", "isis", "lindholm", "markham", "mincemeat", "mycenae", "plugging", "smokescreen", "speakeasy"]
For length 25: 73 sets, example: ["alliance", "archbishop", "balm", "bonnet", "brute", "centipede", "cobol", "departure", "deploy", "diophantine", "efferent", "elysee", "exorcism", "fiat", "filmy", "flatworm", "gestapo", "infra", "isis", "lindholm", "markham", "mincemeat", "mycenae", "speakeasy", "vein"]
For length 26: 14 sets, example: ["alliance", "archbishop", "balm", "bonnet", "centipede", "cobol", "departure", "diophantine", "efferent", "elysee", "eradicate", "escritoire", "exorcism", "fiat", "filmy", "flatworm", "gestapo", "infra", "isis", "lindholm", "mincemeat", "mycenae", "plugging", "smokescreen", "speakeasy", "vein"]
For length 27: 2 sets, example: ["alliance", "archbishop", "balm", "brute", "centipede", "cobol", "covariate", "deploy", "diophantine", "efferent", "elysee", "eradicate", "exorcism", "fiat", "filmy", "flatworm", "gestapo", "infra", "isis", "lindholm", "mincemeat", "moresby", "mycenae", "plugging", "smokescreen", "speakeasy", "vein"]
For length 28: None
For length 29: None
For length 30: None
For length 31: None
 
Grand total sets: 349167
</pre>
 
=={{header|Kotlin}}==
{{trans|C}}
<syntaxhighlight lang="scala">// version 1.1.2
 
class Item(val word: String, val weight: Int) {
override fun toString() = "($word $weight)"
}
 
val items = arrayOf(
Item("alliance", -624),
Item("archbishop", -915),
Item("balm", 397),
Item("bonnet", 452),
Item("brute", 870),
Item("centipede", -658),
Item("cobol", 362),
Item("covariate", 590),
Item("departure", 952),
Item("deploy", 44),
Item("diophantine", 645),
Item("efferent", 54),
Item("elysee", -326),
Item("eradicate", 376),
Item("escritoire", 856),
Item("exorcism", -983),
Item("fiat", 170),
Item("filmy", -874),
Item("flatworm", 503),
Item("gestapo", 915),
Item("infra", -847),
Item("isis", -982),
Item("lindholm", 999),
Item("markham", 475),
Item("mincemeat", -880),
Item("moresby", 756),
Item("mycenae", 183),
Item("plugging", -266),
Item("smokescreen", 423),
Item("speakeasy", -745),
Item("vein", 813)
)
 
val n = items.size
val indices = IntArray(n)
var count = 0
 
const val LIMIT = 5
 
fun zeroSum(i: Int, w: Int) {
if (i != 0 && w == 0) {
for (j in 0 until i) print("${items[indices[j]]} ")
println("\n")
if (count < LIMIT) count++ else return
}
val k = if (i != 0) indices[i - 1] + 1 else 0
for (j in k until n) {
indices[i] = j
zeroSum(i + 1, w + items[j].weight)
if (count == LIMIT) return
}
}
 
fun main(args: Array<String>) {
println("The weights of the following $LIMIT subsets add up to zero:\n")
zeroSum(0, 0)
}</syntaxhighlight>
 
{{out}}
<pre>
The weights of the following 5 subsets add up to zero:
 
(alliance -624) (archbishop -915) (balm 397) (bonnet 452) (brute 870) (centipede -658) (cobol 362) (covariate 590) (departure 952) (deploy 44) (diophantine 645) (efferent 54) (elysee -326) (eradicate 376) (escritoire 856) (exorcism -983) (fiat 170) (filmy -874) (flatworm 503) (mincemeat -880) (plugging -266) (speakeasy -745)
 
(alliance -624) (archbishop -915) (balm 397) (bonnet 452) (brute 870) (centipede -658) (cobol 362) (covariate 590) (departure 952) (deploy 44) (diophantine 645) (efferent 54) (elysee -326) (eradicate 376) (escritoire 856) (exorcism -983) (infra -847) (isis -982) (mincemeat -880) (moresby 756) (mycenae 183) (smokescreen 423) (speakeasy -745)
 
(alliance -624) (archbishop -915) (balm 397) (bonnet 452) (brute 870) (centipede -658) (cobol 362) (covariate 590) (departure 952) (deploy 44) (diophantine 645) (efferent 54) (elysee -326) (eradicate 376) (escritoire 856) (fiat 170) (infra -847) (isis -982) (markham 475) (mincemeat -880) (plugging -266) (speakeasy -745)
 
(alliance -624) (archbishop -915) (balm 397) (bonnet 452) (brute 870) (centipede -658) (cobol 362) (covariate 590) (departure 952) (deploy 44) (diophantine 645) (efferent 54) (elysee -326) (eradicate 376) (exorcism -983) (fiat 170) (infra -847) (isis -982) (mincemeat -880) (moresby 756) (plugging -266) (vein 813)
 
(alliance -624) (archbishop -915) (balm 397) (bonnet 452) (brute 870) (centipede -658) (cobol 362) (covariate 590) (departure 952) (deploy 44) (diophantine 645) (efferent 54) (elysee -326) (eradicate 376) (exorcism -983) (fiat 170) (infra -847) (isis -982) (smokescreen 423)
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">a = {{"alliance", -624}, {"archbishop", -915}, {"balm", 397}, {"bonnet", 452},
{"brute", 870}, {"centipede", -658}, {"cobol", 362}, {"covariate", 590},{"departure", 952},
{"deploy", 44}, {"diophantine", 645}, {"efferent", 54}, {"elysee", -326}, {"eradicate", 376},
Line 768 ⟶ 1,557:
 
result = Rest@Select[ Subsets[a, 7], (Total[#[[;; , 2]]] == 0) &];
Map[ (Print["A zero-sum subset of length ", Length[#], " : ", #[[;; , 1]]])& , result ]</langsyntaxhighlight>
 
<pre>A zero-sum subset of length 2 : {archbishop,gestapo}
Line 781 ⟶ 1,570:
The above code uses a brute-force approach, but Mathematica includes several solution schemes that can be used to solve this problem. We can cast it as an integer linear programming problem, and thus find the largest or smallest subset sum, or even sums with specific constraints, such as a sum using three negative values and nine positive values.
 
<langsyntaxhighlight Mathematicalang="mathematica">a = {{"alliance", -624}, {"archbishop", -915}, {"balm", 397}, {"bonnet", 452},
{"brute", 870}, {"centipede", -658}, {"cobol", 362}, {"covariate", 590},{"departure", 952},
{"deploy", 44}, {"diophantine", 645}, {"efferent", 54}, {"elysee", -326}, {"eradicate", 376},
Line 815 ⟶ 1,604:
 
Print["3 -ves, 9 +ves: ", Select[Transpose[{threeNineSoln*aValues, aNames}], #[[1]] != 0 &]];
</syntaxhighlight>
</lang>
 
<pre>Maximal solution: {{-624, alliance}, {-915, archbishop}, {397, balm},
Line 831 ⟶ 1,620:
{170, fiat}, {503, flatworm}, {-982, isis}, {475, markham},
{423, smokescreen}}.</pre>
 
=={{header|MiniZinc}}==
<syntaxhighlight lang="minizinc">
%Subset sum. Nigel Galloway: January 6th., 2021.
enum Items={alliance,archbishop,balm,bonnet,brute,centipede,cobol,covariate,departure,deploy,diophantine,efferent,elysee,eradicate,escritoire,exorcism,fiat,filmy,flatworm,gestapo,infra,isis,lindholm,markham,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein};
array[Items] of int: weight=[-624,-915,397,452,870,-658,362,590,952,44,645,54,-326,376,856,-983,170,-874,503,915,-847,-982,999,475,-880,756,183,-266,423,-745,813];
var set of Items: selected;
var int: wSelected=sum(n in selected)(weight[n]);
constraint wSelected=0;
</syntaxhighlight>
{{out}}
<pre>
selected = {alliance, archbishop, balm, bonnet, brute, centipede, cobol, covariate, departure, deploy, diophantine, efferent, elysee, eradicate, escritoire, exorcism, fiat, filmy, flatworm, mincemeat, plugging, speakeasy};
----------
Finished in 185msec
</pre>
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE SubsetSum;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
 
TYPE
String = ARRAY[0..63] OF CHAR;
Item = RECORD
word : String;
weight : INTEGER;
END;
 
PROCEDURE WriteItem(self : Item);
VAR buf : String;
BEGIN
FormatString("(%s, %i)", buf, self.word, self.weight);
WriteString(buf);
END WriteItem;
 
CONST N = 31;
VAR
items : ARRAY[0..N] OF Item;
indicies : ARRAY[0..N] OF INTEGER;
count : INTEGER;
PROCEDURE Init;
VAR i : INTEGER;
BEGIN
items[0] := Item{"alliance", -624};
items[1] := Item{"archbishop", -915};
items[2] := Item{"balm", 397};
items[3] := Item{"bonnet", 452};
items[4] := Item{"brute", 870};
items[5] := Item{"centipede", -658};
items[6] := Item{"cobol", 362};
items[7] := Item{"covariate", 590};
items[8] := Item{"departure", 952};
items[9] := Item{"deploy", 44};
items[10] := Item{"diophantine", 645};
items[11] := Item{"efferent", 54};
items[12] := Item{"elysee", -326};
items[13] := Item{"eradicate", 376};
items[14] := Item{"escritoire", 856};
items[15] := Item{"exorcism", -983};
items[16] := Item{"fiat", 170};
items[17] := Item{"filmy", -874};
items[18] := Item{"flatworm", 503};
items[19] := Item{"gestapo", 915};
items[20] := Item{"infra", -847};
items[21] := Item{"isis", -982};
items[22] := Item{"lindholm", 999};
items[23] := Item{"markham", 475};
items[24] := Item{"mincemeat", -880};
items[25] := Item{"moresby", 756};
items[26] := Item{"mycenae", 183};
items[27] := Item{"plugging", -266};
items[28] := Item{"smokescreen", 423};
items[29] := Item{"speakeasy", -745};
items[30] := Item{"vein", 813};
 
count := 0;
END Init;
 
CONST LIMIT = 5;
PROCEDURE ZeroSum(i,w : INTEGER);
VAR j,k : INTEGER;
BEGIN
IF (i#0) AND (w=0) THEN
FOR j:=0 TO i-1 DO
WriteItem(items[indicies[j]]);
WriteString(" ");
END;
WriteLn;
WriteString("---------------");
WriteLn;
IF count<LIMIT THEN
INC(count)
ELSE
RETURN;
END;
END;
IF i#0 THEN
k := indicies[i-1]+1;
ELSE
k := 0;
END;
FOR j:=k TO N-1 DO
indicies[i] := j;
ZeroSum(i+1,w+items[j].weight);
IF count=LIMIT THEN RETURN; END;
END;
END ZeroSum;
 
VAR buf : ARRAY[0..63] OF CHAR;
VAR d : INTEGER;
BEGIN
Init;
d := LIMIT;
FormatString("The weights of the following %i subsets add up to zero:\n\n", buf, d);
WriteString(buf);
ZeroSum(0,0);
 
ReadChar;
END SubsetSum.</syntaxhighlight>
 
=={{header|Nim}}==
{{libheader|itertools}}
We need the third party module "itertools" to compute the combinations.
<syntaxhighlight lang="nim">import sequtils, strformat, strutils
import itertools
 
const Words = {"alliance": -624,
"archbishop": -915,
"balm": 397,
"bonnet": 452,
"brute": 870,
"centipede": -658,
"cobol": 362,
"covariate": 590,
"departure": 952,
"deploy": 44,
"diophantine": 645,
"efferent": 54,
"elysee": -326,
"eradicate": 376,
"escritoire": 856,
"exorcism": -983,
"fiat": 170,
"filmy": -874,
"flatworm": 503,
"gestapo": 915,
"infra": -847,
"isis": -982,
"lindholm": 999,
"markham": 475,
"mincemeat": -880,
"moresby": 756,
"mycenae": 183,
"plugging": -266,
"smokescreen": 423,
"speakeasy": -745,
"vein": 813}
 
var words: seq[string]
var values: seq[int]
for (word, value) in Words:
words.add word
values.add value
 
for lg in 1..words.len:
block checkCombs:
for comb in combinations(words.len, lg):
var sum = 0
for idx in comb: sum += values[idx]
if sum == 0:
echo &"For length {lg}, found for example: ", comb.mapIt(words[it]).join(" ")
break checkCombs
echo &"For length {lg}, no set found."</syntaxhighlight>
 
{{out}}
<pre>For length 1, no set found.
For length 2, found for example: archbishop gestapo
For length 3, found for example: centipede markham mycenae
For length 4, found for example: alliance balm deploy mycenae
For length 5, found for example: alliance brute covariate deploy mincemeat
For length 6, found for example: alliance archbishop balm deploy gestapo mycenae
For length 7, found for example: alliance archbishop bonnet cobol departure exorcism moresby
For length 8, found for example: alliance archbishop balm bonnet fiat flatworm isis lindholm
For length 9, found for example: alliance archbishop balm bonnet brute covariate eradicate mincemeat plugging
For length 10, found for example: alliance archbishop balm bonnet brute centipede cobol departure deploy mincemeat
For length 11, found for example: alliance archbishop balm bonnet brute centipede cobol departure infra moresby speakeasy
For length 12, found for example: alliance archbishop balm bonnet brute centipede cobol covariate diophantine efferent elysee infra
For length 13, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure efferent eradicate filmy isis
For length 14, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee filmy markham speakeasy
For length 15, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee exorcism flatworm infra mycenae
For length 16, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee exorcism filmy gestapo infra
For length 17, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine exorcism isis mincemeat mycenae plugging vein
For length 18, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy isis mycenae vein
For length 19, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism fiat infra isis smokescreen
For length 20, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism gestapo infra isis smokescreen speakeasy
For length 21, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism flatworm infra lindholm mincemeat plugging speakeasy
For length 22, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism fiat filmy flatworm mincemeat plugging speakeasy
For length 23, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism infra isis mincemeat moresby mycenae smokescreen speakeasy
For length 24, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy gestapo infra markham mincemeat moresby mycenae plugging smokescreen speakeasy
For length 25, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine eradicate exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging speakeasy
For length 26, found for example: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee eradicate escritoire exorcism fiat filmy gestapo infra isis markham mincemeat mycenae plugging speakeasy vein
For length 27, found for example: alliance archbishop balm bonnet brute centipede covariate departure deploy efferent elysee eradicate escritoire exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging smokescreen speakeasy
For length 28, no set found.
For length 29, no set found.
For length 30, no set found.
For length 31, no set found.</pre>
 
=={{header|OCaml}}==
Line 836 ⟶ 1,831:
Just search randomly until a result is found:
 
<langsyntaxhighlight lang="ocaml">let d =
[ "alliance", -624; "archbishop", -915; "balm", 397; "bonnet", 452;
"brute", 870; "centipede", -658; "cobol", 362; "covariate", 590;
Line 870 ⟶ 1,865:
in
let res = aux [] d in
List.iter (fun (n,w) -> Printf.printf " %4d\t%s\n" w n) res</langsyntaxhighlight>
 
=={{header|Perl}}==
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use ntheory qw/:all/;
my $print_all_combinations = 0;
 
my %pairs = (
Line 886 ⟶ 1,880:
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
print "Length $n: @names[@_]\n" unless vecsum(@weights[@_]);
lastfor, print "Length $n: @names[@_]\n" if vecsum(@weights[@_]) == 0;
} @names, $n;
}</syntaxhighlight>
}
 
} 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:
{{out}}
<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:
<langsyntaxhighlight lang="perl">use List::Util qw/sum/;
use Algorithm::Combinatorics qw/combinations/;
foreach my $n (1 .. @names) {
Line 934 ⟶ 1,914:
last;
}
}</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
Simple Brute force
<lang perl6>my @pairs =
<!--<syntaxhighlight lang="phix">(phixonline)-->
alliance => -624, archbishop => -915, balm => 397, bonnet => 452,
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
brute => 870, centipede => -658, cobol => 362, covariate => 590,
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">words</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weights</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">"alliance"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">624</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"archbishop"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">915</span><span style="color: #0000FF;">},</span>
departure => 952, deploy => 44, diophantine => 645, efferent => 54,
<span style="color: #0000FF;">{</span><span style="color: #008000;">"balm"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">397</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"bonnet"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">452</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"brute"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">870</span><span style="color: #0000FF;">},</span>
elysee => -326, eradicate => 376, escritoire => 856, exorcism => -983,
<span style="color: #0000FF;">{</span><span style="color: #008000;">"centipede"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">658</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"cobol"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">362</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"covariate"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">590</span><span style="color: #0000FF;">},</span>
fiat => 170, filmy => -874, flatworm => 503, gestapo => 915,
<span style="color: #0000FF;">{</span><span style="color: #008000;">"departure"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">952</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"deploy"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">44</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"diophantine"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">645</span><span style="color: #0000FF;">},</span>
infra => -847, isis => -982, lindholm => 999, markham => 475,
<span style="color: #0000FF;">{</span><span style="color: #008000;">"efferent"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">54</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"elysee"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">326</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"eradicate"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">376</span><span style="color: #0000FF;">},</span>
mincemeat => -880, moresby => 756, mycenae => 183, plugging => -266,
<span style="color: #0000FF;">{</span><span style="color: #008000;">"escritoire"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">856</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"exorcism"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">983</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"fiat"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">170</span><span style="color: #0000FF;">},</span>
smokescreen => 423, speakeasy => -745, vein => 813;
<span style="color: #0000FF;">{</span><span style="color: #008000;">"filmy"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">874</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"flatworm"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">503</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"gestapo"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">915</span><span style="color: #0000FF;">},</span>
my @weights = @pairs».value;
<span style="color: #0000FF;">{</span><span style="color: #008000;">"infra"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">847</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"isis"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">982</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"lindholm"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">999</span><span style="color: #0000FF;">},</span>
my %name = @pairs.hash.invert;
<span style="color: #0000FF;">{</span><span style="color: #008000;">"markham"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">475</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"mincemeat"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">880</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"moresby"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">756</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"mycenae"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">183</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"plugging"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">266</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"smokescreen"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">423</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"speakeasy"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">745</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"vein"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">813</span><span style="color: #0000FF;">}})</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">needed</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">done</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">={})</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">needed</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- got a full set</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">weights</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cw</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">scw</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cw</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"items"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scw</span><span style="color: #0000FF;">,</span><span style="color: #008000;">","</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">done</span><span style="color: #0000FF;">+</span><span style="color: #000000;">needed</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- get all combinations with and without the next item:</span>
<span style="color: #000000;">done</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">needed</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">),</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">done</span><span style="color: #0000FF;">]))</span>
<span style="color: #008080;">or</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">needed</span> <span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">weights</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d: No zero-sum subsets of that length\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
1: No zero-sum subsets of that length
2: archbishop,gestapo
3: centipede,markham,mycenae
4: alliance,balm,deploy,mycenae
5: alliance,brute,covariate,deploy,mincemeat
6: alliance,archbishop,balm,deploy,gestapo,mycenae
7: alliance,archbishop,bonnet,cobol,departure,exorcism,moresby
8: alliance,archbishop,balm,bonnet,fiat,flatworm,isis,lindholm
9: alliance,archbishop,balm,bonnet,brute,covariate,eradicate,mincemeat,plugging
10: alliance,archbishop,balm,bonnet,brute,centipede,cobol,departure,deploy,mincemeat
11: alliance,archbishop,balm,bonnet,...,departure,infra,moresby,speakeasy, (11 items)
12: alliance,archbishop,balm,bonnet,...,diophantine,efferent,elysee,infra, (12 items)
13: alliance,archbishop,balm,bonnet,...,efferent,eradicate,filmy,isis, (13 items)
14: alliance,archbishop,balm,bonnet,...,elysee,filmy,markham,speakeasy, (14 items)
15: alliance,archbishop,balm,bonnet,...,exorcism,flatworm,infra,mycenae, (15 items)
16: alliance,archbishop,balm,bonnet,...,exorcism,filmy,gestapo,infra, (16 items)
17: alliance,archbishop,balm,bonnet,...,mincemeat,mycenae,plugging,vein, (17 items)
18: alliance,archbishop,balm,bonnet,...,filmy,isis,mycenae,vein, (18 items)
19: alliance,archbishop,balm,bonnet,...,fiat,infra,isis,smokescreen, (19 items)
20: alliance,archbishop,balm,bonnet,...,infra,isis,smokescreen,speakeasy, (20 items)
21: alliance,archbishop,balm,bonnet,...,lindholm,mincemeat,plugging,speakeasy, (21 items)
22: alliance,archbishop,balm,bonnet,...,flatworm,mincemeat,plugging,speakeasy, (22 items)
23: alliance,archbishop,balm,bonnet,...,moresby,mycenae,smokescreen,speakeasy, (23 items)
24: alliance,archbishop,balm,bonnet,...,mycenae,plugging,smokescreen,speakeasy, (24 items)
25: alliance,archbishop,balm,bonnet,...,moresby,mycenae,plugging,speakeasy, (25 items)
26: alliance,archbishop,balm,bonnet,...,mycenae,plugging,speakeasy,vein, (26 items)
27: alliance,archbishop,balm,bonnet,...,mycenae,plugging,smokescreen,speakeasy, (27 items)
28: No zero-sum subsets of that length
29: No zero-sum subsets of that length
30: No zero-sum subsets of that length
31: No zero-sum subsets of that length
</pre>
===Alternative===
Using the harder set of weights from Go, and the version 1 approach of Python, modified to omit words and
using a dictionary so that fractional weights can be accomodated.<br>
Note that fractional weights may trigger all the usual IEEE-754 issues such as 0.3+0.6-0.9 != 0, so you may need to use sprintf()'d keys with matching to_number()'s.<br>
This is significantly faster (near instant, in fact) than an "all possible combinations" approach.
Shows the first zero-sum subset found, only.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">weights</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{-</span><span style="color: #000000;">61</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">373</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">311</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">249</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">311</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">92</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">185</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">433</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">-</span><span style="color: #000000;">402</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">247</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">156</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">125</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">249</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">464</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">278</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">218</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">-</span><span style="color: #000000;">123</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">216</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">373</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">185</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">402</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">156</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">402</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">61</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">902</span> <span style="color: #0000FF;">}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">sums</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">weights</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">-- make a separate modifiable copy of sums, otherwise
-- it c/would mark sums[weights[w]*{2,3,etc}] as valid,
-- ie there cannot be any w in the getd_by_index(node).</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">weights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">w</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">},</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sk</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_all_keys</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sk</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sk</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">!=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sk</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sk</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">getd_by_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">))&</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">sums</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">!=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">weights</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">getd_by_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Total %d for %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">),</span><span style="color: #000000;">t</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Total 0 for {-61,32,373,311,249,311,32,-92,-185,-433,-402,-247,156,125,249,32,-464,-278,218,32,-123,-216,373,-185,-402,156,-402,-61,902}
</pre>
 
=={{header|Picat}}==
Using constraint modelling.
 
<syntaxhighlight lang="picat">import cp.
 
%
% Get any solution.
%
go =>
things(Things),
subset_sum(Things, X, Z),
println(z=Z),
println(x=X),
println([Things[I] : I in 1..Things.length, X[I] == 1]),
nl.
 
%
% Solve subset problem for any length (wrapper).
%
subset_sum(Things, X, Z) =>
subset_sum(Things,_,X,Z).
 
%
% Solve for a specific length (if Len2 is nonvar).
%
subset_sum(Things, Len2, X, Z) =>
Weights = [ T[2] : T in Things],
Len = Things.length,
X = new_list(Len),
X :: 0..1,
 
Z #= sum(X),
if nonvar(Len2) then
Z #= Len2
end,
Z #> 0, % require at least one thing
sum([X[I] * Weights[I] : I in 1..Len]) #= 0,
solve($[ff], X).
 
things(Things) =>
Things = [
[alliance, -624],
[archbishop, -915],
[balm, 397],
[bonnet, 452],
[brute, 870],
[centipede, -658],
[cobol, 362],
[covariate, 590],
[departure, 952],
[deploy, 44],
[diophantine, 645],
[efferent, 54],
[elysee, -326],
[eradicate, 376],
[escritoire, 856],
[exorcism, -983],
[fiat, 170],
[filmy, -874],
[flatworm, 503],
[gestapo, 915],
[infra, -847],
[isis, -982],
[lindholm, 999],
[markham, 475],
[mincemeat, -880],
[moresby, 756],
[mycenae, 183],
[plugging, -266],
[smokescreen, 423],
[speakeasy, -745],
[vein, 813 ]
].</syntaxhighlight>
 
for 1..^@weights -> $n {
given @weights.combinations($n).first({ 0 == [+] @^comb }) {
when .so { say "Length $n: ", .map: {%name{$_}} }
default { say "Length $n: (none)" }
}
}</lang>
{{out}}
<pre>Lengthz 1:= (none)8
x = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,1,1,1,1]
Length 2: archbishop gestapo
[[flatworm,503],[infra,-847],[lindholm,999],[mincemeat,-880],[plugging,-266],[smokescreen,423],[speakeasy,-745],[vein,813]]
Length 3: centipede markham mycenae
</pre>
Length 4: alliance balm deploy mycenae
 
Length 5: alliance brute covariate deploy mincemeat
Some other experiments.
Length 6: alliance archbishop balm deploy gestapo mycenae
 
Length 7: alliance archbishop bonnet cobol departure exorcism moresby
Get a solution - if possible - for a specific number of selected things.
Length 8: alliance archbishop balm bonnet fiat flatworm isis lindholm
<syntaxhighlight lang="picat">go2 =>
Length 9: alliance archbishop balm bonnet brute covariate eradicate mincemeat plugging
things(Things),
Length 10: alliance archbishop balm bonnet brute centipede cobol departure deploy mincemeat
foreach(Len in 1..Things.length)
Length 11: alliance archbishop balm bonnet brute centipede cobol departure infra moresby speakeasy
println(len=Len),
Length 12: alliance archbishop balm bonnet brute centipede cobol covariate diophantine efferent elysee infra
(subset_sum(Things, Len, X, _Z) ->
Length 13: alliance archbishop balm bonnet brute centipede cobol covariate departure efferent eradicate filmy isis
println([Things[I,1] : I in 1..Things.length, X[I] == 1])
Length 14: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee filmy markham speakeasy
;
Length 15: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee exorcism flatworm infra mycenae
true
Length 16: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee exorcism filmy gestapo infra
),
Length 17: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine exorcism isis mincemeat mycenae plugging vein
nl
Length 18: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy isis mycenae vein
end,
Length 19: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism fiat infra isis smokescreen
nl.</syntaxhighlight>
Length 20: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism gestapo infra isis smokescreen speakeasy
 
Length 21: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism flatworm infra lindholm mincemeat plugging speakeasy
{{out}}
Length 22: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism fiat filmy flatworm mincemeat plugging speakeasy
<pre>len = 1
Length 23: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism infra isis mincemeat moresby mycenae smokescreen speakeasy
 
Length 24: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy gestapo infra markham mincemeat moresby mycenae plugging smokescreen speakeasy
len = 2
Length 25: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine eradicate exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging speakeasy
[archbishop,gestapo]
Length 26: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee eradicate escritoire exorcism fiat filmy gestapo infra isis markham mincemeat mycenae plugging speakeasy vein
 
Length 27: alliance archbishop balm bonnet brute centipede covariate departure deploy efferent elysee eradicate escritoire exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging smokescreen speakeasy</pre>
len = 3
[exorcism,fiat,vein]
 
len = 4
[exorcism,gestapo,speakeasy,vein]
 
len = 5
[fiat,infra,lindholm,smokescreen,speakeasy]
 
len = 6
[exorcism,flatworm,gestapo,isis,plugging,vein]
 
len = 7
[fiat,flatworm,infra,isis,lindholm,plugging,smokescreen]
 
len = 8
[flatworm,infra,lindholm,mincemeat,plugging,smokescreen,speakeasy,vein]
 
len = 9
[exorcism,filmy,flatworm,infra,markham,moresby,plugging,smokescreen,vein]
 
len = 10
[fiat,filmy,flatworm,gestapo,isis,markham,mincemeat,moresby,mycenae,plugging]
 
len = 11
[exorcism,fiat,flatworm,gestapo,infra,isis,lindholm,plugging,smokescreen,speakeasy,vein]
 
len = 12
[eradicate,fiat,infra,isis,lindholm,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 13
[escritoire,fiat,filmy,gestapo,infra,isis,lindholm,markham,mincemeat,moresby,plugging,smokescreen,speakeasy]
 
len = 14
[escritoire,exorcism,fiat,flatworm,infra,isis,lindholm,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 15
[efferent,elysee,escritoire,exorcism,fiat,filmy,flatworm,infra,isis,lindholm,moresby,mycenae,smokescreen,speakeasy,vein]
 
len = 16
[diophantine,elysee,eradicate,fiat,filmy,flatworm,infra,isis,lindholm,markham,mincemeat,moresby,mycenae,plugging,speakeasy,vein]
 
len = 17
[deploy,diophantine,elysee,eradicate,escritoire,exorcism,fiat,filmy,flatworm,infra,isis,lindholm,markham,mincemeat,moresby,speakeasy,vein]
 
len = 18
[deploy,diophantine,efferent,escritoire,exorcism,fiat,filmy,gestapo,infra,isis,lindholm,markham,mincemeat,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 19
[departure,deploy,diophantine,efferent,elysee,eradicate,exorcism,fiat,filmy,flatworm,infra,isis,lindholm,markham,mincemeat,mycenae,smokescreen,speakeasy,vein]
 
len = 20
[covariate,diophantine,efferent,elysee,eradicate,exorcism,fiat,filmy,flatworm,gestapo,infra,isis,markham,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 21
[cobol,deploy,diophantine,efferent,elysee,eradicate,escritoire,exorcism,fiat,filmy,flatworm,infra,isis,lindholm,markham,mincemeat,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 22
[brute,centipede,cobol,covariate,deploy,diophantine,efferent,elysee,escritoire,exorcism,fiat,filmy,flatworm,infra,isis,markham,mincemeat,moresby,plugging,smokescreen,speakeasy,vein]
 
len = 23
[bonnet,centipede,cobol,departure,deploy,diophantine,efferent,elysee,eradicate,escritoire,exorcism,fiat,filmy,infra,isis,markham,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 24
[archbishop,brute,centipede,cobol,covariate,deploy,diophantine,efferent,elysee,escritoire,exorcism,fiat,filmy,flatworm,gestapo,infra,isis,markham,mincemeat,moresby,plugging,smokescreen,speakeasy,vein]
 
len = 25
[archbishop,bonnet,centipede,cobol,departure,deploy,diophantine,efferent,elysee,eradicate,escritoire,exorcism,fiat,filmy,gestapo,infra,isis,markham,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 26
[alliance,archbishop,bonnet,brute,centipede,covariate,departure,deploy,efferent,elysee,eradicate,exorcism,fiat,filmy,flatworm,gestapo,infra,isis,lindholm,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 27
[alliance,archbishop,balm,brute,centipede,cobol,covariate,deploy,diophantine,efferent,elysee,eradicate,exorcism,fiat,filmy,flatworm,gestapo,infra,isis,lindholm,mincemeat,moresby,mycenae,plugging,smokescreen,speakeasy,vein]
 
len = 28
 
len = 29
 
len = 30
 
len = 31</pre>
 
There are in total 349167 solutions of any number of items (the empty set is not a solution in our book).
<syntaxhighlight lang="picat">go3 =>
things(Things),
Count = count_all(subset_sum(Things, _X, _Z)),
println(count=Count),
nl.
</syntaxhighlight>
 
 
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de *Words
(alliance . -624) (archbishop . -915) (balm . 397) (bonnet . 452)
(brute . 870) (centipede . -658) (cobol . 362) (covariate . 590)
Line 993 ⟶ 2,241:
(infra . -847) (isis . -982) (lindholm . 999) (markham . 475)
(mincemeat . -880) (moresby . 756) (mycenae . 183) (plugging . -266)
(smokescreen . 423) (speakeasy . -745) (vein . 813) )</langsyntaxhighlight>
Minimal brute force solution:
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/simul.l") # For 'subsets'
 
(pick
Line 1,001 ⟶ 2,249:
(find '((L) (=0 (sum cdr L)))
(subsets N *Words) ) )
(range 1 (length *Words)) )</langsyntaxhighlight>
{{Out}}
<pre>-> ((archbishop . -915) (gestapo . 915))</pre>
Line 1,007 ⟶ 2,255:
=={{header|Python}}==
===Version 1===
<langsyntaxhighlight lang="python">words = { # some values are different from example
"alliance": -624, "archbishop": -925, "balm": 397,
"bonnet": 452, "brute": 870, "centipede": -658,
Line 1,041 ⟶ 2,289:
for x in s[-neg]:
print(x, words[x])
break</langsyntaxhighlight>
{{out}}<pre>
('mycenae', 183)
Line 1,052 ⟶ 2,300:
</pre>
===Brute force===
<langsyntaxhighlight lang="python">>>> from itertools import combinations
>>>
>>> word2weight = {"alliance": -624, "archbishop": -915, "balm": 397, "bonnet": 452,
Line 1,072 ⟶ 2,320:
>>> answer
[('archbishop', -915), ('gestapo', 915)]</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,110 ⟶ 2,358:
(for ([i (sub1 len)]) (loop l len (add1 i) '() 0)))
(zero-subsets words)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,120 ⟶ 2,368:
(alliance archbishop balm bonnet brute centipede covariate departure deploy efferent elysee eradicate escritoire exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging smokescreen speakeasy)
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>my @pairs =
alliance => -624, archbishop => -915, balm => 397, bonnet => 452,
brute => 870, centipede => -658, cobol => 362, covariate => 590,
departure => 952, deploy => 44, diophantine => 645, efferent => 54,
elysee => -326, eradicate => 376, escritoire => 856, exorcism => -983,
fiat => 170, filmy => -874, flatworm => 503, gestapo => 915,
infra => -847, isis => -982, lindholm => 999, markham => 475,
mincemeat => -880, moresby => 756, mycenae => 183, plugging => -266,
smokescreen => 423, speakeasy => -745, vein => 813;
my @weights = @pairs».value;
my %name = @pairs.hash.invert;
 
.say for (1..27).hyper(:3batch).map: -> $n {
given @weights.combinations($n).first({ 0 == [+] @^comb }) {
when .so { "Length $n: ({.map: {%name{$_}}})" }
default { "Length $n: (none)" }
}
}</syntaxhighlight>
{{out}}
<pre>Length 1: (none)
Length 2: (archbishop gestapo)
Length 3: (centipede markham mycenae)
Length 4: (alliance balm deploy mycenae)
Length 5: (alliance brute covariate deploy mincemeat)
Length 6: (alliance archbishop balm deploy gestapo mycenae)
Length 7: (alliance archbishop bonnet cobol departure exorcism moresby)
Length 8: (alliance archbishop balm bonnet fiat flatworm isis lindholm)
Length 9: (alliance archbishop balm bonnet brute covariate eradicate mincemeat plugging)
Length 10: (alliance archbishop balm bonnet brute centipede cobol departure deploy mincemeat)
Length 11: (alliance archbishop balm bonnet brute centipede cobol departure infra moresby speakeasy)
Length 12: (alliance archbishop balm bonnet brute centipede cobol covariate diophantine efferent elysee infra)
Length 13: (alliance archbishop balm bonnet brute centipede cobol covariate departure efferent eradicate filmy isis)
Length 14: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee filmy markham speakeasy)
Length 15: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee exorcism flatworm infra mycenae)
Length 16: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee exorcism filmy gestapo infra)
Length 17: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine exorcism isis mincemeat mycenae plugging vein)
Length 18: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy isis mycenae vein)
Length 19: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism fiat infra isis smokescreen)
Length 20: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism gestapo infra isis smokescreen speakeasy)
Length 21: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism flatworm infra lindholm mincemeat plugging speakeasy)
Length 22: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism fiat filmy flatworm mincemeat plugging speakeasy)
Length 23: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism infra isis mincemeat moresby mycenae smokescreen speakeasy)
Length 24: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy gestapo infra markham mincemeat moresby mycenae plugging smokescreen speakeasy)
Length 25: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine eradicate exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging speakeasy)
Length 26: (alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee eradicate escritoire exorcism fiat filmy gestapo infra isis markham mincemeat mycenae plugging speakeasy vein)
Length 27: (alliance archbishop balm bonnet brute centipede covariate departure deploy efferent elysee eradicate escritoire exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging smokescreen speakeasy)</pre>
 
=={{header|REXX}}==
This REXX solution isn't limited to integers for the weights. &nbsp; &nbsp; This isn't a brute force solution.
 
<br><br>While optimizing the original program, it was found that sorting the names by weight could yield a vastly
While optimizing the original program, it was found that sorting the names by weight could yield a vastly
<br>improved algorithm (by an order of magnitude), so the extra code to sort the list was included, as well as
<br>another sort to show the solutions in alphabetical order. &nbsp; Support was also added to allow specification of
<br>which "chunk" to search for solutions &nbsp; (that is, out of the 31 names, take a "chunk" at a time).
<br><br>Showing of the timing (elapsed time) was also added, as well as "que pasa" informational messages. &nbsp; The
<br>sum &nbsp; (which is zero for this task) can be any number, and can be specifiable on the command line.
<lang rexx>/*REXX pgm finds some non-null subsets of a weighted list whose sum=zero*/
parse arg target stopAt chunkette . /*get args from the command line*/
if target==''|target==',' then target=0 /*TARGET given? No, use default*/
if stopAt==''|stopAt==',' then stopAt=1 /*Max solutions? " " " */
 
zzz = 'alliance -624 archbishop -915 balm 397' ,
'bonnet 452 brute 870 centipede -658' ,
'cobol 362 covariate 590 departure 952' ,
'deploy 44 diophantine 645 efferent 54' ,
'elysee -326 eradicate 376 escritoire 856' ,
'exorcism -983 fiat 170 filmy -874' ,
'flatworm 503 gestapo 915 infra -847' ,
'isis -982 lindholm 999 markham 475' ,
'mincemeat -880 moresby 756 mycenae 183' ,
'plugging -266 smokescreen 423 speakeasy -745' ,
'vein 813'
 
@.=0; y=0; do N=1 until zzz='' /*build an array from a list. */
parse var zzz @.N #.N zzz /*pick from list like a nose. */
end /*N*/
call esort N /*sort the names with weights.*/
call tellZ 'sorted' /*show the sorted list. */
chunkStart=1 /*the default place to start. */
chunkEnd =N /* " " " " end. */
if chunkette\=='' then do /*solutions just for chunkette*/
chunkStart=chunkette
chunkEnd =chunkette
end
call time 'Reset' /*reset the REXX elapsed time.*/
??=0 /*number of solutions so far. */
 
Added was "que pasa" informational messages. &nbsp; The sum &nbsp; (which is zero for this task) &nbsp; can be any number,
do chunk=chunkStart to chunkEnd /*traipse through the items. */
<br>and can be specifiable on the command line.
call tello center(' doing chunk:' chunk" ",79,'─')
<syntaxhighlight lang="rexx">/*REXX program finds some non─null subsets of a weighted list whose sum eqals zero.*/
call combN N, chunk /*N items, a CHUNK at a time. */
parse arg _=??;target stopAt chunkette . if _==0 then _='No' /*Englishiseoption foroptional aarguments zerofrom count.the CL*/
if target=='' | target=="," then target= 0 /*Not specified? Then use the default.*/
call tello _ 'solution's(??) "found so far and took",
if stopAt=='' | stopAt=="," then stopAt= 1 /* " " format(time('Elapsed'),,2) 'seconds" so far.',. " " " */
y= 0
end /*chunk*/
zz= 'archbishop -915 covariate 590 mycenae 183 brute 870 balm 397 fiat 170' ,
'smokescreen 423 eradicate 376 efferent 54 bonnet 452 vein 813 ' ,
'diophantine 645 departure 952 lindholm 999 moresby 756 isis -982 ' ,
'mincemeat -880 alliance -624 flatworm 503 elysee -326 cobol 362 ' ,
'centipede -658 exorcism -983 gestapo 915 filmy -874 deploy 44 ' ,
'speakeasy -745 plugging -266 markham 475 infra -847 escritoire 856 '
@.= 0
do N=1 until zz='' /*construct an array from the ZZ list. */
parse var zz @.N #.N zz /*pick from the list like a nose. */
end /*N*/
call eSort N /*sort the names with weights. */
call tellZ 'sorted' /*display the sorted list. */
chunkStart= 1 /*the default place to start. */
chunkEnd = N /* " " " " end. */
if chunkette\=='' then do /*solutions just for a chunkette. */
chunkStart= chunkette
chunkEnd = chunkette
end
call time 'Reset' /*reset the REXX elapsed time. */
??= 0 /*the number of solutions (so far). */
do chunk=chunkStart to chunkEnd /*traipse through the items. */
call tello center(' doing chunk:' chunk" ", 79, '─')
call combN N, chunk /*N items, a CHUNK at a time. */
_= ?? /*set a temporary variable to ??. */
if _==0 then _= 'No' /*Englishise _ for a zero count. */
call tello _ 'solution's(??) "found so far."
end /*chunk*/
 
if ??==0 then ??= 'no' /*Englishise the solutions number. */
call tello 'Found' ?? "subset"s(??) 'whose summed weight's(??) "=" target
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────COMBN subroutine────────────────────*/
combN: procedure expose @. #. ?? stopAt target; parse arg x,y; !.= @.0
base= x + 1; bbase= base - y; ym=y-1 /*!.n are the combination digits. */
do n=1 for y; !.n=n /*construct the first combination. */
 
do n=1 for y; !.n=n; end /*build the first combination. n*/
ym= y - 1
 
do j=1; _= !.1; s= #._ /*getobtain the first digit and the sum. */
if s>target then leave /*Is 1st dig>target? Then we're done.*/
do k=2 for ym; _= !.k; s= s + #._ /*Σ the weights; is sum > target ? */
 
do k=2 for ym if s>target then do; _=! if .combUp(k-1) then return; s=s+#._ /*Σ theiterate weightsj; is sum > target?*/end
end /*k*/
if s>target then do; if .combUp(k-1) then return; iterate j; end
if s==target then call telly /*have we found a pot of gold? */
end /*k*/
!.y= !.y + 1; if !.y==base then if .combUp(ym) then leave /*bump digit.*/
 
if s==target then call telly end /*havej*/; return /*done with wethis foundcombination aset. pot of gold? */
/*──────────────────────────────────────────────────────────────────────────────────────*/
!.y=!.y+1; if !.y==base then if .combUp(ym) then leave /*bump dig*/
.combUp: procedure expose !. y bbase; parse arg d; if d==0 then return 1
end /*j*/
return p= !.d; do u=d to y; !.u= p + 1 /*add one to digit we're pointing /*doneat. with this combination set.*/
if !.u >= bbase+u then return .combUp(u-1)
 
p= !.u /*P will be used for the next digt. */
.combUp: procedure expose !. y bbase; parse arg d; if d==0 then return 1
p=!.d; do u=d to y; !.u=p+1 end /*addu*/; 1 to dig we're pointing at return 0 /*go back and sum this combination. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
if !.u>=bbase+u then return .combUp(u-1)
eSort: procedure expose #. @. p=!$.u; parse arg N,$; /*P will be used for the nexth= dig*/N
do while h>1; end /*u*/ h= h % 2
return 0 do i=1 for N-h; j= i; k= h + /*go back & sum this combination.*/i
if $==. then do while $.k<$.j; parse value $.j $.k with $.k $.j
/*──────────────────────────────────ESORT subroutine────────────────────*/
esort: procedure expose #. @. $.; parse arg N,$ if h>=j then leave; j= j - h; k=N k - h
do while h>1; h=h%2 end /*while $.k<$.j*/
do i=1 for N-h; else do while #.k<#.j=i; parse value @.j @.k #.j #.k with @.k=h+i @.j #.k #.j
if $h>==.j then doleave; while $.k<$.j= j - h; parse value $.j $.k with $. k= $.jk - h
if h>=j then leave;end /*while #.k<#.j=j-h; k=k-h*/
end /*while $.k<$.ji*/
end else do /*while #.k<#.jh>1*/; parse value @.j @.k #.j #.k with @.k @.j #.k #.j return
/*──────────────────────────────────────────────────────────────────────────────────────*/
if h>=j then leave; j=j-h; k=k-h
s: if arg(1)==1 then return arg(3); return word(arg(2) 's', end 1) /*whilesimple #.k<#.jpluralizer*/
tello: parse arg _,e; if e==. then say; say _; call lineout 'SUBSET.'y, _; return
end /*i*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
end /*while h>1*/
telly: ??= ?? + 1; nameL= /*start with a "null" name list. */
return
do gi=1 for y; ggg= !.gi /*build duplicate array (to be sorted).*/
/*──────────────────────────────────one─liner subroutines─────────────────────*/
$.gi= @.ggg /*transform from index ──► a name. */
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*plural*/
end /*gi*/ /*build duplicate array (to be sorted).*/
tello: parse arg _,e; if e==. then say; say _; call lineout 'SUBSET.'y,_; return
call eSort y, . /*sort the names alphabetically. */
/*──────────────────────────────────TELLY subroutine────────────────────*/
telly: ??=??+1; do gs=1 for y; nameL= nameL $.gs /*start withbuild a "null"list nameof list.names whose sum = 0 */
end /*gs*/ do gi=1 for y; ggg=!.gi /*buildthe duplist arrayof (tonames could be sorted). */
call tello '['y" name"s(y)']' space(nameL)
$.gi=@.ggg /*transform from index──► a name.*/
if ??<stopAt | stopAt==0 then return end /*gi*/see if we reached a (or the) /*build dup array (to be sorted)limit.*/
call tello 'Stopped after finding ' ?? " subset"s(??)'.', .
call eSort y,. /*sort the names alphabetically. */
exit /*a short─timer, we should quit then. */
do gs=1 for y; nameL=nameL $.gs /*build list of names whose sum=0*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
end /*gs*/ /*list of names could be sorted */
tellz: do j=1 for N /*show a list of names and weights. */
call tello '['y" name"s(y)']' space(nameL)
call tello right('['j']', 30) right(@.j, 11) right(#.j, 5)
if ??<stopAt | stopAt==0 then return /*see if we reached a (the) limit*/
end /*j*/
call tello 'Stopped after finding ' ?? " subset"s(??)'.',.
call tello
exit /*a short─timer, we have to quit.*/
call tello 'There are ' N " entries in the (above)" arg(1) 'table.'
/*──────────────────────────────────TELLZ subroutine────────────────────*/
tellz: do j=1 call fortello; N /*show list of names and weights.*return</syntaxhighlight>
call tello right('['j']',30) right(@.j,11) right(#.j,5)
end /*j*/
call tello
call tello 'There are ' N " entries in the (above)" arg(1) 'table.'
call tello; return</lang>
Output note: &nbsp; this program also writes the displayed output to file(s): &nbsp; SUBSET.nnn
<br> ──────── where &nbsp; nnn &nbsp; is the ''chunk'' number.
<br>
 
{{Out}}out|output|text= &nbsp;when using the input of: &nbsp; &nbsp; <tt> 0 &nbsp; 12 </tt><br>}}
 
(The above arguments set the target sum to zero and limits finding of a dozen solutions.)
(The above arguments set the target sum to zero, and limits the finding of a dozen solutions.)
<pre style="height:90ex">
<pre>
[1] exorcism -983
[2] isis -982
Line 1,269 ⟶ 2,557:
[31] lindholm 999
 
There are 31 entries in the (above) sorted table.
 
─────────────────────────────── doing chunk: 1 ────────────────────────────────
No solutions found so far.
 
No solutions found so far and took 0.00 seconds so far.
─────────────────────────────── doing chunk: 2 ────────────────────────────────
[2 names] archbishop gestapo
1 solution found so far.
 
1 solution found so far and took 0.01 seconds so far.
─────────────────────────────── doing chunk: 3 ────────────────────────────────
[3 names] exorcism fiat vein
[3 names] centipede markham mycenae
3 solutions found so far.
 
3 solutions found so far and took 0.06 seconds so far.
─────────────────────────────── doing chunk: 4 ────────────────────────────────
[4 names] exorcism gestapo speakeasy vein
[4 names] deploy exorcism moresby mycenae
[4 names] bonnet elysee escritoire isis
[4 names] eradicate isis mycenae smokescreen
[4 names] balm efferent filmy smokescreen
[4 names] centipede covariate gestapo infra
[4 names] centipede covariate speakeasy vein
[4 names] brute centipede efferent plugging
[4 names] alliance balm deploy mycenae
 
Stopped after finding 12 subsets.
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Subset sum problem
 
knap = [["alliance", -624],
["archbishop", -915],
["balm", 397],
["bonnet", 452],
["brute", 870],
["centipede", -658],
["cobol", 362],
["covariate", 590],
["departure", 952],
["deploy", 44],
["diophantine", 645],
["efferent", 54],
["elysee", -326],
["eradicate", 376],
["escritoire", 856],
["exorcism", -983],
["fiat", 170],
["filmy", -874],
["flatworm", 503],
["gestapo", 915],
["infra", -847],
["isis", -982],
["lindholm", 999],
["markham", 475],
["mincemeat", -880],
["moresby", 756],
["mycenae", 183],
["plugging", -266],
["smokescreen", 423],
["speakeasy", -745],
["vein", 813]]
 
knapsack = createDimList([pow(2, len(knap)),len(knap)+2])
knapweight = createDimList([pow(2, len(knap)),len(knap)+2])
lenknap = list(pow(2, len(knap)))
 
powerset(knap)
 
func powerset(list)
n1 = 0
num = 0
for i = 2 to (2 << len(list)) - 1 step 2
n2 = 0
n1 = n1 + 1
weight = 0
for j = 1 to len(list)
if i & (1 << j)
n2 = n2 + 1
knapsack[n1][n2] = list[j][1]
weight = weight + list[j][2]
knapweight[n1][n2] = list[j][2]
ok
next
lenknap[n1] = n2+1
if weight = 0
see "" + num + ": "
for p = 1 to lenknap[n1]-1
see "{" + knapsack[n1][p] + " " + knapweight[n1][p]+ "}"
next
see nl
num = num + 1
ok
next
 
func createDimList(dimArray)
sizeList = len(dimArray)
newParms = []
for i = 2 to sizeList
Add(newParms, dimArray[i])
next
alist = list(dimArray[1])
if sizeList = 1
return aList
ok
for t in alist
t = createDimList(newParms)
next
return alist
</syntaxhighlight>
Output:
<pre>
0: {(archbishop, -915), (gestapo, 915)}
1: {(fiat, 170), (vein, 813), (isis, -982)}
2: {(alliance, -624), (departure, 952), (elysee, -326)}
3: {(alliance, -624), (archbishop, -915), (departure, 952), (covariate, 590)}
4: {(markham, 475), (infra, -847), (eradicate, 376)}
5: {(flatworm, 503), (eradicate, 376), (filmy, -874)}
</pre>
 
=={{header|Ruby}}==
a brute force solution:
<langsyntaxhighlight lang="ruby">weights = {
'alliance' =>-624, 'archbishop'=>-915, 'balm' => 397, 'bonnet' => 452,
'brute' => 870, 'centipede' =>-658, 'cobol' => 362, 'covariate'=> 590,
Line 1,321 ⟶ 2,699:
puts "no subsets of length #{n} sum to zero"
end
end</langsyntaxhighlight>
 
{{out}}
Line 1,356 ⟶ 2,734:
no subsets of length 30 sum to zero
no subsets of length 31 sum to zero</pre>
 
=={{header|Scala}}==
{{Out}}Best seen running in your browser by [https://scastie.scala-lang.org/KnhJimmSTL6QXIGTAdZjBQ Scastie (remote JVM)].
<syntaxhighlight lang="scala">object SubsetSum extends App {
private val LIMIT = 5
private val n = items.length
private val indices = new Array[Int](n)
private var count = 0
 
private def items = Seq(
Item("alliance", -624),
Item("archbishop", -915),
Item("balm", 397),
Item("bonnet", 452),
Item("brute", 870),
Item("centipede", -658),
Item("cobol", 362),
Item("covariate", 590),
Item("departure", 952),
Item("deploy", 44),
Item("diophantine", 645),
Item("efferent", 54),
Item("elysee", -326),
Item("eradicate", 376),
Item("escritoire", 856),
Item("exorcism", -983),
Item("fiat", 170),
Item("filmy", -874),
Item("flatworm", 503),
Item("gestapo", 915),
Item("infra", -847),
Item("isis", -982),
Item("lindholm", 999),
Item("markham", 475),
Item("mincemeat", -880),
Item("moresby", 756),
Item("mycenae", 183),
Item("plugging", -266),
Item("smokescreen", 423),
Item("speakeasy", -745),
Item("vein", 813)
)
 
private def zeroSum(i: Int, w: Int): Unit = {
if (count < LIMIT) {
if (i != 0 && w == 0) {
for (j <- 0 until i) print(f"${items(indices(j))}%s ")
println
count += 1
} else
for (j <- (if (i != 0) indices(i - 1) + 1 else 0) until n) {
indices(i) = j
zeroSum(i + 1, w + items(j).weight)
}
}
}
 
// Not optimized
private case class Item(word: String, weight: Int) {
override def toString: String = f"($word%s, $weight%d)"
}
 
println(f"The weights of the following $LIMIT%d subsets add up to zero:")
zeroSum(0, 0)
 
}</syntaxhighlight>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">var pairs = Hash(
alliance => -624, archbishop => -915,
brute => 870, centipede => -658,
departure => 952, deploy => 44,
elysee => -326, eradicate => 376,
fiat => 170, filmy => -874,
infra => -847, isis => -982,
mincemeat => -880, moresby => 756,
smokescreen => 423, speakeasy => -745,
balm => 397, bonnet => 452,
cobol => 362, covariate => 590,
diophantine => 645, efferent => 54,
escritoire => 856, exorcism => -983,
flatworm => 503, gestapo => 915,
lindholm => 999, markham => 475,
mycenae => 183, plugging => -266,
vein => 813,
)
 
var weights = pairs.keys.sort.map{|k| pairs{k} }
var inverse = pairs.flip
 
for n in (1 .. weights.end) {
var found = false
weights.combinations(n, {|*comb|
if (comb.sum == 0) {
say "Length #{n}: "+" ".join(inverse{comb...})
found = true
break
}
})
found || say "Length #{n}: (none)"
}</syntaxhighlight>
{{out}}
<pre style="height: 40ex; overflow: scroll">
Length 1: (none)
Length 2: archbishop gestapo
Length 3: centipede markham mycenae
Length 4: alliance balm deploy mycenae
Length 5: alliance brute covariate deploy mincemeat
Length 6: alliance archbishop balm deploy gestapo mycenae
Length 7: alliance archbishop bonnet cobol departure exorcism moresby
Length 8: alliance archbishop balm bonnet fiat flatworm isis lindholm
Length 9: alliance archbishop balm bonnet brute covariate eradicate mincemeat plugging
Length 10: alliance archbishop balm bonnet brute centipede cobol departure deploy mincemeat
Length 11: alliance archbishop balm bonnet brute centipede cobol departure infra moresby speakeasy
Length 12: alliance archbishop balm bonnet brute centipede cobol covariate diophantine efferent elysee infra
Length 13: alliance archbishop balm bonnet brute centipede cobol covariate departure efferent eradicate filmy isis
Length 14: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee filmy markham speakeasy
Length 15: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy elysee exorcism flatworm infra mycenae
Length 16: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee exorcism filmy gestapo infra
Length 17: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine exorcism isis mincemeat mycenae plugging vein
Length 18: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy isis mycenae vein
Length 19: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism fiat infra isis smokescreen
Length 20: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism gestapo infra isis smokescreen speakeasy
Length 21: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate exorcism flatworm infra lindholm mincemeat plugging speakeasy
Length 22: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism fiat filmy flatworm mincemeat plugging speakeasy
Length 23: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism infra isis mincemeat moresby mycenae smokescreen speakeasy
Length 24: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee exorcism filmy gestapo infra markham mincemeat moresby mycenae plugging smokescreen speakeasy
Length 25: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine eradicate exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging speakeasy
Length 26: alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine elysee eradicate escritoire exorcism fiat filmy gestapo infra isis markham mincemeat mycenae plugging speakeasy vein
Length 27: alliance archbishop balm bonnet brute centipede covariate departure deploy efferent elysee eradicate escritoire exorcism fiat filmy flatworm infra isis lindholm markham mincemeat moresby mycenae plugging smokescreen speakeasy
Length 28: (none)
Length 29: (none)
Length 30: (none)</pre>
 
=={{header|Tcl}}==
As it turns out that the problem space has small subsets that sum to zero, it is more efficient to enumerate subsets in order of their size rather than doing a simple combination search. This is not true of all possible input data sets though; the problem is known to be NP-complete after all.
<langsyntaxhighlight lang="tcl">proc subsetsOfSize {set size} {
if {$size <= 0} {
return
Line 1,385 ⟶ 2,896:
# Nothing was found
return -code error "no subset sums to zero"
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">set wordweights {
alliance -624
archbishop -915
Line 1,421 ⟶ 2,932:
}
set zsss [searchForSubset $wordweights]
puts "Found zero-summing subset: [join [lsort $zsss] {, }]"</langsyntaxhighlight>
{{Out}}
<pre>
Line 1,429 ⟶ 2,940:
=={{header|Ursala}}==
This solution scans the set sequentially while maintaining a record of all distinct sums obtainable by words encountered thus far, and stops when a zero sum is found.
<langsyntaxhighlight Ursalalang="ursala">#import std
#import int
 
Line 1,471 ⟶ 2,982:
#cast %zm
 
main = nullset weights</langsyntaxhighlight>
The name of the function that takes the weighted set is <code>nullset</code>. It manipulates a partial result represented as a list of pairs, each containing a subset of weighted words and the sum of their weights. Here is a rough translation:
* <code>=><></code> fold right combinator with the empty list as the vacuuous case
Line 1,492 ⟶ 3,003:
'smokescreen': 423,
'speakeasy': -745>
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
class Item {
construct new(word, weight) {
_word = word
_weight = weight
}
 
word { _word }
weight { _weight }
 
toString {Fmt.swrite("$-11s $4d", _word, _weight) }
}
 
var items = [
Item.new("alliance", -624),
Item.new("archbishop", -915),
Item.new("balm", 397),
Item.new("bonnet", 452),
Item.new("brute", 870),
Item.new("centipede", -658),
Item.new("cobol", 362),
Item.new("covariate", 590),
Item.new("departure", 952),
Item.new("deploy", 44),
Item.new("diophantine", 645),
Item.new("efferent", 54),
Item.new("elysee", -326),
Item.new("eradicate", 376),
Item.new("escritoire", 856),
Item.new("exorcism", -983),
Item.new("fiat", 170),
Item.new("filmy", -874),
Item.new("flatworm", 503),
Item.new("gestapo", 915),
Item.new("infra", -847),
Item.new("isis", -982),
Item.new("lindholm", 999),
Item.new("markham", 475),
Item.new("mincemeat", -880),
Item.new("moresby", 756),
Item.new("mycenae", 183),
Item.new("plugging", -266),
Item.new("smokescreen", 423),
Item.new("speakeasy", -745),
Item.new("vein", 813)
]
 
var n = items.count
var indices = List.filled(n, 0)
var count = 0
var LIMIT = 5
 
var zeroSum // recursive
zeroSum = Fn.new { |i, w|
if (i != 0 && w == 0) {
for (j in 0...i) System.print("%(items[indices[j]]) ")
System.print()
if (count < LIMIT) {
count = count + 1
} else {
return
}
}
var k = (i != 0) ? indices[i-1] + 1 : 0
var j = k
while (j < n) {
indices[i] = j
zeroSum.call(i + 1, w + items[j].weight)
if (count == LIMIT) return
j = j + 1
}
}
 
System.print("The weights of the following %(LIMIT) subsets add up to zero:\n")
zeroSum.call(0, 0)</syntaxhighlight>
 
{{out}}
<pre style="height: 90ex; overflow: scroll">
The weights of the following 5 subsets add up to zero:
 
alliance -624
archbishop -915
balm 397
bonnet 452
brute 870
centipede -658
cobol 362
covariate 590
departure 952
deploy 44
diophantine 645
efferent 54
elysee -326
eradicate 376
escritoire 856
exorcism -983
fiat 170
filmy -874
flatworm 503
mincemeat -880
plugging -266
speakeasy -745
 
alliance -624
archbishop -915
balm 397
bonnet 452
brute 870
centipede -658
cobol 362
covariate 590
departure 952
deploy 44
diophantine 645
efferent 54
elysee -326
eradicate 376
escritoire 856
exorcism -983
infra -847
isis -982
mincemeat -880
moresby 756
mycenae 183
smokescreen 423
speakeasy -745
 
alliance -624
archbishop -915
balm 397
bonnet 452
brute 870
centipede -658
cobol 362
covariate 590
departure 952
deploy 44
diophantine 645
efferent 54
elysee -326
eradicate 376
escritoire 856
fiat 170
infra -847
isis -982
markham 475
mincemeat -880
plugging -266
speakeasy -745
 
alliance -624
archbishop -915
balm 397
bonnet 452
brute 870
centipede -658
cobol 362
covariate 590
departure 952
deploy 44
diophantine 645
efferent 54
elysee -326
eradicate 376
exorcism -983
fiat 170
infra -847
isis -982
mincemeat -880
moresby 756
plugging -266
vein 813
 
alliance -624
archbishop -915
balm 397
bonnet 452
brute 870
centipede -658
cobol 362
covariate 590
departure 952
deploy 44
diophantine 645
efferent 54
elysee -326
eradicate 376
exorcism -983
fiat 170
infra -847
isis -982
smokescreen 423
</pre>
 
=={{header|XPL0}}==
{{trans|C}}
<syntaxhighlight lang "XPL0">include xpllib; \for Print
def \Items\ Wd, Wt;
def N = 31;
int Set(N), Items;
 
proc SubSum(I, Weight);
int I, Weight, J;
[if I#0 & Weight=0 then
[for J:= 0 to I-1 do
Print("%s%s", if J then " " else "", Items(Set(J),Wd));
Print("\n");
exit;
];
for J:= if I#0 then Set(I-1)+1 else 0 to N-1 do
[Set(I):= J;
SubSum(I+1, Weight+Items(J,Wt));
];
];
 
[Items:= [
["alliance", -624],
["archbishop", -915],
["balm", 397],
["bonnet", 452],
["brute", 870],
["centipede", -658],
["cobol", 362],
["covariate", 590],
["departure", 952],
["deploy", 44],
["diophantine", 645],
["efferent", 54],
["elysee", -326],
["eradicate", 376],
["escritoire", 856],
["exorcism", -983],
["fiat", 170],
["filmy", -874],
["flatworm", 503],
["gestapo", 915],
["infra", -847],
["isis", -982],
["lindholm", 999],
["markham", 475],
["mincemeat", -880],
["moresby", 756],
["mycenae", 183],
["plugging", -266],
["smokescreen", 423],
["speakeasy", -745],
["vein", 813] ];
SubSum(0, 0);
]</syntaxhighlight>
{{out}}
<pre>
alliance archbishop balm bonnet brute centipede cobol covariate departure deploy diophantine efferent elysee eradicate escritoire exorcism fiat filmy flatworm mincemeat plugging speakeasy
</pre>
 
=={{header|zkl}}==
{{trans|C}}
<syntaxhighlight lang="zkl">var items=T(
T("alliance", -624), T("archbishop", -915), T("balm", 397),
T("bonnet", 452), T("brute", 870), T("centipede", -658),
T("cobol", 362), T("covariate", 590), T("departure", 952),
T("deploy", 44), T("diophantine", 645), T("efferent", 54),
T("elysee", -326), T("eradicate", 376), T("escritoire", 856),
T("exorcism", -983), T("fiat", 170), T("filmy", -874),
T("flatworm", 503), T("gestapo", 915), T("infra", -847),
T("isis", -982), T("lindholm", 999), T("markham", 475),
T("mincemeat", -880), T("moresby", 756), T("mycenae", 183),
T("plugging", -266), T("smokescreen", 423), T("speakeasy", -745),
T("vein", 813));
fcn subSum(set,i,weight){
if(i and not weight){
itms:=i.pump(List,'wrap(n){ items[set[n]][0] });
println(itms.len(),": ",itms.concat(","));
throw(Exception.TheEnd);
}
foreach j in ([i and set[i-1] + 1 or 0 .. items.len()-1]){
set[i]=j;
self.fcn(set, i+1, weight + items[j][1]);
}
}
 
set:=List.createLong(items.len(),0);
try{ subSum(set,0,0); }catch(TheEnd){}</syntaxhighlight>
{{out}}
<pre>
22: alliance,archbishop,balm,bonnet,brute,centipede,cobol,covariate,departure,deploy,diophantine,efferent,elysee,eradicate,escritoire,exorcism,fiat,filmy,flatworm,mincemeat,plugging,speakeasy
</pre>
9,482

edits