Konversi string menjadi setara dengan Rövarspråket


15

Rövarspråket

Rövarspråket adalah permainan kata yang dimainkan oleh anak-anak Swedia, dari buku-buku tentang Kalle Blomkvist oleh Astrid Lindgren.

Aturan dasarnya adalah sebagai berikut (dari Wikipedia):

  • Setiap konsonan (pengejaan, bukan pelafalan) digandakan, dan o dimasukkan di antaranya.
  • Vokal dibiarkan utuh.

Beberapa contoh:

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

Konsonan Swedia sama dengan konsonan bahasa Inggris, sehingga program harus bekerja dengan entri Swedia dan Inggris.

Huruf "y" diambil sebagai konsonan dalam kasus ini - seperti sebagian besar waktu.


Tugas Anda:

Tulis program untuk mengonversi string huruf Swedia, yang dimasukkan melalui fungsi atau melalui stdin, ke dalam padanan Rövarspråket-nya. Jawaban terpendek dalam byte menang!


@ MartinBüttner Menjelaskan pertanyaan saya lebih lanjut - itu harus bekerja dengan Swedia (karena itu adalah permainan kata Swedia).
James Williams

Apa arti dari entri alfabet?
Pengoptimal

@Optimizer String hanya karakter alfabet. Maaf, saya mengucapkannya dengan buruk, saya akan mengedit
James Williams

3
Bagaimana seharusnya kita memperlakukan non-surat? Setidaknya spasi muncul dalam contoh kedua.
nimi

2
Sebagai tambahan: 'Y' dianggap sebagai vokal dalam bahasa Swedia
leo

Jawaban:


14

Retina , 14 + 5 = 19 byte

Retina adalah bahasa yang pada dasarnya hanya .NET regex dengan overhead sesedikit mungkin. Kode untuk program ini terdiri dari dua file:

i`[b-z-[eiou]]
$0o$0

Ini membaca input pada STDIN dan mencetak output ke STDOUT.

Jika Anda memanggil file pattern.rgxdan replacement.rpl, Anda dapat menjalankan program seperti itu

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

Penjelasan

Ini cukup mudah, tetapi saya akan menambahkan beberapa penjelasan (kebanyakan tentang cara kerja Retina). Jika Retina dipanggil dengan 2 file maka secara otomatis diasumsikan beroperasi dalam "mode Ganti", di mana file pertama adalah regex dan file kedua adalah polanya.

Retina dapat dikonfigurasikan (termasuk RegexOptionsdan opsi lainnya) dengan menambahkan regex dengan `dan string konfigurasi. Dalam hal ini saya hanya memberikan iyang merupakan pengubah regex normal untuk ketidakpekaan huruf.

Adapun regex itu sendiri, menggunakan pengurangan kelas karakter .NET untuk mencocokkan konsonan dalam kisaran ASCII. Pengganti kemudian hanya menulis pertandingan kembali dua kali dengan odi antaranya.


Apakah Anda melewatkan satu adi kelas karakter vokal Anda?
Brian Gordon

3
@BrianGordon Tidak, saya memulai kelas karakter b, jadi saya tidak perlu mengurangi a.
Martin Ender

2
Menarik, saya belum pernah melihat kisaran karakter subtraktif yang bersarang sebelumnya. Apakah itu hanya hal. NET?
Steve Bennett

Saya merasa Anda perlu menghitung setidaknya satu karakter untuk membatasi antara dua file. itu akan menjadi titik koma atau baris baru dalam bahasa lain. itu adalah ruang antara nama file jika Anda ingin pilih-pilih tentang dari mana karakter berasal dari bahasa ini.
Sparr

@Parr ya, itu kebijakannya sekarang, tapi kebijakan itu lebih baru daripada tantangan / jawaban ini. Sebagai referensi (Faktanya, jika Anda melihat waktu, Anda dapat melihat bahwa saya mendorong kebijakan karena jawaban ini, tetapi menerapkan aturan seperti itu di seluruh situs secara surut tidak masuk akal.)
Martin Ender

12

Menggunakan Unix KSH 27 28 32 27 byte (atau 21 jika kita hanya menghitung perintah sed di dalam)

Terima kasih atas saran orang lain :) Dihormati.

.. Saya turun ke ini:

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

(diizinkan untuk spasi dan karakter Swedia)

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

4
Juga, saya pikir itu boleh untuk mengklaim jawaban Anda adalah sebuah sedprogram, dan hanya menghitung byte antara tanda kutip tunggal
Digital Trauma

1
s/[^AEIOU]/&o&/igtampaknya berfungsi .. setidaknya untuk satu kata ... Anda harus mengecualikan spasi juga
Digital Trauma

1
bash, meskipun shell tidak masalah, asalkan program sed Anda dalam tanda kutip tunggal
Digital Trauma

1
Juga hati-hati untuk vokal Swedia ö, å, dll - kebutuhan tersebut tidak termasuk juga. Mungkin lebih baik menggunakan daftar putih konsonan sajas/[BCDFGHJ-NP-TV-Z]/&o&/ig
Digital Trauma

2
Saya akan membuatnya 'sed' dan menggunakan "s / [^ AEIOUÅÄÖ] / & o & / ig", yang mencakup vokal dan spasi Swedia untuk 25 byte.
swstephe

7

CJam, 32 30 byte

q{_eu'[,66>"EIOU"-#)g{'o1$}*}/

Ini adalah program lengkap membaca dari STDIN dan mencetak ke STDOUT. Ini berfungsi untuk input Unicode sembarang dan memperlakukan 42 karakter berikut sebagai konsonan:

BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz

Uji di sini.

Penjelasan

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

5

JavaScript, 59 57 55 44 byte

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"));

And since it wasn't asked to output, you don't need the alert either.

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.

@Masterzagh That's cool, thanks again!
ProgramFOX

4

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.

@MartinBüttner Thanks! Still new to Mathematica golfing...
LegionMammal978

@MartinBüttner Was going to do that anyways but got distracted by some notifications :P
LegionMammal978

4

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!


3

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.


3

Java 8, 45

Use as a lambda function. Uses regular expression.

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

Try here


2

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?
Alex A.

@AlexA. I already noticed the problem. It was a zero-character fix (\s to \W).
PhiNotPi

+1, most thorough explanation for Perl code I have seen on this site.
Zgarb

2

C (ideone.com version) - 133

Ok, this is huge. But C doesn't have regular expressions. Please tell me if you see something that can make it shorter...

#define x (*c<66||*c>90)&&(*c<98||*c>122)||strchr("EIOUeiou",*c)?"":
c[2];main(){while(0<(*c=getchar()))printf("%s%s%s",c,x"o",x c);}

How does the local variable c get declared?
wjl

@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.
Jerry Jeremiah

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

@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?
Jerry Jeremiah

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

2

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.


2

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


1

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.


You can save 4 bits by removing 4 chars and replacing one char with another one.
Jakube



1

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: /codegolf//a/48182/34718


1

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

1

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)


0

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


2
input is always on stack on GS
Optimizer

0

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.


3
This also duplicates spaces and chars like ä.
ProgramFOX

0

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"

0

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


0

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)

0

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"


0

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.

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.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.