Skip to content

Instantly share code, notes, and snippets.

@blezek
Created October 26, 2012 15:46
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 blezek/3959527 to your computer and use it in GitHub Desktop.
Save blezek/3959527 to your computer and use it in GitHub Desktop.
Finds words in a specified dictionary file from a scrambled list of letters
#!/usr/bin/env groovy
import groovy.util.Node;
import java.util.zip.GZIPInputStream;
def root = new Node ( null, "root", [ path : "", leaf : false, value : "" ] );
Words = []
// Pull off the first letter, see if the node has that.
// If at end of word, make as leaf node
def stuffWord ( word, node ) {
if ( word.length() == 0 ) {
node.attributes()["leaf"] = true
return
}
letter = new String ( word[0] )
child = node.children().find { it.attributes()["value"] == letter }
if ( ! child ) {
child = new Node ( node, letter, [ path : node.attributes()["path"] + letter, leaf : false, value : letter ] );
}
stuffWord ( word.substring(1), child )
}
// See if we match anything
def findWords ( letters, node ) {
// Do a depth first search
node.children().each { child ->
index = letters.findIndexOf { it == child.name() }
if ( index >= 0 ) {
// we have a match, remove the letter
remainingLetters = letters.substring(0,index) + letters.substring(index+1,letters.length() )
if ( child.attributes()["leaf"] ) {
Words.add ( child.attributes()["path"] )
}
findWords ( remainingLetters, child )
}
}
}
if ( this.args.size() != 2 ) {
println ( "usage: letterpress <dictionary> <letters>" )
println ( 'sample: \ngroovy letterpress.groovy sowpods.txt xmwzldqgtnpuwwanuemwcpisv | awk \'{ print length($0),$0 | "sort -n -r"}\'> zac2.txt' )
System.exit ( 1 )
}
def DictionaryFile = this.args[0];
def Letters = this.args[1];
def StartTime = System.currentTimeMillis()
def count = 0;
def input = new FileInputStream ( DictionaryFile );
if ( DictionaryFile.endsWith ( '.gz' ) ) {
input = new GZIPInputStream ( input )
}
input.eachLine {
stuffWord ( it.toLowerCase(), root )
count++
}
def EndTime = System.currentTimeMillis()
println ( "# Searching ${DictionaryFile} for words made up of ${Letters}" )
println ( "# Finished building tree in ${ (EndTime-StartTime)/1000.0 } seconds for ${count} entries" )
StartTime = System.currentTimeMillis()
findWords ( Letters, root )
EndTime = System.currentTimeMillis()
println ( "# Found words in ${ (EndTime-StartTime)/1000.0 } seconds" )
// Sort longest to shortest, then alphabetically
Words = Words.sort { a, b ->
eq = a.length() <=> b.length()
if ( eq == 0 ) {
eq = a <=> b
} else {
eq *= -1
}
eq
}
Words.each {
println ( it )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment