
// WordWheel.java
// https://rosettacode.org/wiki/Word_wheel
// Modified by Andrew Davison, ad@coe.psu.ac.th, Dec. 2022

/* Find all the words made from letters in the word wheel, where
   the letters can be used at most once. Also, all the words must
   include the center letter.

   I ran this code using a text dictionary (words.txt) and with
   Hunspell, and the speedup when using Hunspell is very noticable
   when the wheel uses over 7 letters. Hunspell also often returns
   more words.

   One proviso is that the first time Hunspell is used, there can be 
   a delay while it loads. 

   A boolean filter function is passed as an argument to
   WordUtils.subsets() to reduce its output of words.

  Usage:
    > compile WordWheel.java
    > run WordWheel <wheel-letters> <center-letter>
  e.g.
    > run WordWheel ndeokgelw k
  Others:
    tendiop d       // see ww1.png
    swndira a       // see ww3.png
    glafeir r       // see ww4.png
    nguaoresd d     -- 9 letters   // see ww2.png
    ndeokgelw k     -- 9 letters  
      // see https://rosettacode.org/wiki/Word_wheel
*/

import java.io.*;
import java.util.*;
import java.util.function.Function;


public class WordWheel
{
  public static void main(String[] args)
  {
    if (args.length != 2) {
      System.out.println("Usage: run WordWheel <wheel-letters> <center-letter>");
      return;
    }
    String wheelLetters = args[0];
    String centerLetter = args[1];

    long start = System.currentTimeMillis();

    System.out.println("Generating subsets of \"" + wheelLetters + 
              "\" with center letter '" + centerLetter + "' and len > 3");

    // pass a filter into subsets()
    Function<String, Boolean> klen2 = w -> 
                   ((w.length() > 3) && w.contains(centerLetter));
    ArrayList<String> subsets = WordUtils.subsets(wheelLetters, klen2);

    // generate permutations of all the subsets
    System.out.println("Generating permutations of the subsets");
    ArrayList<String> perms = new ArrayList<>();
    for(String word : subsets) 
      perms.addAll( WordUtils.permutes(word));

    // sort and remove duplicates
    Collections.sort(perms, new LengthFirstComparator());
    perms = WordUtils.removeDups(perms);

    // uncomment one of these two lines...
    // ArrayList<String> dict = WordUtils.loadDict();
    HunspellChecker hsc = new HunspellChecker();

    System.out.println("Finding words...");
    ArrayList<String> words = new ArrayList<>();
    for(String word : perms) {
      // uncomment one of these two lines...
      // if (dict.contains(word)) {
      if (hsc.isCorrect(word))
        words.add(word);
    }

    hsc.close();
    WordUtils.printWords(words);

    long duration = System.currentTimeMillis() - start;
    System.out.println("Duration: " + duration/1000 + " secs");
  }  // end of main()


}  // end of WordWheel class

