In the previous post we tried to remember integer sequences using the lengths of words in a memorable phrase, though it turned out to be somewhat difficult to find memorable phrases with the right length words. Rather than encoding digits with word lengths, we can represent digits by particular letters, such as those used by the major system. The major system uses phonetic sounds rather than the actual letters, but for simplicity I'll use the actual letters here.
Here's a mapping of letters to digits:
(def letters->digit
{"s" 0
"c" 0
"z" 0
"x" 0
"t" 1
"d" 1
"th" 1
"n" 2
"m" 3
"r" 4
"l" 5
"ch" 6
"j" 6
"sh" 6
"k" 7
"g" 7
"f" 8
"v" 8
"p" 9
"b" 9})
All other letters and characters are ignored.
To encode text as digits, we can make a regular expression, prioritizing two-character encodings:
(def pattern
(->> (keys letters->digit)
(sort-by count >)
(str/join "|")
re-pattern))
Encoding, then, looks like this:
(defn major-encode [text]
(->> (str/lower-case text)
(re-seq pattern)
(map letters->digit)
(apply str)))
(major-encode "I wish I knew")
"672"
Because each word can encode more than one digit, we need to update our find-words
function from the previous post to accept the encoding function as an argument:
(defn find-words [encoder digits words]
(loop [words words
ds digits
match []]
(cond
(str/blank? ds) match
(empty? words) nil
:else (let [[word & words] words
c (encoder word)]
(cond
(str/starts-with? ds c)
, (recur words
(subs ds (count c))
(conj match word))
(seq match)
, (recur (concat (drop 1 match) [word] words)
digits
[])
:else
, (recur words digits []))))))
(find-words
major-encode
"672"
(words "Those are things I wish I knew more about."))
["I" "wish" "I" "knew"]
(defn match [encoder digits text]
(let [ws (words text)
ds (transduce (map encoder) str ws)
i (.indexOf ds digits)]
(when-not (neg? i)
i)))
And here are updates to match
and search-kjv
so they also take an encoder function:
(defn search-kjv [encoder digits]
(let [digits (str digits)]
(some (fn [{:keys [text] :as verse}]
(when (match encoder digits text)
(when-let [ws (find-words encoder digits (words text))]
[ws verse])))
kjv)))
(search-kjv major-encode 1414)
[["the" "earth" "were"] {:verse "Genesis 2:1", :text "Thus the heavens and the earth were finished, and all the host of them."}]
Here are the mnemonics this encoding finds for the digit sequences in the previous post:
Digits | Text | Verse |
---|---|---|
1414 | Thus the heavens and the earth were finished, and all the host of them. | Genesis 2:1 |
1732 | And he said unto him, Take me an heifer of three years old, and a she goat of three years old, and a ram of three years old, and a turtledove, and a young pigeon. | Genesis 15:9 |
2236 | And the Gentiles shall see thy righteousness, and all kings thy glory: and thou shalt be called by a new name, which the mouth of the Lord shall name. | Isaiah 62:2 |
2646 | Now Jericho was straitly shut up because of the children of Israel: none went out, and none came in. | Joshua 6:1 |
3183 | And Jephthah said unto the elders of Gilead, Did not ye hate me, and expel me out of my father’s house? and why are ye come unto me now when ye are in distress? | Judges 11:7 |
Interestingly, matches aren't as easy to find. When we encoded digits with word length we found four out of five matches in Genesis, while this letter-based major system only finds two in Genesis and one as late as Isaiah, more than halfway through the Bible. The tradeoff is that the matches are a bit shorter. Rather than requiring four words to match four digits, two of the matches encode four digits with three words and one encodes with only two words.
Of course, the mnemonics aren't much better than they were before. They're still arbitrary sentence fragments, though possibly "Now Jericho" stands on its own enough to remember a bit more easily. It's a tougher problem how to remember that "Now Jericho" encodes the square root of seven, but those familiar with the story in Joshua 6 may find a way.
In the next post we'll encode using the phonetic major system.