Rotonyms are words that ROT-13 in to other words. I discovered the term from this site, which I found during my morning Reddit session. I think the author invented the term, because the only reference I found to 'rotonym' came from his site. Long story short, I knocked out a Python script to find all the rotonyms, given a list of words (just for the heck of it). I like problems like this. Its like the kind of work you had to do in high school and uni, before you enter the real word of programming and discover that most problems have blurry definitions and its hard to tell if your solution actualy works in all cases. Here's the code, let me know if you have a better solution.

words = [line.rstrip() for line in open("WORD.LST")]
words_set = set(words)

letters = "abcdefghijklmnopqrstuvwxyz"
repl = dict(zip(letters, letters[13:]+letters[:13]))

def rot13(word):
    return "".join(repl.get(c, c) for c in word)

found = []

for word in words:
    rotword = rot13(word)
    if rotword in words_set:
        found.append( (word, rotword) )

found.sort( key=lambda words:(len(words[0]), words[0]) )
for word, rotword in found:
    print "%s\\t%s"%(word, rotword)

If you want to run it, you will need this word list. Its not the most interesting code you will see, but I was impressed at how much functionality Python squeezes in to each line, without making it too obfusticated. It would be interesting to see this solved in other languages for comparison.

Update: fs111 reminded me that there was a rot13 string encoding in Python. So the code becomes:

words = [line.rstrip() for line in open("WORD.LST")]
words_set = set(words)

found = []

for word in words:
    rotword = word.encode("rot13")
    if rotword in words_set:
        found.append( (word, rotword) )

found.sort( key=lambda words:(len(words[0]), words[0]) )
for word, rotword in found:
    print "%s\\t%s"%(word, rotword)
This blog post was posted to It's All Geek to Me on Tuesday January 22nd, 2008 at 3:40PM

11 Responses to "Rotonym, what the heck is a rotonym?"

  • fs111
    January 22nd, 2008, 5:46 p.m.

    Why that complicated?

    >>> w = "Hello"
    >>> print w.encode('rot13')

  • January 22nd, 2008, 6:07 p.m.

    Ack. I had forgotten there was a rot13 encoding!

  • Christian Glodt
    January 22nd, 2008, 7:15 p.m.

    Why so many loops and so many lines? :D

    >>> words = set([w.strip().decode('ascii', 'ignore') for w in file('/usr/share/dict/words')])
    >>> print [(w, w.encode('rot13')) for w in words if w.encode('rot13') in words]

    First line reads the dictionary while ignoring unicode encoding errors (unfortunately necessary on my Ubuntu system). Second line gets the rotonyms (I don't like the duplicated encode() call in that line).

    Favourite rotonyms from my dictionary:
    Robyn - Ebola
    sync - flap
    rail - envy
    one - bar
    Green - Terra

    In conclusion, I

  • January 22nd, 2008, 7:23 p.m.

    In conclusion you what?

    Neat, but I also removed equivalent pairs and sorted the output by length of word.

  • fa
    January 22nd, 2008, 9:01 p.m.
  • January 22nd, 2008, 10:10 p.m.

    I was thinking something similar to Christian.

    words = set([line.strip() for line in file('WORD.LST', 'r')])
    rotwords = set([word.encode('rot13') for word in words]) & words
    for word in sorted(rotwords, key=len, reverse=True):
    print word.encode('rot13'), word

    With sorted printing, and maximal work done by native code.

  • January 22nd, 2008, 10:30 p.m.

    It should be noted that it is only necessary to run half of the word list (A-M).
    I like how Corey sorted by length, it does well to push the one and two letter matches down.

    "I think the author invented the term, because the only reference I found to ‘rotonym’ came from his site."

    I think I did, also; likely (found and named them) out of the same drive for interesting exercises that motivated you to code your own script to find them.

  • Christian Glodt
    January 22nd, 2008, 11:54 p.m.

    I wrote "In conclusion, I <3 (heart) list comprehensions!", but the everything after the < didn't show up because WordPress took it for the beginning of an HTML tag. Sorry about that.

    It is nice, every once in a while, to cram as much functionality as possible into the fewest lines of code imaginable.

  • January 23rd, 2008, 11:49 a.m.

    An implementation in Haskell:

  • January 24th, 2008, 6:10 a.m.

    Something similar to Corey and Christian's solutions. The list of words could be a frozen set, because we don't have to mutate it. The 2nd list of rot13 words need not be a set, since we we just iterate over it. This is 2 or 3 lines long, depending on how you look at it :)

    s = frozenset(x.strip() for x in open('WORD.LST','r'))
    for w, rw in sorted([(x,x.encode('rot13')) for x in s if x.encode('rot13') in s],key=len,reverse=True) : print '%s : %s'%(w.ljust(20),rw)

  • January 24th, 2008, 9:16 p.m.

    Jeethu, the change to frozenset is superfluous in this case, it doesn't gain anything. However, all you've managed to do is add back the python-land conditional that Christian's example employed. Using the set intersection (&) to sort out which ROTs are words is much more efficient.

Leave a Comment

You can use bbcode in the comment: e.g. [b]This is bold[/b], [url][/url], [code python]import this[/code]
Preview Posting...
Previewing comment, please wait a moment...

My Tweets

Will McGugan

My name is Will McGugan. I am an unabashed geek, an author, a hacker and a Python expert – amongst other things!

Search for Posts
Possibly related posts
Popular Tags
Recent Comments
def thousands_with_commas(number): new_number = [] number = str(number) mod_value = len(number) % 3 counter = 3 if len(number) 4: return ...
don't know why this was tempting.. (#1)import re from collections import Counter, OrderedDict cnt=Counter() with open(./t) as f: #--- strip ...
- Mike on Python Coder Test
Hello! I've seen this test and tried to do them. Result added bellow. First path: def thousands_with_commas(i): i = str(i) ...
Why another framework? what wrong with django, pyramid, flask?will be have answer for this question in the docs)
Hi! Really great code, good work! But trying to use it on a responsive site, it didn't resize images. So, ...
© 2008 Will McGugan.

A technoblog blog, design by Will McGugan