Skip to content

Instantly share code, notes, and snippets.

@karlwilcox
Created January 29, 2017 15:25
Show Gist options
  • Save karlwilcox/2a1b14f38fc3db315543f8c46251e0d7 to your computer and use it in GitHub Desktop.
Save karlwilcox/2a1b14f38fc3db315543f8c46251e0d7 to your computer and use it in GitHub Desktop.
Simple front end to grep and the dictionary word list to help in solving word based puzzles, for example, if you stuck on those in "The GCHQ Puzzle Book"
#!/bin/bash
# Various utilities to help with the GCHQ Puzzle Book...
wordlist="/usr/share/dict/british-english"
formatter="column"
# turn off filename globbing (we never need it)
set -f
if [[ $# -lt 2 ]]; then
cat<<ENDHELP
Usage: word [flags] command string...
Commands are:
starts - show all words starting with string
ends - show all words ending with string
contains - show all words that have string embedded
anagram - show all (partial) anagrams of string
surround - show all words that start with string1 and end with string2 (*)
prefix - show the remaining part of all words starting with string (*)
suffix - show the remaining part of all words ending with string (*)
search - treat string as an abitrary regular expression
(all commands may be abbreviated to their shortest unique length)
Flags are:
-w - ensure that output of the commands marked (*) are actually words
-1 - output results in a single column (for piping to other commands)
-p - don't include proper nouns in the results
-s - don't include possessives in the results
ENDHELP
exit 1
fi
while true; do
case "$1" in
-w) realWords=true; shift;;
-1) onePerLine=true; shift;;
-p) noProperNouns=true; shift;;
-s) noPossessives=true; shift;;
*) break;
esac
done
# This is where the work gets done...
case "$1" in
st*) result=$(grep "^$2" $wordlist);;
e*) result=$(grep "${2}\$" $wordlist);;
a*) len=${#2}; result=$(grep -E "^[$2]{$len}\$" $wordlist);;
c*) result=$(grep "..*$2.*." $wordlist);;
se*) result=$(grep -E "$2" $wordlist);;
sur*) result=$(grep "^$2..*${3}\$" $wordlist | sed -e "s/^$2//" -e "s/$3$//");;
suf*) result=$(grep "${2}\$" $wordlist | sed -e "s/${2}\$//");;
p*) result=$(grep "^$2" $wordlist | sed -e "s/^$2//");;
*) echo "Unknown command"; exit 2;;
esac
# And here is where the output is filtered and formatted
if [[ ! -z $noProperNouns ]]; then
filteredResult=""
for item in $result; do
if [[ ${item:0:1} =~ [a-z] ]] ; then
filteredResult="$filteredResult $item"
fi
done
result=$filteredResult
fi
if [[ ! -z $realWords ]]; then
filteredResult=""
for item in $result; do
if grep -q "^${item}\$" $wordlist ; then
filteredResult="$filteredResult $item"
fi
done
result=$filteredResult
fi
if [[ ! -z $noPossessives ]]; then
filteredResult=""
re="'s"
for item in $result; do
if [[ ! $item =~ $re ]] ; then
filteredResult="$filteredResult $item"
fi
done
result=$filteredResult
fi
if [ -z $onePerLine ]; then
echo $result | sed -e "s/ /\n/g" | $formatter
else
for item in $result; do
echo $item
done
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment