-
-
Save LyndonArmitage/f320cb0eac5a8274c657 to your computer and use it in GitHub Desktop.
WordWheelSolver.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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