Created
October 26, 2012 15:46
-
-
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
This file contains hidden or 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
#!/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