Update: After posting this answer, I noticed that an existing answer had the same approach, but I'll still keep mine around since it's more verbose and even has working code :)
If you only had one instance of each item in the original item pool, and your items represented binary digits;
var items {
1 : 1,
2 : 1,
4 : 1,
8 : 1,
16: 1,
32: 1
};
The problem would be simplified to generating a sequence of all numbers that can be represented by these digits:
- 0 ([ ] - no items)
- 1 ([ 1 ])
- 2 ([ 2 ])
- 3 ([ 2, 1 ])
- 4 ([ 4 ])
- etc.
So, your problem can be viewed as simply asking for the sequence of numbers that can be represented by -- not binary -- but a mixed-radix numeral system.
Which means, you could write a counter for this weird numbering system to iterate through values 0 and MAX. So, you'd start with incrementing the least significant digit and carry over to the more significant digit when you've exhausted all the possible values that digit can take.
var items = {
1: 12, // we have 12 x item1
2: 1, // we have 1 x item2
3: 1,
4: 7,
5: 2,
6: 2
};
var counter = {
1: 0,
2: 0,
3: 0,
4: 0,
5: 0,
6: 0
};
function increment(digit) {
if (digit > 6) {
return false;
}
var value = counter[digit] + 1;
if (value > items[digit]) {
counter[digit] = 0;
return increment(digit + 1);
}
counter[digit] = value;
return true;
}
while (increment(1)) {
var set = [];
for (var digit in counter) {
var value = counter[digit];
for (var i = 0; i < value; i++) {
set.push(digit);
}
}
document.write("<div>" + set + "</div>");
}
The output looks something like this:
1
1,1
1,1,1
---- snip ----
2
1,2
1,1,2
---- big snip ----
1,1,1,1,1,1,1,1,2,3,4,4,4,4,4,4,4,5,5,6,6
1,1,1,1,1,1,1,1,1,2,3,4,4,4,4,4,4,4,5,5,6,6
1,1,1,1,1,1,1,1,1,1,2,3,4,4,4,4,4,4,4,5,5,6,6
1,1,1,1,1,1,1,1,1,1,1,2,3,4,4,4,4,4,4,4,5,5,6,6
1,1,1,1,1,1,1,1,1,1,1,1,2,3,4,4,4,4,4,4,4,5,5,6,6