# Convert a string to its Rövarspråket equivalent

## Rövarspråket

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

The basic rules are as follows (from Wikipedia):

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

A few examples:

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

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 string of Swedish letters, inputted through a function or through stdin, into its Rövarspråket equivalent. Shortest answer in bytes wins!

• @MartinBüttner Clarified my question further - it should work with Swedish (as it is a Swedish word-game). Mar 24 '15 at 18:14
• What is the meaning of alphabetical entries ? Mar 24 '15 at 18:15
• @Optimizer A string of only alphabetical characters. Sorry, I worded it badly, I'll edit Mar 24 '15 at 18:15
• How should we treat non letters? At least spaces show up in the second example.
– nimi
Mar 24 '15 at 19:28
• On a side note: 'Y' is considered a vowel in Swedish
– leo
Mar 26 '15 at 12:18

# Retina, 14 + 5 = 19 bytes

Retina is a language that is essentially just .NET regex with as little overhead as possible. The code for this program consists of two files:

i[b-z-[eiou]]

$0o$0


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 "hello" | ./Retina pattern.rgx replacement.rpl


## Explanation

This is pretty straightforward, but let me add some explanation anyway (mostly about how Retina works). 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.

As for the regex itself, it uses .NET's character class subtraction to match any consonant in the ASCII range. The replacement then just writes the match back twice with an o in between.

• Are you missing an a in your vowel character class? Mar 25 '15 at 19:22
• @BrianGordon No, I'm starting the character class from b, so I don't need to subtract a. Mar 25 '15 at 19:27
• Interesting, I've never seen nested, subtractive character ranges before. Is that just a .NET thing? Apr 20 '15 at 9:18
• I feel like you need to count at least one character for the delimiting between the two files. that would be a semicolon or newline in another language. it's the space between the filenames if you want to get picky about where the character comes from in this language. May 20 '15 at 3:41
• @Sparr yes, that's the policy now, but that policy is newer than this challenge/answer. For reference (In fact, if you look at the time stamps, you can see that I pushed for the policy because of this answer, but applying rules like that throughout the site retroactively doesn't make much sense.) May 20 '15 at 12:23

Using Unix KSH 27 28 32 27 bytes (or 21 if we only count inside sed command)

Thanks to the suggestions of others :) Appreciated.

.. I got down to this:

sed 's/[^AEIOUÅÄÖ ]/&o&/ig'


(allowed for spaces and Swedish characters)

echo "hello" | sed 's/[BCDFGHJ-NP-TV-Z]/&o&/ig'
hohelollolo
echo "HELLO" | sed 's/[BCDFGHJ-NP-TV-Z]/&o&/ig'
HoHELoLLoLO
echo "QuIcKlY Now" | sed 's/[BCDFGHJ-NP-TV-Z]/&o&/ig'
QoQuIcocKoKlolYoY NoNowow

• Also, I think it is allowable to claim your answer is a sed program, and just count the bytes between the single quotes Mar 24 '15 at 19:21
• s/[^AEIOU]/&o&/ig seems to work.. for single words at least... you'll need to exclude spaces as well Mar 24 '15 at 19:23
• bash, though the shell shouldn't matter, so long as your sed program is in single quotes Mar 24 '15 at 19:30
• Also watch out for the swedish vowels ö, å, etc - these need excluding too. Might be better to use a whitelist of just the consonants s/[BCDFGHJ-NP-TV-Z]/&o&/ig Mar 24 '15 at 19:32
• I would make it 'sed' and use "s/[^AEIOUÅÄÖ ]/&o&/ig", which covers Swedish vowels and spaces for 25 bytes. Mar 24 '15 at 22:34

# CJam, 32 30 bytes

q{_eu'[,66>"EIOU"-#)g{'o1$}*}/  This is a full program reading from STDIN and printing to STDOUT. It works for arbitrary Unicode input and treats the following 42 characters as consonants: BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz  Test it here. ## Explanation q "Slurp STDIN."; { }/ "For each character..."; _eu "Duplicate and convert to upper case."; '[,66> "Get a string from B to Z using range and slice."; "EIOU"- "Remove the remaining four vowels."; # "Find the position of the character in this string or -1 if the character can't be found."; )g "Increment, take signum, which gives 1 for consonants, and 0 otherwise."; { }* "Repeat this block that many times, i.e. do nothing for non-consonants."; 'o "Push an 'o'."; 1$     "Copy the current character.";


# JavaScript, 59575544 bytes

