Subset sum problem: Difference between revisions

Content added Content deleted
m (→‎{{header|Ring}}: Remove vanity tags)
Line 1,342: Line 1,342:
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 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>
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|Phix}}==
Simple Brute force
<lang Phix>sequence {words,weights} = columnize({{"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}})

function comb(sequence pool, integer needed, done=0, sequence chosen={})
if needed=0 then -- got a full set
integer t = 0
for i=1 to length(chosen) do
t += weights[chosen[i]]
end for
if t=0 then
for i=1 to length(chosen) do
chosen[i] = words[chosen[i]]
end for
printf(1,"%d: %s\n",{length(chosen),sprint(chosen)})
return 1
end if
elsif done+needed<=length(pool) then
-- get all combinations with and without the next item:
done += 1
if comb(pool,needed-1,done,append(chosen,pool[done]))
or comb(pool,needed,done,chosen) then
return 1
end if
end if
return 0
end function

integer n = length(weights)
for i=1 to n do
if comb(tagset(n),i)=0 then
printf(1,"%d: No zero-sum subsets of that length\n",{i})
end if
end for</lang>
{{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","brute","centipede","cobol","departure","infra","moresby","speakeasy"}
12: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","diophantine","efferent","elysee","infra"}
13: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","efferent","eradicate","filmy","isis"}
14: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","elysee","filmy","markham","speakeasy"}
15: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","elysee","exorcism","flatworm","infra","mycenae"}
16: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","elysee","exorcism","filmy","gestapo","infra"}
17: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","exorcism","isis","mincemeat","mycenae","plugging","vein"}
18: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","efferent","elysee","exorcism","filmy","isis","mycenae","vein"}
19: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","efferent","elysee","eradicate","exorcism","fiat","infra","isis","smokescreen"}
20: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","efferent","elysee","eradicate","exorcism","gestapo","infra","isis","smokescreen","speakeasy"}
21: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","efferent","elysee","eradicate","exorcism","flatworm","infra","lindholm","mincemeat","plugging","speakeasy"}
22: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","efferent","elysee","eradicate","escritoire","exorcism","fiat","filmy","flatworm","mincemeat","plugging","speakeasy"}
23: {"alliance","archbishop","balm","bonnet","brute","centipede","cobol","covariate","departure","deploy","diophantine","efferent","elysee","eradicate","escritoire","exorcism","infra","isis","mincemeat","moresby","mycenae","smokescreen","speakeasy"}
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"}
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"}
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"}
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"}
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 dictionary so that fractional weights can be accomodated).<br>
This is significantly faster (near instant, in fact) than an "all possible combinations" approach.<br>
Note that new_dict(tid) has been introduced for this task in 0.8.0, which has not yet been shipped.

Shows the first zero-sum subset found, only.
<lang Phix>constant weights = {-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 }

integer sums = new_dict()

for w=1 to length(weights) do
-- 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).
integer s = new_dict(sums)
atom v = weights[w]
if getd_index(v,s)=NULL then setd(v,{w},s) end if
sequence sk = getd_all_keys(s)
for i=1 to length(sk) do
integer node = getd_index(sk[i],sums)
if node!=NULL and getd_index(sk[i]+v,s)=0 then
setd(sk[i]+v,getd_by_index(node,sums)&w,s)
end if
end for
destroy_dict(sums)
sums = s

integer node = getd_index(0,sums)
if node!=0 then
sequence s0 = getd_by_index(node,sums)
atom t = 0 -- (sanity check)
for i=1 to length(s0) do
integer si = s0[i]
t += weights[si]
s0[i] = weights[si]
end for
printf(1,"Total %d for %s\n",{t,sprint(s0)})
exit
end if
end for</lang>
{{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|PicoLisp}}==
=={{header|PicoLisp}}==