This question is the inverse of this one by James Williams.


Rövarspråket is a word game played by Swedish children, from the books about Kalle Blomkvist by Astrid Lindgren.

The basic rules used during encoding are as follows (from Wikipedia):

  • Every consonant (spelling matters, not pronunciation) was doubled, and an o was inserted in-between.
  • Vowels were left intact.

A few examples of decoding:

  • "hohelollolo" -> "hello"
  • "MoMinon sosvovävovarore äror fofulollol momedod ålol" -> "Min svävare är full med ål"

Swedish consonants are the same as the English ones, so the program should work with both Swedish and English entries.

The letter "y" is taken as a consonant in this case - as most of the time it is.

Your Task:

Write a program to convert a Rövarspråket string of Swedish letters, inputted through a function or through stdin, into its decoded equivalent. Shortest answer in bytes wins!

  • \$\begingroup\$ Are uppercase letters treated the same way as their lowercase counterparts? e.g. does HOHELOLLOLO become HELLO? \$\endgroup\$ – Sp3000 Mar 24 '15 at 23:12
  • 1
    \$\begingroup\$ In the case of a function, should results be returned, printed to stdout/closest alternative, or either? \$\endgroup\$ – Alex A. Mar 24 '15 at 23:12
  • \$\begingroup\$ @AlexA. I think any of those are fine. \$\endgroup\$ – orlp Mar 24 '15 at 23:16
  • \$\begingroup\$ @MartinBüttner Oops, no, caught me. It should indeed be HoHELoLLoLO. \$\endgroup\$ – orlp Mar 24 '15 at 23:35
  • \$\begingroup\$ @Sp3000 Sorry, I was mistaken, the os in the middle must be lowercase. So HOHELOLLOLO is not a valid input. If the input is invalid your program is allowed to do whatever, it will only be tested for valid inputs. \$\endgroup\$ – orlp Mar 24 '15 at 23:36

12 Answers 12


Retina, 19 + 2 = 21 bytes

Retina strikes again! The code for this program consists of two files:


This reads the input on STDIN and prints the output to STDOUT.

If you call the files pattern.rgx and replacement.rpl, you can run the program simply like

echo "hohelollolo" | ./Retina pattern.rgx replacement.rpl


As for the previous answer, if Retina is invoked with 2 files it is automatically assumed to operate in "Replace mode", where the first file is the regex and the second file is the pattern.

