I need to make this method more recursive to make it expandable

12 hours ago 3
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.

Read Entire Article