You can interpret generate combinations of {...}x as count in base X
Your question, rephrased: Enumerate base X numbers, up to the highest such number with n digits
Naïve stab:
for(int i = 0; i < Math.pow(5, 3); i++) {
System.out.println(Integer.toString(i, 5));
}
Now, a few observations:
- Your example begins with "012", I'll assume that you actually meant "000"
- The base in your example is "4 + 1 = 5"
- The base in the general case is "b - a + 1", where your range is {a..b}
- The symbols normally used to represent numbers in base X are the Arabic numerals 0..(X-1)
- The symbols that you use in your number system are the Arabic numerals, from a to b
- Numbers do not have leading zeros, string representations of numbers do.
- The highest number of length n in base X is Xn - 1
- You can not customize String padding, so set width to n and replace ' ' with a
To generate your list of Strings:
- Find the base of your number system
- Count from 0 to Xn-1
- Generate a base X representation of each number
- Add a to all symbols in the generated representation
- Pad the string on the left with a
Code!
public static void main(String[] args) {
for(String s : generate(3, 0, 4)) {
System.out.println(s);
}
}
private static List<String> generate(int n, int a, int b) {
List<String> numbers = new ArrayList<>();
int base = b - a + 1; // (1)
for(int i = 0; i < Math.pow(base, n); i++) { // (2)
String s = Integer.toString(i, base); // (3)
s = substituteSymbols(s, a); // (4)
s = String.format("%" + n + "s", s); // (5)...
s = replacePadding(a, s); // ...(5)
numbers.add(s);
}
return numbers;
}
private static String substituteSymbols(String s, int a) {
char[] digits = s.toCharArray();
StringBuilder sb = new StringBuilder();
for(int c = 0; c < digits.length; c++) {
int val = Character.getNumericValue(digits[c]) + a;
sb.append(Character.forDigit(val, Character.MAX_RADIX));
}
return sb.toString();
}
private static String replacePadding(int a, String s) {
return s.replace(' ', Character.forDigit(a, Character.MAX_RADIX));
}
Note:
- You could also stick to the naïve stab and discard Strings containing digits less than a
- A robust solution should handle invalid arguments
- A generic solution should not assume alphanumeric symbols
- This solution will create unnecessary garbage due to all new Strings
- If the base is higher than Character.MAX_RADIX, base 10 will be used