I am having trouble getting the logic right for a method I'm trying to write and I thought it might be a fun problem for someone else to have a look at. The target language is Java, though I'm just going to present it generically so as not to discourage anyone from sharing their thoughts.
The input to the method is an arbitrary number of hierarchical sets of data and the output is a list of combinations of members of that data where each combination has one member from each set of hierarchical data. However, every possible combination isn't included. The key to building the combinations is whether or not a given element is a leaf member in the hierarchy or not and each element of each set knows its name and whether or not it is a leaf. First, I'll give an example and then I'll try to articulate the rules. For concreteness, we'll consider that the input is the following three sets:
A1 B1 C1
A10 B10 C10
A11 B100 C11
B101 C12
B102 C13
B103
B104
B105
B11
B110
B111
B112
B113
B114
The corresponding output would look like this:
(1) A1 B1 C1 (37) A10 B111 C11 (73) A11 B103 C10
(2) A10 B1 C1 (38) A10 B111 C12 (74) A11 B103 C11
(3) A10 B10 C1 (39) A10 B111 C13 (75) A11 B103 C12
(4) A10 B100 C1 (40) A10 B112 C1 (76) A11 B103 C13
(5) A10 B100 C10 (41) A10 B112 C10 (77) A11 B104 C1
(6) A10 B100 C11 (42) A10 B112 C11 (78) A11 B104 C10
(7) A10 B100 C12 (43) A10 B112 C12 (79) A11 B104 C11
(8) A10 B100 C13 (44) A10 B112 C13 (80) A11 B104 C12
(9) A10 B101 C1 (45) A10 B113 C1 (81) A11 B104 C13
(10) A10 B101 C10 (46) A10 B113 C10 (82) A11 B11 C1
(11) A10 B101 C11 (47) A10 B113 C11 (83) A11 B110 C1
(12) A10 B101 C12 (48) A10 B113 C12 (84) A11 B110 C10
(13) A10 B101 C13 (49) A10 B113 C13 (85) A11 B110 C11
(14) A10 B102 C1 (50) A10 B114 C1 (86) A11 B110 C12
(15) A10 B102 C10 (51) A10 B114 C10 (87) A11 B110 C13
(16) A10 B102 C11 (52) A10 B114 C11 (88) A11 B111 C1
(17) A10 B102 C12 (53) A10 B114 C12 (89) A11 B111 C10
(18) A10 B102 C13 (54) A10 B114 C13 (90) A11 B111 C11
(19) A10 B103 C1 (55) A11 B1 C1 (91) A11 B111 C12
(20) A10 B103 C10 (56) A11 B10 C1 (92) A11 B111 C13
(21) A10 B103 C11 (57) A11 B100 C1 (93) A11 B112 C1
(22) A10 B103 C12 (58) A11 B100 C10 (94) A11 B112 C10
(23) A10 B103 C13 (59) A11 B100 C11 (95) A11 B112 C11
(24) A10 B104 C1 (60) A11 B100 C12 (96) A11 B112 C12
(25) A10 B104 C10 (61) A11 B100 C13 (97) A11 B112 C13
(26) A10 B104 C11 (62) A11 B101 C1 (98) A11 B113 C1
(27) A10 B104 C12 (63) A11 B101 C10 (99) A11 B113 C10
(28) A10 B104 C13 (64) A11 B101 C11 (100) A11 B113 C11
(29) A10 B11 C1 (65) A11 B101 C12 (101) A11 B113 C12
(30) A10 B110 C1 (66) A11 B101 C13 (102) A11 B113 C13
(31) A10 B110 C10 (67) A11 B102 C1 (103) A11 B114 C1
(32) A10 B110 C11 (68) A11 B102 C10 (104) A11 B114 C10
(33) A10 B110 C12 (69) A11 B102 C11 (105) A11 B114 C11
(34) A10 B110 C13 (70) A11 B102 C12 (106) A11 B114 C12
(35) A10 B111 C1 (71) A11 B102 C13 (107) A11 B114 C13
(36) A10 B111 C10 (72) A11 B103 C1
Though I understand the pattern unambiguously, it's hard for me to articulate the rules for the same reason that it's hard for me to write the method. Basically, if an elemnet is a non leaf, it's only used to build combinations with the root element from the sets to it's right. If instead an element is a leaf, it's crossed with all of the posisble combinations to it's right. Obviously the problem is recursive and I feel like the psuedo code should look something like this:
buildCombinations(element, setNumber, numberOfSets)
{
if (element.IsLeaf( ))
{
List list = buildCombinations(elementFromNextList, setNumber++, numberOfSets)
CrossJon element with list
}
else
{
IfOnlyIKnew!
}
}
But I've been staring at it for two days and I just can't quite wrap my head around it. I supsect that I've not done an adaquate job of explaining the situation so please feel free to ask questions for clarification. In any event, this strikes me as the kind of problem that might be obvious to someone a bit smarter than me and I'd love it if anyone can offer any suggestions.
Thanks in advance!
A11 East C1containsEast?