s=>s.replace(/(?![eiou])[b-z]/gi,"$&o$&")


Thanks to Masterzagh for reminding me that a function would be acceptable as well, and for his regex tip regarding backreferences without capturing!

Longer version with input/output:

alert(prompt().replace(/(?![eiou])[b-z]/gi,"$&o$&"));


Displays a prompt box to enter the string, then shows a dialog containing the Rövarspråket output. The code uses a regex to double the consonants and insert os.

• "Write a program to convert a string of Swedish letters, inputted through a function or through stdin", You can make it s=>alert(s.replace(/(?![eiou])([b-z])/gi,"$1o$1"));
– user64039
Jan 12 '17 at 15:09
• And since it wasn't asked to output, you don't need the alert either.
– user64039
Jan 12 '17 at 15:16
• One more thing, you can backreference without capturing. Basically do s=>s.replace(/(?![eiou])[b-z]/gi,"$&o$&"), since $& means current match you can remove the parenthesis that capture your letter and while you're at it save another byte by removing the semicolon at the end. – user64039 Jan 12 '17 at 15:40 • @Masterzagh That's cool, thanks again! Jan 12 '17 at 16:13 # Mathematica, 8473 72 bytes StringReplace[#,a:RegularExpression@"(?i)[BCDFGHJ-NP-TV-Z]":>a<>"o"<>a]&  Explanation: • RegularExpression@"(?i)[BCDFGHJ-NP-TV-Z]" is a regex matching all consonants case-insensitively. • a:*..*:>a<>"o"<>a creates a delayed rule to bind those consonants to a, and replace it with and o surrounded by itself. • Finally, StringReplace[#,*..*]& creates a pure function applying that rule to every matching letter in its argument. • @MartinBüttner Thanks! Still new to Mathematica golfing... Mar 24 '15 at 23:17 • @MartinBüttner Was going to do that anyways but got distracted by some notifications :P Mar 24 '15 at 23:25 # Julia, 46 44 bytes t->replace(t,r"(?![eiou])[b-z]"i,s->s*"o"*s)  This creates an anonymous function that takes a single string input and prints the Rövarspråket equivalent. To call it, give it a name, e.g. f=t->.... Not much has really been golfed here, other than spaces after the commas in replace(). Here we're using 3 arguments in the replace() function: the input string, the regular expression for identifying substrings, and a replacement. Julia denotes regular expression patterns by r"...". Adding i to the end makes it case insensitive. This particular regex matches consonants. If a function is used for the replacement, the output is that function applied to each matched substring. The function we're using here takes a string s and returns sos, since * performs string concatenation in Julia. Thus the end result is the input string with each consonant doubled with an "o" between. Examples: julia> f("Min svävare är full med ål") "MoMinon sosvovävovarore äror fofulollol momedod ålol" julia> f("hello") "hohelollolo" julia> f("Rövarspråket") "RoRövovarorsospoproråkoketot"  Note that this will be 9 bytes longer if we have to print the result rather than return it. Awaiting confirmation from the OP. Edit: Saved 2 bytes thanks to Martin Büttner! # Haskell, 81 bytes x n|elem n"bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ"=[n,'o',n]|1<2=[n] f=(>>=x)  Usage: f "Hello there!" -> "HoHelollolo tothoherore!". I cannot cleverly construct the list of consonants without expensive imports. Even turning the letter to check to lowercase needs more bytes than simply listing both upper and lowercase consonants. # Java 8, 45 Use as a lambda function. Uses regular expression. a->a.replaceAll("(?i)[b-z&&[^eiou]]","$0o$0")  Try here • "Write a program to..." This looks more like a function to me. Feb 13 '20 at 20:06 # Perl, 33 Bytes This answer is mostly regex-only, with a small amount of extra code to perform I/O. $_=<>;s/[^aeiou\W]/$&o$&/gi;print


It's been a while since I've used Perl regexes, so this can probably be improved.

