I'd like to write a Java method that operates something like this:
input 1, output { {0}, {1} }
input 2, output { {0, 0}, {0, 1}, {1, 0}, {1, 1} }
input 3, output { {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, ... {1, 1, 1} }
...
(I use 0 and 1 in the example for concision; the lowest-level subelements might be HIGH and LOW, 'A' and 'Z', or any two other distinct values.)
This feels like a good candidate for recursion, but that's just a feeling at this point. All of my efforts so far have seemed suboptimal.* Any thoughts on a good approach, other than using a different language?
* For example: Loop over 0 to (2^input)-1; interpret the number as an [input]-digit binary value; use the binary digits to generate the subarray. Bleah.
EDIT: Present generalized iterative solution
public enum Item {
ITEM1, ITEM2, ...; // As many as needed
private static final int ITEM_COUNT = values().length;
public static Item[][] allCombinationsOfSize(int comboSize) {
int arraySize = (int) Math.pow(ITEM_COUNT, comboSize);
Item array[][] = new Item[arraySize][];
for ( int n = 0 ; n < arraySize ; ++n ) {
array[n] = nthSubarray(n, comboSize);
}
return array;
}
private static Item[] nthSubarray(int n, int comboSize) {
Item combo[] = new Item[comboSize];
for ( int i = comboSize - 1 ; i >= 0 ; --i ) {
combo[i] = Item.values()[n % ITEM_COUNT];
n /= ITEM_COUNT;
}
return combo;
}
}
I believe that allCombinationsOfSize is the method I'm looking for. I still have a sneaking suspicion that I'm missing something more elegant. Nevertheless, the above allows me to write this in my JUnit test ...
for ( Signal signals[] : Signal.allCombinationsOfSize(pinCount) ) {
assertEquals(
cls.getSimpleName() + " result",
expectedResultFor(cls, signals),
actualResultFor(cls, signals)
);
}
... which is fairly straightforward.