-1

So I want to make an anagram decoder, and I want to know if there's a better way to do it. My current code is this:

Random random = new Random();
char[] splitAnagram = chosenAnagram.toCharArray();
int[] presetNumbers = new int[chosenAnagram.length()];
int i = 0;
while (true) {
    TimeUnit.MILLISECONDS.sleep(10);
    int thisRandom = random.nextInt(chosenAnagram.length());
    if (Arrays.asList(presetNumbers).contains(thisRandom) == true)
        presetNumbers[i] = thisRandom;
    else
        continue;
    i++;
    if (i > chosenAnagram.length())
        break;
}
for (int l = 0; l < chosenAnagram.length(); l++) {
    System.out.println(splitAnagram[presetNumbers[l]]);
}

Basically, it generates random numbers for each letter, so that it "scrambles" the word. It's flawed as is, because it's not even supposed to loop yet, just make one scramble, but it just in-general seems really slow and prone-to-error (I sleep by 10ms because it can only make random numbers every system time change).

I'm wondering if there's some other algorithm for this, or a possible API I could use. Thank you!

P.S I'm running Eclipse Photon, in case you know of a plugin for that.

tdog
  • 169
  • 2
  • 11
  • `Arrays.asList(presetNumbers).contains(thisRandom)` is always false. Look carefully at the types (try assigning the list to a variable). – Andy Turner Aug 29 '18 at 19:05
  • Why are you using randoms at all? For making a list of all possible anagrams for a given word there is no need to random. It would just rearrange in nested loops. It probably is me misunderstanding something, but could you solve it for me? – Yunnosch Aug 29 '18 at 19:06
  • @Yunnosch I was using randoms because I don't know how to rearrange arrays without them. – tdog Aug 29 '18 at 19:10
  • 1
    There's an easier way to find anagrams. Convert your dictionary (i.e., word list) into an array where each element is a list of anagrams and each key is made by sorting the letters of these words in alphabetical order. For example, a dictionary ["act", "cat", "dog", "fish", "god"] would be converted into ["act" => ["act", "cat"], "dgo" => ["dog", "god"], "ifhs" => ["fish"]]. You only need to do this once. Then to find all the anagrams of a word, sort its letters in alphabetical order and use the result to access this array. – r3mainer Aug 29 '18 at 19:34
  • Check out [Collections.shuffle](https://docs.oracle.com/javase/9/docs/api/java/util/Collections.html#shuffle-java.util.List-java.util.Random-). – pjs Aug 29 '18 at 19:36

1 Answers1

0

I found a way to do this with the Fisher--Yates Shuffle, from this Stackoverflow post. Here is how the code turned out:

@SuppressWarnings("unchecked")
private void beginDecoding(String chosenAnagram) throws InterruptedException {
    Random random = new Random();
    List madeAnagrams = new ArrayList();
    int factorial = 1;
    for (int i = chosenAnagram.length(); i > 0; i--) {
        factorial = i * factorial;
    }
    System.out.println(factorial);
    while (true) {
        if (madeAnagrams.size() == factorial) {
            break;
        }
        TimeUnit.MILLISECONDS.sleep(10);
        char[] splitAnagram = chosenAnagram.toCharArray();
        for (int i = chosenAnagram.length() - 1; i > 0; i--) {
            int index = random.nextInt(i + 1);
            char letter = splitAnagram[index];
            splitAnagram[index] = splitAnagram[i];
            splitAnagram[i] = letter;
        }
        String returnAnagram = new String(splitAnagram);
        if (!madeAnagrams.contains(returnAnagram)) {
            madeAnagrams.add(returnAnagram);
            System.out.println(returnAnagram);
        }
        else
            continue;
    }
}
tdog
  • 169
  • 2
  • 11