You might have heard of palindromic sentences. You can read the letters in these sentences forwards of backwards, and they’ll still form the same words. Try reading these sentences backwards:
Live not on evil. Race fast, safe car! Never odd or even.
But there is another word play that is even more impressive: a magic word square. This one was very famous in ancient roman times:
It’s the latin expression
sator arepo tenet opera rotas. What’s amazing about this square is that you can can read its words top-to-bottom, and also bottom-to-top, left-to-right and right-to-left:
That’s the ultimate palindromic wordplay. Ancient Romans were so amazed by this, that they often wrote this word-grid into houses, temples, monuments, drinking vessels. Many believed the perfectly symmetric grid had the power to repel bad spirits and bring good luck.
It probably must have taken Romans either a strike of luck, or an incredible amount of work to discover such a square of latin words. After discovering its existence, I kept asking myself if such a perfect 5×5 square of English words existed.
With computers, finding one should be a trivial task. So I wrote a little Python program to do it. Here’s how it works.
First, we need to get all the English words with five letters. That’s an easy task, using a free wordlist from the internet:
import urllib.request src = "http://raw.githubusercontent.com" src += "/codenrg/sator-square/master/words-en.txt" fp = urllib.request.urlopen(src) words = [str(line, 'utf-8').rstrip() for line in fp]
words is a list with all words in the English language. A magic square can only be assembled with words of 5 characters, so let’s filter our words:
words = filter(lambda x: len(x) == 5, words)
A word can only fit in the square if it’s backwards read is also in the square. For instance, the word
stop is a candidate, because the word
pots is also a valid word in English, whereas the word
coder isn’t, because
redoc doesn’t exist in the English language.
To filter words that don’t have a valid reverse, let’s put our words in a set, and check if every word’s reverse is in it.
words = set(words) rev = lambda w: "".join(reversed(list(w))) words = [w for w in words if rev(w) in words]
Now all we need to do is to try to assemble a perfect square using the viable words:
squares =  for w1 in words: w2_match = lambda x: x == w1 and x[-1] == w1[-2] for w2 in filter(w2_match, words): w3_match = lambda x: x == w1 and x == w2 for w3 in filter(w3_match, words): if w3 == rev(w3): square = [w1, w2, w3, rev(w2), rev(w1)] squares.append(square) for x in squares: print("%s\n%s\n%s\n%s\n%s\n\n" % tuple(x))
Can you tell the complexity order of this code? If you don’t know what I’m taking about, you should definitively see my book Computer Science Distilled. It’s a slim intro to computer science that includes many basic principles every programmer should know. Check it out!
With the wordlist fetched from here, I was able to find 3 magic squares! This is the coolest one:
P A R T S A P A R T R A D A R T R A P A S T R A P
Can you find magic squares in other languages? Would you like to propose improvements to the code? Send me a pull request on Github: https://github.com/codenrg/sator-square.
EDIT: Thanks to Bak Yeon O for creating a Korean translation of this article.