Skip to content

Instantly share code, notes, and snippets.

@LyndonArmitage
Last active July 28, 2016 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LyndonArmitage/f320cb0eac5a8274c657 to your computer and use it in GitHub Desktop.
Save LyndonArmitage/f320cb0eac5a8274c657 to your computer and use it in GitHub Desktop.
WordWheelSolver.scala
import scala.collection.mutable
object WordWheelSolver {
private val defaultMinSize = 3
def main(args: Array[String]) {
if (args.length >= 3) {
val minLetters: Int = {
if (args.length >= 4) {
args(3).toInt
} else {
defaultMinSize
}
}
val required: Char = args(0).charAt(0)
if (args(0).length > 1) {
Console.err.println("Using first character of arg1 (" + required + ") only")
}
val others = args(1).toList
val wordList = loadWordList(args(2), minLetters)
val results = solve(required, others, wordList, minLetters)
results.foreach(println)
} else {
Console.err.println("Requires 3 arguments:")
Console.err.println("arg 1: Required letters")
Console.err.println("arg 2: Optional letters")
Console.err.println("arg 3: Path to word list")
Console.err.println("arg 4 (Optional): Min letter count, defaults to " + defaultMinSize)
}
}
def loadWordList(path: String, minLength: Int): Iterator[String] = {
scala.io.Source.fromFile(path, "UTF-8")
.getLines()
.filter(_.length >= minLength)
}
def createWordMap(wordList: Iterator[String]): Map[String, List[String]] = {
val toWords: mutable.HashMap[String, List[String]] = mutable.HashMap[String, List[String]]()
// Take each word and map it to it's ordered counterpart
wordList.foreach(word => {
val ordered = sortWord(word)
if (toWords.contains(ordered)) {
toWords.put(ordered, toWords.get(ordered).get :+ word)
} else {
toWords.put(ordered, List[String](word))
}
})
// convert to an immutable map
toWords.toMap
}
def sortWord(word: String) = word.toCharArray.sorted.mkString
def solve(required: Char, otherChars: List[Char], wordList: Iterator[String], minLength: Int): Seq[String] = {
// Define a hash map for storing ordered word strings to the original words
val toWords = createWordMap(wordList)
// Generate all possible combinations of otherChars + the required character
val allPossibles = Range.inclusive(minLength - 1, otherChars.length)
.flatMap(i => otherChars.combinations(i))
.sortWith((left, right) => left.length > right.length)
.map(l => l.::(required))
.map(s => sortWord(s.mkString))
.iterator
// Get a flat list of the results
allPossibles.flatMap(possible => {
toWords.get(possible)
}).flatten.toSeq
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment