Rotating Letters
Svaqvat gur ybatrfg jbeq jura ebg13'q vf nyfb n jbeq.

Table of Contents

Idea

When viewing Greg Egan's twitter he mentioned words that were the Rot-13 of each other and.

Now I have a much more comprehensive list of words (obtained when looking for long wordlists for XKCD style password generation) so I think I could solve this problem, create new problems, and look at various fun patterns in English words using programming. To do this I will use Clojure.

What Do I Mean By "Rotating Letters"?

When I say "rotating words" I simply mean.

If you are used to modular arithmetic you could imagine it as simply adding 13 to each letter.

A Digression on XOR Ciphers

Another interesting way to do this with actual encryption is the XOR cipher with a key. The rot-13 system is also in essence XOR though without any key.

The rot-n Function

This shifts a word n letter to the right (or left) through modular addition and subtraction.

(defn rot-n
  "Rotate or shift a word `n` letters."
  [word shift]
  (->> word
       (map (fn [character]
              (let [lowercase-offset (int \a)
                    char-num         (- (int character) lowercase-offset)
                    english-chars    (inc (- (int \z) (int \a)))]
                (char (+ lowercase-offset (mod (+ char-num shift) english-chars))))))
       str/join))

English Words

Rot 13

Rot-13 is a classic example of english.

(ns rot-13
  (:require [clojure.string :as str]))
<<rot-n>>

;; Load the words into a set
(let [words    (-> "words_alpha.txt" slurp str/lower-case str/split-lines)
      word-set (set words)]
  (->> words
       (filter (fn [word]
                 (let [rot-word (rot-n word 13)]
                   (contains? word-set rot-word))))
       (sort #(> (count %1) (count %2)))))

So we get two pairs, for a total four answers, which I will call pair g and pair c. The first was found by Greg Egan, here, while the second was found by me, while running my program.

pair g pair c
abjurer chechen
nowhere purpura

This is fun, though not terribly interesting, to try to make it fun I will genralize it.

Generalized Rotation

Rot 13 is a rather elegant because it, as mentioned before, allows you to return to the original value rather quickly. But now we may begin to wonder what we were evaluating there.

What if we allowed for other values like rot-2 or rot-5? What would that look like?

Rot Cycles

26 13 26/3 13/2 26/5 13/3 26/7 13/4 26/9 13/5 26/11 13/6

So we are left rather sadly with this series of patterns.

So what do we get? Well sadly not much. I ran the code below and only two-letter words were found, mostly acronyms and other similar things.

(ns rot-4
  (:require [clojure.string :as str]))

<<rot-n>>

(defn rot-cycle?
  "Check if there is a rotation cycle.

  Orig is the original word (used to evaluate the cycle), word is the
  last word, shift is the rotation applied, and words is a set of all
  words being evaluated."
  [shift words orig word]
  (let [rot-word (rot-n word shift)]
    (cond (= rot-word orig)                true
          (not (contains? words rot-word)) false
          :else                            (rot-cycle? shift words orig rot-word))))
(def word-set (-> "words_alpha.txt" slurp str/lower-case str/split-lines set))

;; Load the words into a set
(let [words    (-> "words_alpha.txt" slurp str/lower-case str/split-lines)
      word-set (set words)]
  (->> words
       (filter (fn [word]
                 (rot-cycle? 13 word-set word word)))
       (sort #(> (count %1) (count %2)))))

Last Modified: 2021-W48-3 17:56

Generated Using: Emacs 27.2 (Org mode 9.4.6)

Except where otherwise noted content on cons.dev is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.