#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
static int total_nodes;
// prints subset found
void printSubset(int A[], int size)
{
for(int i = 0; i < size; i++)
{
}
}
// qsort compare function
int comparator(const void *pLhs, const void *pRhs)
{
int *lhs = (int *)pLhs;
int *rhs = (int *)pRhs;
return *lhs > *rhs;
}
// inputs
// s - set vector
// t - tuplet vector
// s_size - set size
// t_size - tuplet size so far
// sum - sum so far
// ite - nodes count
// target_sum - sum to be found
void subset_sum(int s[], int t[],
int s_size, int t_size,
int sum, int ite,
int const target_sum)
{
total_nodes++;
if( target_sum == sum )
{
// We found sum
printSubset(t, t_size);
// constraint check
if( ite + 1 < s_size && sum - s[ite] + s[ite+1] <= target_sum )
{
// Exclude previous added item and consider next candidate
subset_sum(s, t, s_size, t_size-1, sum - s[ite], ite + 1, target_sum);
}
return;
}
else
{
// constraint check
if( ite < s_size && sum + s[ite] <= target_sum )
{
// generate nodes along the breadth
for( int i = ite; i < s_size; i++ )
{
t[t_size] = s[i];
if( sum + s[i] <= target_sum )
{
// consider next level node (along depth)
subset_sum(s, t, s_size, t_size + 1, sum + s[i], i + 1, target_sum);
}
}
}
}
}
// Wrapper that prints subsets that sum to target_sum
void generateSubsets(int s[], int size, int target_sum)
{
int *tuplet_vector
= (int *)malloc(size
* sizeof(int));
int total = 0;
// sort the set
qsort(s
, size
, sizeof(int), &comparator
);
for( int i = 0; i < size; i++ )
{
total += s[i];
}
if( s[0] <= target_sum && total >= target_sum )
{
subset_sum(s, tuplet_vector, size, 0, 0, 0, target_sum);
}
}
int main()
{
int weights[] = {15, 22, 14, 26, 32, 9, 16, 8};
int target = 53;
int size = ARRAYSIZE(weights);
generateSubsets(weights, size, target);
printf("Nodes generated %d\n", total_nodes
);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KIAojZGVmaW5lIEFSUkFZU0laRShhKSAoc2l6ZW9mKGEpKS8oc2l6ZW9mKGFbMF0pKQogCnN0YXRpYyBpbnQgdG90YWxfbm9kZXM7CiAKLy8gcHJpbnRzIHN1YnNldCBmb3VuZAp2b2lkIHByaW50U3Vic2V0KGludCBBW10sIGludCBzaXplKQp7CiAgICBmb3IoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQogICAgewogICAgICAgIHByaW50ZigiJSpkIiwgNSwgQVtpXSk7CiAgICB9CiAKICAgIHByaW50ZigiXG4iKTsKfQogCi8vIHFzb3J0IGNvbXBhcmUgZnVuY3Rpb24KaW50IGNvbXBhcmF0b3IoY29uc3Qgdm9pZCAqcExocywgY29uc3Qgdm9pZCAqcFJocykKewogICAgaW50ICpsaHMgPSAoaW50ICopcExoczsKICAgIGludCAqcmhzID0gKGludCAqKXBSaHM7CiAKICAgIHJldHVybiAqbGhzID4gKnJoczsKfQogCi8vIGlucHV0cwovLyBzICAgICAgICAgICAgLSBzZXQgdmVjdG9yCi8vIHQgICAgICAgICAgICAtIHR1cGxldCB2ZWN0b3IKLy8gc19zaXplICAgICAgIC0gc2V0IHNpemUKLy8gdF9zaXplICAgICAgIC0gdHVwbGV0IHNpemUgc28gZmFyCi8vIHN1bSAgICAgICAgICAtIHN1bSBzbyBmYXIKLy8gaXRlICAgICAgICAgIC0gbm9kZXMgY291bnQKLy8gdGFyZ2V0X3N1bSAgIC0gc3VtIHRvIGJlIGZvdW5kCnZvaWQgc3Vic2V0X3N1bShpbnQgc1tdLCBpbnQgdFtdLAogICAgICAgICAgICAgICAgaW50IHNfc2l6ZSwgaW50IHRfc2l6ZSwKICAgICAgICAgICAgICAgIGludCBzdW0sIGludCBpdGUsCiAgICAgICAgICAgICAgICBpbnQgY29uc3QgdGFyZ2V0X3N1bSkKewogICAgdG90YWxfbm9kZXMrKzsKIAogICAgaWYoIHRhcmdldF9zdW0gPT0gc3VtICkKICAgIHsKICAgICAgICAvLyBXZSBmb3VuZCBzdW0KICAgICAgICBwcmludFN1YnNldCh0LCB0X3NpemUpOwogCiAgICAgICAgLy8gY29uc3RyYWludCBjaGVjawogICAgICAgIGlmKCBpdGUgKyAxIDwgc19zaXplICYmIHN1bSAtIHNbaXRlXSArIHNbaXRlKzFdIDw9IHRhcmdldF9zdW0gKQogICAgICAgIHsKICAgICAgICAgICAgLy8gRXhjbHVkZSBwcmV2aW91cyBhZGRlZCBpdGVtIGFuZCBjb25zaWRlciBuZXh0IGNhbmRpZGF0ZQogICAgICAgICAgICBzdWJzZXRfc3VtKHMsIHQsIHNfc2l6ZSwgdF9zaXplLTEsIHN1bSAtIHNbaXRlXSwgaXRlICsgMSwgdGFyZ2V0X3N1bSk7CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvLyBjb25zdHJhaW50IGNoZWNrCiAgICAgICAgaWYoIGl0ZSA8IHNfc2l6ZSAmJiBzdW0gKyBzW2l0ZV0gPD0gdGFyZ2V0X3N1bSApCiAgICAgICAgewogICAgICAgICAgICAvLyBnZW5lcmF0ZSBub2RlcyBhbG9uZyB0aGUgYnJlYWR0aAogICAgICAgICAgICBmb3IoIGludCBpID0gaXRlOyBpIDwgc19zaXplOyBpKysgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0W3Rfc2l6ZV0gPSBzW2ldOwogCiAgICAgICAgICAgICAgICBpZiggc3VtICsgc1tpXSA8PSB0YXJnZXRfc3VtICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBjb25zaWRlciBuZXh0IGxldmVsIG5vZGUgKGFsb25nIGRlcHRoKQogICAgICAgICAgICAgICAgICAgIHN1YnNldF9zdW0ocywgdCwgc19zaXplLCB0X3NpemUgKyAxLCBzdW0gKyBzW2ldLCBpICsgMSwgdGFyZ2V0X3N1bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KIAovLyBXcmFwcGVyIHRoYXQgcHJpbnRzIHN1YnNldHMgdGhhdCBzdW0gdG8gdGFyZ2V0X3N1bQp2b2lkIGdlbmVyYXRlU3Vic2V0cyhpbnQgc1tdLCBpbnQgc2l6ZSwgaW50IHRhcmdldF9zdW0pCnsKICAgIGludCAqdHVwbGV0X3ZlY3RvciA9IChpbnQgKiltYWxsb2Moc2l6ZSAqIHNpemVvZihpbnQpKTsKIAogICAgaW50IHRvdGFsID0gMDsKIAogICAgLy8gc29ydCB0aGUgc2V0CiAgICBxc29ydChzLCBzaXplLCBzaXplb2YoaW50KSwgJmNvbXBhcmF0b3IpOwogCiAgICBmb3IoIGludCBpID0gMDsgaSA8IHNpemU7IGkrKyApCiAgICB7CiAgICAgICAgdG90YWwgKz0gc1tpXTsKICAgIH0KIAogICAgaWYoIHNbMF0gPD0gdGFyZ2V0X3N1bSAmJiB0b3RhbCA+PSB0YXJnZXRfc3VtICkKICAgIHsKIAogICAgICAgIHN1YnNldF9zdW0ocywgdHVwbGV0X3ZlY3Rvciwgc2l6ZSwgMCwgMCwgMCwgdGFyZ2V0X3N1bSk7CiAKICAgIH0KIAogICAgZnJlZSh0dXBsZXRfdmVjdG9yKTsKfQogCmludCBtYWluKCkKewogICAgaW50IHdlaWdodHNbXSA9IHsxNSwgMjIsIDE0LCAyNiwgMzIsIDksIDE2LCA4fTsKICAgIGludCB0YXJnZXQgPSA1MzsKIAogICAgaW50IHNpemUgPSBBUlJBWVNJWkUod2VpZ2h0cyk7CiAKICAgIGdlbmVyYXRlU3Vic2V0cyh3ZWlnaHRzLCBzaXplLCB0YXJnZXQpOwogCiAgICBwcmludGYoIk5vZGVzIGdlbmVyYXRlZCAlZFxuIiwgdG90YWxfbm9kZXMpOwogCiAgICByZXR1cm4gMDsKfQ==