There are lots of questions and answers for combination algorithms but in all my searching I haven't seen this problem anywhere before. This is as much a mathematical challenge as a coding challenge.
The Problem:
If I have a set of distinguished items and a set of undistinguished boxes, how do I find all the combinations of items in boxes?
Bear in mind, it's not just the number of combinations that we want, the program must output, all the possible combinations.
Rules:
- All the objects must be used
- The order the objects are placed in the box doesn't matter
- The order the boxes are positioned in doesn't matter
- Boxes have no limit on the number of items they can contain
- The only thing that distinguishes a box is the items it contains
Examples of equivalency:
- [ab][cd][ ] is equivalent to [ab][ ][cd]
- [abcd][ ][ ] is equivelent to [bdac][ ][ ]
- [ab][c][d] is equivalent to [ab][d][c]
I can sit down with a pen and paper to draw out all the combinations but I can't work out what algorithm my brain is using.
In this code a, b, c and d are items.
std::vector<char> unsorted = { 'a', 'b', 'c', 'd' };
int box_count = 3;
std::vector<std::vector<std::vector<char>>> sorted = {};
sorted = FillBoxes(unsorted, box_count);
Expected Result:
sorted = {
{ {a}, {b}, {c,d}},
{ {a}, {b,c}, {d} },
{ {a}, {b,d}, {c} },
{ {a}, {b,c,d}, {} },
{ {a,b}, {c}, {d} },
{ {a,b}, {c,d}, {} },
{ {a,c}, {b}, {d} },
{ {a,c}, {b,d}, {} },
{ {a,d}, {b}, {c} },
{ {a,d}, {b,c}, {} },
{ {a,b,c}, {d}, {} },
{ {a,b,d}, {c}, {} },
{ {a,c,d}, {b}, {} },
{ {a,b,c,d}, {}, {} }
}
I am looking for a logical algorithm that does the job of FillBoxes()
, and outputs the list as seen in sorted
.
I have had a few ideas involving binary trees and iterative pointers but none of them have worked. It looks like a solvable problem but if it is mathematically impossible, I'd appreciate the feedback too.
Thanks!
(prefered language c++ but I can read most common programming languages)