ARTICLE AD BOX
I wrote a function that uses a list of characters, then returns a list of all permutations of those characters where no character is repeated of a given length. I eventually want to change it so that the list of characters is an input rather than being hard-coded in, but that's not the most fundamental problem I wanted help with.
This code does work for sequences of characters of length 1, 2, or 3, but if I continue writing it like this, it's going to get bigger and more awkward and more repetitive the more I expand the maximum length. I intuitively sense that there must be some recursive way to do this more efficiently, but it feels daunting to figure out exactly how.
Code is in Java 11.
import java.util.ArrayList; import java.util.Arrays; //Pretend the class wrapper is here public static ArrayList<ArrayList<Character>> five6789Scramble(byte length) { /*Returns all non-repeating permutations of the characters in charSet that don't start with the zero index character */ if(length < 0) { System.out.println("input length for five6789Scramble must not be negative"); throw new IndexOutOfBoundsException(); } ArrayList<Character> charSet = new ArrayList<Character>( Arrays.asList('a','b','c','d','e','f','g','h','i','j' )); if(length>charSet.toArray().length) { System.out.println("length specified for five6789Scramble is too long"); throw new IndexOutOfBoundsException(); } ArrayList<ArrayList<Character>> ret = new ArrayList<ArrayList<Character>>(); for (byte i=1; i<10; i++) { if(length > 1) { ArrayList<Character> remainingChars = new ArrayList<Character>(charSet); remainingChars.remove(i); ArrayList<Character> toAddStarter = new ArrayList<Character>(); toAddStarter.add(charSet.get(i)); for (byte j=0; j<remainingChars.toArray().length; j++) { if(length > 2) { ArrayList<Character> toAddStarterTwo = new ArrayList<Character>(toAddStarter); toAddStarterTwo.add(remainingChars.get(j)); ArrayList<Character> remainingCharsTwo = new ArrayList<Character>(remainingChars); remainingCharsTwo.remove(j); for(byte k=0; k<remainingCharsTwo.toArray().length; k++) { ArrayList<Character> toAdd = new ArrayList<Character>(toAddStarterTwo); toAdd.add(remainingCharsTwo.get(k)); ret.add(toAdd); } } else { ArrayList<Character> toAdd = new ArrayList<Character>(toAddStarter); toAdd.add(remainingChars.get(j)); ret.add(toAdd); } } } else { ArrayList<Character> toAdd = new ArrayList<Character>(); toAdd.add(charSet.get(i)); ret.add(toAdd); } } return ret; }(The ultimate goal here is to build numbers digit by digit so that I can find which of the 9*9! ten-digit numbers where each digit is different have the least versus most factors, which is why I don't want it to start with the first character which will be a zero, but I don't think that's relevant.)
Is there a way to make this recursive so that I don't have to write an "if (length > 3)" block that copies the code from the "if (length > 2)" block? I eventually want to get this to length 10, even though that will produce an output of 3,265,920 arrays of length ten.
