Memorizing numbers and enumerating possibilities

This post will illustrate two things: how to memorize numbers, and how to enumerate products of sets in Python.

Major system

There’s a way of memorizing numbers by converting digits to consonant sounds, then adding vowels to make memorable words. It’s called the “major” mnemonic system, though it’s not certain where the system or the name came from.

I learned the major system as a child, but never used it. I thought about it more recently when I ran across the article Harry Potter and the Mnemonic Major System by Kris Fris.

Here is the encoding system in the form of a Python dictionary, using IPA symbols for the consonant sounds.

    digit_encodings = {
        0: ['s', 'z'],
        1: ['t', 'd', 'ð', 'θ'],
        2: ['n', 'ŋ'],
        3: ['m'],
        4: ['r'],
        5: ['l'],
        6: ['ʤ', 'ʧ', 'ʃ', 'ʒ'],
        7: ['k', 'g'],
        8: ['f', 'v'],
        9: ['p', 'b']

The method is based on consonant sounds, not spelling. For example, the word “circle” would be a possible encoding of the number 0475. Note that the soft ‘c’ in circle encodes a 0 and the hard ‘c’ encodes a 7.

It’s curious that some digits have only one associated consonant sound, while others have up to four. The method was not originally designed for English, at least not modern English, and there may be some historical vestiges of other languages in the system. Even so, the sounds are fairly evenly spread out phonetically. It may not be optimal for English speakers, but some care went into designing it.

For more on the major system, see its Wikipedia page.

Enumerating set products

There are multiple consonant sound choices for a given digit, and so it would be natural to enumerate the possibilities when searching for a suitable encoding of a number.

If you only ever worked with two digit numbers, you could use a pair of for loops. But then if you wanted to work with three digit numbers, you’d need three nested for loops. For a fixed number of digits, this is messy, and for a variable number of digits it’s unworkable.

The function product from itertools gives an elegant solution. Pass in any number of iterable objects, and it will enumerate their Cartesian product.

    from itertools import product

    def enumerate_ipa(number):
        encodings = [digit_encodings[int(d)] for d in str(number)]
        for p in product(*encodings):

In the code above, encodings is a list of lists of phonetic symbols. Unfortunately product takes lists as its argument, not a list of lists. The * operator takes care of unpacking encodings into the form product wants.


Suppose you wanted to use the major system to memorize

1/π = .31830988

I’m not recommending that you memorize this number, or that you use the major system if you do want to memorize it, but let’s suppose that’s what you’d like to do.

You could break the digits into groups however you like, but here’s what you get if you divide them into 318, 309, and 88.

The digits in 318 could be encoded as mtf, mtv, mdf, mdv, mðf, mðv, mθf, or mθv.

The digits in 309 could be encoded as msp, msb, mzp, or mzb.

The digits in 88 could be encoded as ff, fv, vf, or vv.

So one possibility would be to encode 31830988 as “midwife mishap fife.” You could think of a pie that got turned upside down. It was the midwife’s mishap, knocked over while she was playing a fife.

Notice that the “w” sound in “midwife” doesn’t encode anything, nor does the “h” sound in “mishap.”

Related posts