Listing 1. findwords.sh<remark role="output-file">11935l1.qrk</remark></title> <programlisting> <![CDATA[ #!/bin/sh # Findwords -- given a set of letters, try to find all the words you can # spell dictionary="/Users/taylor/Documents/Linux Journal/dictionary.txt" testwords=$(mktemp /tmp/findwords.XXXXXX) || exit 1 if [ -z "$1" ] ; then echo "Usage: findwords [sequence of letters]" exit 0 fi if [ "$1" = "-f" ] ; then showfails=1 shift fi ## PART ONE: make the regular expression length="$(echo "$1" | wc -c)" minlength=$(( $length - 4 )) # we can ignore a max of 2 letters if [ $minlength -lt 3 ] ; then echo "Error: sequence must be at least 5 letters long" exit 0 fi unique="$(echo $1 | sed 's/./&\ /g' | tr '[[:upper:]]' '[[:lower:]]' | sort | uniq | fmt | \ tr -C -d '[[:alpha:]]')" while [ $minlength -lt $length ] do regex="^[$unique]{$minlength}$" if [ $verbose ] ; then echo "Raw word list of length $minlength for letterset $unique:" grep -E $regex "$dictionary" | tee -a $testwords else grep -E $regex "$dictionary" >> $testwords fi minlength="$(( $minlength + 1 ))" done ## PART TWO: sort letters for validity filter pattern="$(echo $1 | sed 's/./&\ /g' | tr '[[:upper:]]' '[[:lower:]]' | sort | fmt | sed 's/ //g')" for word in $( cat $testwords ) do # echo "checking $word for validity" simplified="$(echo $word | sed 's/./&\ /g' | tr '[[:upper:]]' '[[:lower:]]' | sort | fmt | sed 's/ //g')" ## PART THREE: do all letters of the word appear in the pattern # once and exactly once? Easy way: loop through and # remove each letter as used, then compare end states indx=1 failed=0 before=$pattern while [ $indx -lt ${#simplified} ] do ltr=${simplified:$indx:1} after=$(echo $before | sed "s/$ltr/-/") if [ $before = $after ] ; then # nothing changed, so we don't have that # letter available any more if [ $showfails ] ; then echo "FAILURE: came close, but can't make $word" fi failed=1 else before=$after fi indx=$(( $indx + 1 )) done if [ $failed -eq 0 ] ; then echo "SUCCESS: You can make the word $word" fi done /bin/rm -f $testwords exit 0