17
\$\begingroup\$

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!

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

28 Answers 28

14
\$\begingroup\$

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.

\$\endgroup\$
6
  • \$\begingroup\$ Are you missing an a in your vowel character class? \$\endgroup\$
    – Rag
    Commented Mar 25, 2015 at 19:22
  • 3
    \$\begingroup\$ @BrianGordon No, I'm starting the character class from b, so I don't need to subtract a. \$\endgroup\$ Commented Mar 25, 2015 at 19:27
  • 2
    \$\begingroup\$ Interesting, I've never seen nested, subtractive character ranges before. Is that just a .NET thing? \$\endgroup\$ Commented Apr 20, 2015 at 9:18
  • \$\begingroup\$ 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. \$\endgroup\$
    – Sparr
    Commented May 20, 2015 at 3:41
  • \$\begingroup\$ @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.) \$\endgroup\$ Commented May 20, 2015 at 12:23
12
\$\begingroup\$

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
\$\endgroup\$
12
  • 5
    \$\begingroup\$ Also, I think it is allowable to claim your answer is a sed program, and just count the bytes between the single quotes \$\endgroup\$ Commented Mar 24, 2015 at 19:21
  • 1
    \$\begingroup\$ s/[^AEIOU]/&o&/ig seems to work.. for single words at least... you'll need to exclude spaces as well \$\endgroup\$ Commented Mar 24, 2015 at 19:23
  • 1
    \$\begingroup\$ bash, though the shell shouldn't matter, so long as your sed program is in single quotes \$\endgroup\$ Commented Mar 24, 2015 at 19:30
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 24, 2015 at 19:32
  • 2
    \$\begingroup\$ I would make it 'sed' and use "s/[^AEIOUÅÄÖ ]/&o&/ig", which covers Swedish vowels and spaces for 25 bytes. \$\endgroup\$
    – swstephe
    Commented Mar 24, 2015 at 22:34
8
\$\begingroup\$

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.";
\$\endgroup\$
5
\$\begingroup\$

JavaScript, 59 57 55 44 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.

\$\endgroup\$
4
  • \$\begingroup\$ "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")); \$\endgroup\$
    – user64039
    Commented Jan 12, 2017 at 15:09
  • \$\begingroup\$ And since it wasn't asked to output, you don't need the alert either. \$\endgroup\$
    – user64039
    Commented Jan 12, 2017 at 15:16
  • \$\begingroup\$ 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. \$\endgroup\$
    – user64039
    Commented Jan 12, 2017 at 15:40
  • \$\begingroup\$ @Masterzagh That's cool, thanks again! \$\endgroup\$
    – ProgramFOX
    Commented Jan 12, 2017 at 16:13
4
\$\begingroup\$

Mathematica, 84 73 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.
\$\endgroup\$
2
  • \$\begingroup\$ @MartinBüttner Thanks! Still new to Mathematica golfing... \$\endgroup\$ Commented Mar 24, 2015 at 23:17
  • \$\begingroup\$ @MartinBüttner Was going to do that anyways but got distracted by some notifications :P \$\endgroup\$ Commented Mar 24, 2015 at 23:25
4
\$\begingroup\$

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!

\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

Java 8, 45

Use as a lambda function. Uses regular expression.

a->a.replaceAll("(?i)[b-z&&[^eiou]]","$0o$0")

Try here

\$\endgroup\$
1
  • \$\begingroup\$ "Write a program to..." This looks more like a function to me. \$\endgroup\$ Commented Feb 13, 2020 at 20:06
2
\$\begingroup\$

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.
\$\endgroup\$
3
  • \$\begingroup\$ Won't [^aeiou] still match å and other non-ASCII vowels? \$\endgroup\$
    – Alex A.
    Commented Mar 25, 2015 at 0:40
  • \$\begingroup\$ @AlexA. I already noticed the problem. It was a zero-character fix (\s to \W). \$\endgroup\$
    – PhiNotPi
    Commented Mar 25, 2015 at 0:51
  • \$\begingroup\$ +1, most thorough explanation for Perl code I have seen on this site. \$\endgroup\$
    – Zgarb
    Commented Mar 25, 2015 at 8:49
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 16 15 13 bytes

-2 bytes thanks to Kevin Cruijssen

žNDu«SD'o«€Ć‡

Try it online!

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

C 106

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"+x*2,&c,x+"o",&c))x=c<66|c>122|c>90&c<98||index("EIOUeiou",c);}

Try it online!

\$\endgroup\$
7
  • \$\begingroup\$ How does the local variable c get declared? \$\endgroup\$
    – wjl
    Commented Mar 25, 2015 at 21:20
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Mar 26, 2015 at 11:31
  • \$\begingroup\$ 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). \$\endgroup\$
    – wjl
    Commented Mar 26, 2015 at 15:40
  • \$\begingroup\$ @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? \$\endgroup\$ Commented Mar 26, 2015 at 18:38
  • \$\begingroup\$ 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. =) \$\endgroup\$
    – wjl
    Commented Mar 26, 2015 at 20:06
1
\$\begingroup\$

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.

Try it here.

\$\endgroup\$
1
  • \$\begingroup\$ You can save 4 bits by removing 4 chars and replacing one char with another one. \$\endgroup\$
    – Jakube
    Commented Mar 24, 2015 at 19:12
1
\$\begingroup\$

Clip 10, 30

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

Basic regex substitution.

\$\endgroup\$
1
\$\begingroup\$

Pyth, 25 24 23

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

Run it here.

\$\endgroup\$
1
  • \$\begingroup\$ One char of your solution is redundant. \$\endgroup\$
    – Jakube
    Commented Mar 24, 2015 at 21:42
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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)

\$\endgroup\$
0
\$\begingroup\$

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 ö.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ input is always on stack on GS \$\endgroup\$
    – Optimizer
    Commented Mar 25, 2015 at 9:40
0
\$\begingroup\$

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.

\$\endgroup\$
1
  • 4
    \$\begingroup\$ This also duplicates spaces and chars like ä. \$\endgroup\$
    – ProgramFOX
    Commented Mar 25, 2015 at 13:02
0
\$\begingroup\$

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"
\$\endgroup\$
0
\$\begingroup\$

<>< (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

\$\endgroup\$
0
\$\begingroup\$

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)
\$\endgroup\$
0
\$\begingroup\$

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"

\$\endgroup\$
0
\$\begingroup\$

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$&")}
\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$
    – user64039
    Commented Jan 12, 2017 at 15:13
  • \$\begingroup\$ 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. \$\endgroup\$
    – user64039
    Commented Jan 12, 2017 at 15:20
0
\$\begingroup\$

Japt v2.0a0, 7 bytes

r\c_+io

Try it

\$\endgroup\$
0
\$\begingroup\$

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!".

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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