$_=<>; This takes input from STDIN <> and stores it into the default variable$_
s/          /     /gi;        This is a case-(i)nsentive, (g)lobal,
(s)ubstitution regex.  Since no other
variable is specified, it is applied to
the default variable $_. [^aeiou\W] This matches any single character that is a consonant, by using a double- negative ^\W to match only alphanumeric characters excluding vowels. Accented vowels are not considered alphanumeric by Perl.$&o$& This forms the replacement.$& contains the
match (the consonant), so this replaces each
consonant with two copies of itself with
an 'o' in between.
print   This prints the result.  With no arguments,
it prints $_ by default.  • Won't [^aeiou] still match å and other non-ASCII vowels? Mar 25 '15 at 0:40 • @AlexA. I already noticed the problem. It was a zero-character fix (\s to \W). Mar 25 '15 at 0:51 • +1, most thorough explanation for Perl code I have seen on this site. Mar 25 '15 at 8:49 # Python, 61 I couldn't get a character class union or subtraction to work, and so I don't think Python has that feature. I had to use a negative lookahead instead. import re;f=lambda s:re.sub('(?i)(?![eiou])([b-z])',r'\1o\1',s)  Run it here: http://repl.it/fQ5 Link to the inverse: https://codegolf.stackexchange.com/a/48182/34718 ## Windows Batch, 235 bytes @echo off setlocal enabledelayedexpansion set d=qwrtypsdfghjklzxcvbnm set #=%1 :x if defined # ( for /l %%i in (0,1,20)do ( set m=!d:~%%i,1! if /i !m!==%#:~0,1% set g=!g!!m!o) set g=!g!%#:~0,1% set #=%#:~1% goto x) echo %g%  Usage: script.bat hello  Output: hohelollolo  You might be wondering why I didnt set d to "aoui", checking for not-equals requires breaking out of a loop. Not everything that should work, does work, in batch. The script handles 1 word of characters [as they appear on your keyboard]. All spaces and newlines that are still present are required for the script to run. Windows XP or higher, required. Not tested in Windows 8 and above. ## PowerShell - 35 bytes Just to show that PowerShell can compete in these sometimes too, and with the regex shamelessly stolen from Martin Büttner's Retina answer: %{$_-replace'[b-z-[eiou]]','$0o$0'}


accepts string input from stdin

# 05AB1E, 1615 13 bytes

-2 bytes thanks to Kevin Cruijssen

žNDu«SD'o«€Ć‡


Try it online!

• .š can be u (to uppercase) to save a byte. And nice answer! Feb 13 '20 at 14:13
• I just had the feeling 13 bytes was possible.. Took me a bit to find it, though: žNDu«SD'o«€Ć‡ Feb 13 '20 at 14:23
• haha, I was searching for "capital" instead of upper, thanks for the improvements @KevinCruijssen Feb 13 '20 at 16:26

# C 107

Thanks to @ceilingcat for some very nice pieces of golfing - now even shorter

x;main(c){for(;read(0,&c,1);printf("%s%s%s",&c,x+"o",x?"":&c))x=c<66|c>122|c>90&c<98||index("EIOUeiou",c);}


Try it online!

• How does the local variable c get declared?
– wjl
Mar 25 '15 at 21:20
• @wjl global variables in C are zero initialized. Local variables are on the stack and are not initialized. See stackoverflow.com/questions/3553559/… Variables with out a type default to int and since printf works on chars the code might have endian issues - I will check tomorrow. Mar 26 '15 at 11:31
• Yes, I understand default initialization. I was just trying to nicely point out that this code does not compile since c isn't declared at all, e.g. out.c:2:18: error: ‘c’ undeclared (first use in this function).
– wjl
Mar 26 '15 at 15:40
• @wjl I guess it depends on the compiler. It compiles and runs at ideone.com ideone.com/s7M5mZ when you choose C - any idea what the difference is? Mar 26 '15 at 18:38
• Looks like a bug with ideone's compiler. If you fix the newline between c[2];main (necessary because #define doesn't end at a semicolon) it gives similar errors to GCC. Anyway, no big deal, it's still a fun code-golf, but you might actually need a few more characters to make this valid C. =)
– wjl
Mar 26 '15 at 20:06

# Pyth - 28 bytes

This is works in the obvious way by generating the consonants list on the fly using set-wise difference.

