Skip to main content

Robber language generator

· 11 min read
Filip Tammergård
Software Engineer at Frilans Finans

Robber language (Swedish: rövarspråket) is said to have been invented by Sture Lindgren — husband of the author Astrid Lindgren — when he played with his friends as a child. Astrid Lindgren's books about Kalle Blomkvist made the language popular in Sweden.

Robber language is a spoken code where every consonant is replaced by the consonant + "o" + the consonant again. From that simple rule, building a robber language generator should be dead easy. When it comes to written robber language, however, there are a few more aspects to consider. So this post is really about a written robber language generator.

note

Robber language was designed for Swedish and doesn't translate cleanly to English. Swedish has a clean consonant/vowel split — the letter "y" is a vowel, and "x" is always pronounced "ks" — which is what makes the rule "consonant + o + consonant" work consistently. English is messier: "y" flips between consonant and vowel ("yes" vs "happy"), "x" can sound like "ks" ("ax") or "z" ("xylophone"), and digraphs like "sh", "ch" and "th" represent single sounds that the letter-by-letter rule splits apart.

Spoken English actually works fine if you treat a consonant as a consonant sound rather than a letter — "ship" then becomes one consonant sound + vowel + consonant sound, not s-h-i-p. By sound, "ship" translates to "shoshipop"; a letter-by-letter generator would instead spit out "soshohipop", which doesn't match how the word is pronounced. Doing it by sound puts the burden on the speaker to do the phonetic analysis on the fly, and writing a generator for it would mean shipping a pronunciation dictionary or grapheme-to-phoneme model rather than the simple letter-by-letter substitution this post is about. So the Swedish examples are the ones that actually sound right when spoken — though even Swedish isn't perfectly clean: digraphs like "sj", "sch" and "tj" are single sounds that the letter-by-letter rule splits apart, just accepted by convention rather than worked around.

TL;DR

  • The simple spoken rule (consonant + "o" + consonant) needs a few additions to work in writing — mainly handling "x" and uppercase.
  • This post walks through two strategies for building a generator in JavaScript: looping over the consonants, and looping over the text to translate.
  • A regex with a callback can collapse the whole thing into two lines, shown as the final alternative.

Calendar maths

· 14 min read
Filip Tammergård
Software Engineer at Frilans Finans

You might think week numbers are dead simple. Surely you just start at week 1 and go up to week 52, then start over? Unfortunately it's not that easy. It turns out to be surprisingly complicated!

note

This article describes week numbering according to ISO 8601, which Sweden and most European countries follow. Other conventions exist — the United States, for example, uses Sunday as the first day of the week and treats week 1 as the week containing January 1 — so the model looks different there. The "53-week year" phenomenon explored below is specific to ISO 8601: ISO requires full seven-day weeks, while the US convention simply truncates the first and last weeks of the year to fit.

TL;DR

  • Most years have 52 weeks, but some have 53.
  • Whether a year has 53 weeks depends on what day of the week January 1 of the following year falls on, and whether the current year is a leap year.
  • Leap years occur slightly less than every four years on average, which makes the model for when 53 weeks appear tricky.

Sum numbers in an array with JavaScript

· 6 min read
Filip Tammergård
Software Engineer at Frilans Finans

There are several ways to compute the sum of numbers in an array with JavaScript. The approaches differ mainly in how readable they are — and readable code is easier to maintain and easier for others to understand and build on.

TL;DR

  • There are many ways to sum numbers in an array, but several of them are hard to read and unnecessarily complicated.
  • The best way is using the built-in reduce function — or the newer Math.sumPrecise if you can rely on it being available.