Retina can be configured (which includes RegexOptions and other options) by prepending the regex with ` and a configuration string. In this case I'm only giving it i which is the normal regex modifier for case insensitivity.

The pattern itself is a bit more interesting this time. It still uses .NET's character class subtraction to match any consonant in the ASCII range, but then it also matches the following o as well as the character after it (i.e. the copy of the consonant). The replacement then just writes the captured consonant back.

You might be wondering why this is not ambiguous in a case like lololol -> lol. The trick is that matches cannot overlap and are always found from left-to-right. So whenever I encounter a consonant, I include the next two character in the match and replace all of them - the search continues after this. It's quite easy to convince yourself that this kind of greedy algorithm will always decode the input correctly. In fact the pattern could even have been


Julia, 61 43 bytes


This creates an anonymous function which accepts a string as input and returns the inverse Rövarspråket transformation of the string. It's the exact inverse of my Julia answer to the Rövarspråket challenge. To call it, give it a name, e.g. f=t->....

The replace() function is doing all of the work here. The first argument is the input string, the second is a regular expression pattern (which in Julia is given as a string preceded by r), and the third is the replacement.

For the regex, we're matching all pairs of consonants separated by an "o". For the replacement, we're taking the match and extracting only the first character, which is the consonant.


julia> f("hohelollolo")

julia> f("MoMinon sosvovävovarore äror fofulollol momedod ålol")
"Min svävare är full med ål"

Questions? Just let me know. Suggestions? Very welcome as always!

Edit: Saved 18 bytes thanks to Martin Büttner!

  • 1
    \$\begingroup\$ @MartinBüttner: Has anyone told you recently that you're awesome? \$\endgroup\$ – Alex A. Mar 24 '15 at 23:41
  • 2
    \$\begingroup\$ I've read something on meta. ;) (And +1 for using Julia!) \$\endgroup\$ – Martin Ender Mar 24 '15 at 23:45
  • 1
    \$\begingroup\$ Btw, you can save two more bytes by mimicking character class subtraction with a lookahead: (?![eiou])[b-z]o. (I think this also goes for a lot of answers on the original challenge.) \$\endgroup\$ – Martin Ender Mar 24 '15 at 23:49
  • \$\begingroup\$ @MartinBüttner: I think meta did a good job of getting the point across. :) And thanks for the support! I've been using Julia for a couple years and I try to use it around PPCG whenever I can. It's a good way to learn new things. Also, thanks once again!! \$\endgroup\$ – Alex A. Mar 24 '15 at 23:51

Sed, 13, 15, 16, 28


Run it like this:

echo MoMinon sosvovävovarore äror fofulollol momedod ålol | sed 's/\([^äöåaeiou]\)o\1/\1/g'


Min svävare är full med ål
  • \$\begingroup\$ I would consider -r part of the bytecount, just like a Python solution has to count re.sub. \$\endgroup\$ – orlp Mar 25 '15 at 14:41
  • \$\begingroup\$ Your solution fails for ooo, which incorrectly gets decoded to o. It should stay ooo. \$\endgroup\$ – orlp Mar 25 '15 at 15:13
  • \$\begingroup\$ @Thor: No Swedish words have to contain "ooo" for "o" to be invalid output because the Rövarspråket-transformed words aren't constrained to be actual Swedish words. \$\endgroup\$ – Alex A. Mar 25 '15 at 18:46
  • \$\begingroup\$ orlp and AlexA: You are correct, I will use a non-vowel group instead. \$\endgroup\$ – Thor Mar 25 '15 at 19:55

Java, 47

Use as a lambda function. Works the exact same way as Martin's answer.


Try here


Pyth, 27


JavaScript (ES6), 46

This turns out to be some language-specific sintax around a regexp. ES6 is quite short. Too bad we miss subtraction


Mathematica, 36 bytes

Roughly uses the strategy in my previous answer.



  • "o"|"O" matches the lettter O insensitively.
  • a_~~*..*~~a_:>a matches any character a followed by an O followed by a again, and replaces it with a.
  • Finally, StringReplace[#,*..*]& creates a pure function applying that rule to every matching sequence in its argument.

Python, 61

The inverse is conveniently is the same length as the original.

import re;g=lambda s:re.sub('(?i)(?![eiou])([b-z])o.',r'\1',s)

Or alternatively:

import re;g=lambda s:re.sub('(?i)(?![eiou])([b-z])o.','\\1',s)

Run it here: http://repl.it/f3N


JavaScript ES6, 108 bytes

  return n

To make this interesting, I tried to do this entirely without regular expressions, which is why it is so long. It works by iterating over the string, copying each letter over to a new string. If it encounters a consonant, it skips the next two letters, which would be o + that letter. Use the snippet for a GUI alert and ES5.

return n}

alert(F('hohelollolo')+'\n'+F('MoMinon sosvovävovarore äror fofulollol momedod ålol'))


JavaScript 65

function R(x){return x.replace(/([bcdfghj-np-tv-z])o\1/gi, "$1")}

PHP - 65 66

$s=$argv[1];echo preg_replace("/([^aeiou])o([^aeiou])/i","$1",$s);
  • \$\begingroup\$ I don't think this is going to work correctly with ä, ö and å or upper case vowels. \$\endgroup\$ – Martin Ender Mar 25 '15 at 16:04
  • \$\begingroup\$ It works for upper case, But yes not for other characters you mentions. It strictly for english only alphabets. \$\endgroup\$ – kuldeep.kamboj Mar 26 '15 at 6:36
  • 1
    \$\begingroup\$ @MartinBüttner, You comment is correct. I copied another version do not have case insensitive (/i) modifier. However my code is still run on local with out this modifier for some unknown reasons. Still i added a "i". One more byte. \$\endgroup\$ – kuldeep.kamboj Mar 26 '15 at 10:29

QuadR, 15 bytes


Try it online!

PCRE Replace…

([^aeiou])o. non-vowel (and call this the first capturing group), "o", any character


\1 the first capturing group


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.