FNzpk+N?+\oN}rNZ-{G{"aeiou"k


Explanation coming soon.

• You can save 4 bits by removing 4 chars and replacing one char with another one. Mar 24 '15 at 19:12

# Clip 10, 30

gx"((?i)[b-z&&[^eiou]])""$1o$1


Basic regex substitution.

# Pyth, 2524 23

sm+d*+\od}rd0-G"aeoui"z


Run it here.

• One char of your solution is redundant. Mar 24 '15 at 21:42

# K, 38 chars

f:{,/(1+2*~(_x)in"aeiouåäö ")#'x,'"o"}

-1 f"Min svävare är full med ål";
MoMinon sosvovävovarore äror fofulollol momedod ålol


# K, 31 bytes

,/{(x,"o",x;x)9>" aeiouåäö"?x}'


A straightforward solution seems fairly competitive given that K lacks regexes. Select between the "XoX" form and "X" form based on whether each character was found in a lookup table of ignored vowels and join the resulting lists.

You can try it in your browser using oK:

http://johnearnest.github.io/ok/index.html?run=%20%2C%2F%7B(x%2C%22o%22%2Cx%3Bx)9%3E%22%20aeiouåäö%22%3Fx%7D'%22Min%20svävare%20är%20full%20med%20ål%22


(Unfortunately I can't provide a clickable link because stack overflow doesn't appear to allow accented characters in URLs)

# Golfscript, 35 bytes

{."aeiouåäö\n "?-1={."o"\}{}if}%


Expects the input to be on the stack. With input (50 bytes):

"#{STDIN.gets}"{."aeiouåäö\n "?-1={."o"\}{}if}%


Works with the swedish vovels å, ä and ö.

• input is always on stack on GS Mar 25 '15 at 9:40

# Sed (on command line), 28 bytes

sed 's/$$[^aeiou]$$/\1o\1/g'


Either pipe the text in or type it direct. Just the sed code on its own is 22 bytes.

• This also duplicates spaces and chars like ä. Mar 25 '15 at 13:02

# R, 45 chars

gsub("([^aeiouäöå ])","\\1o\\1",readline(),i=T)


Simple regex. Reads from stdin. i=T stands for ignore.case=TRUE (thanks to partial matching of argument names), which makes gsub case insensitive.

Usage:

> gsub("([^aeiouäöå ])","\\1o\\1",readline(),i=T)
Min svävare är full med ål
[1] "MoMinon sosvovävovarore äror fofulollol momedod ålol"
> gsub("([^aeiouäöå ])","\\1o\\1",readline(),i=T)
hello
[1] "hohelollolo"
> gsub("([^aeiouäöå ])","\\1o\\1",readline(),i=T)
hElLo
[1] "hohElolLoLo"


# <>< (Fish), 64 bytes

>" oieauåäöOIEAUÅÄÖ"0i:1+?!;01.
:&=?\     l?!v&
^[0o&<&o"o"o:&<


It's not the shortest answer but I enjoy the challenge of programming in <><

Try it out here

# golflua, 36 bytes

B=I.r():g("[^aeiou%W ]","%1o%1")w(B)


Simple pattern-matching: take stdin, then find the non-vowels (%W takes care of non-alphanumeric chars) & insert an o between the two replacements. Sadly, doing all this within the write (i.e., w(I.r():g(....))) also output the count of insertions, though it saved 3 chars. A Lua equivalent would be

line = io.read()
rovar = line:gsub("[^aeiou%W ]","%1o%1")
print(rovar)


# REXX, 107 bytes

parse arg s
v='aeiouåäö '
o=
do until s=''
parse var s l 2 s
if verify(l,v)>0 then l=l'o'l
o=o||l
end
say o


"MoMinon sosvovävovarore äror fofulollol momedod ålol"

# JavaScript 43

Thanks to @Masterzagh for saving on function syntax.

x=>x.replace(/[bcdfghj-np-tv-z]/gi,"$&o$&")


## JavaScript 62

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

• Your function can be in the form of an anonymous arrow function like x=>x.replace(/[bcdfghj-np-tv-z]/gi,"$&o$&"). Arrow functions work like this name=(arg1, arg2)=>{code}. () are not needed if there's only one argument and {} are not needed if there's only one line of code. Return is also not needed if the one line returns something.
– user64039
Jan 12 '17 at 15:13
• And I forgot to say. You don't need to give it a name to solve the problem which only asked you to create a function.
– user64039
Jan 12 '17 at 15:20

# Japt v2.0a0, 7 bytes

r\c_+io


Try it

# Haskell, 75 bytes

x n|elem n[x|x<-['B'..'z'],notElem x"EIOUaeiou"]=[n,'o',n]|1<2=[n]
f=(>>=x)


This is a slight improvement on nimi's answer (unfortunately I can't comment yet) which uses a "clever" way to generate a list of consonants ([x|x<-['B'..'z'],notElem x"EIOUaeiou"]) that saves 6 bytes over just listing them out.

In this case ['B'..'z'] expands to "BCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz".

While some non-letter characters are included in the list of consonants, these don't include any punctuation or spaces so it should work for any regular sentence.

Usage: f "Hello there!" -> "HoHelollolo tothoherore!"`.