Friday Fun: PowerShell Anagrams

Maybe it’s my liberal arts background but I love words and word games. I have a constant pile of crosswords and enjoy tormenting my kids (and wife) with puns.  I am also fascinated with word hacks like palindromes and anagrams. An anagram is where you take a word like ‘pot’ and rearrange the letters to spell another word like ‘opt’ or ‘top’.  Short words are easy to do in your head.  So I thought why not get PowerShell to do some of the letter crunching for me.

Remember, the purpose of these articles is not the end result but the process and the techniques.  Let’s start with a word.

I know that this word should match some of the words in this list.

In an anagram, it has the same letters as the source word, just in a different order. So I figured I could turn the source word into a character array and compare the array of potential targets. I went through a number of experiments but finally settled on this.

In essence I’ve take the letters in the word, ‘angle’, sorted them, then rejoined into a single string, ‘aegln’. If it helps, you could think of this as a type of hash. Now, I can go through each word in my potential list,  perform the same type of hashing operation and compare.

If you try this you should get the expected results.  But the whole point is to discover anagrams for a given word. And for that I need a big list of words.

I found one at from https://github.com/dwyl/english-words that has over 466K entries. I downloaded a copy to my Scripts folder. Given the size, I figured it would be easier to test my process on a subset of words.

This gave me 3 anagrams in just under 15 seconds. Then I realized, it doesn’t make any sense to compare any words from the list that don’t have the same number of characters.

That took 2.5 seconds! Let’s try the whole word list.

That took about 21 seconds.

image

By the way, I also tested with getting the word list first and then piping that to Where-Object.

This was not any faster. It took over 9 seconds to read in the 466K words and then almost 2 minutes to filter.

Now that I have settled on some core code, let’s wrap it up in a function.

The function is a gist on my GitHub repo and defines a function called Get-Anagram. You will need a word list. I’ve set a default value for mine.

Usage, is pretty simple. Specify a word and a word list. My function will write a custom object to the pipeline with a property of all the anagrams. Here are a few examples of the function in action.

image

Yeah, I don’t expect you to have an urgent business need to find an anagram for ‘danger’ (‘ranged’ in case you were curious) but you might need to process a large log file, understand filtering or get an example of how to write a function.

Or maybe you just want to have a little fun. Enjoy!

Leave a Reply

Your email address will not be published. Required fields are marked *