25
\$\begingroup\$

The famous constructed language Esperanto uses the Latin alphabet (mostly, see the linked wikipedia page for details). However, there are some characters with accents: ĉ, ĝ, ĥ, ĵ, ŝ, and ŭ. (C-circumflex, g-circumflex, h-circumflex, j-circumflex, s-circumflex, and u-breve.) Naturally, these characters are very hard to type. Even for this question, I had to search in the Unicode selector for the characters. Due to this, a convention using the letter "x" has been developed for electronic use. For example, "cxu" is used for "ĉu". (Note: the letter "x" is not used normally in the Esperanto alphabet."

However, I am a language purist! This *air quote* x nonsense is killing me! I need a program to fix this, preferably as short as possible so I can type it into my terminal as fast as possible!

Challenge

Your mission is to take a string of Esperanto using x-convention and convert it to real Esperanto.

In effect, you have to map:

cx: ĉ
gx: ĝ
hx: ĥ
jx: ĵ
sx: ŝ
ux: ŭ
Cx: Ĉ
Gx: Ĝ
Hx: Ĥ
Jx: Ĵ
Sx: Ŝ
Ux: Ŭ

All other printable ASCII characters should be accepted and not changed. Unicode would be nice, but not necessary.

Input and output can be in any format reasonable to your language. Good luck!

Testcases

"input" : "output"
_____________
"gxi estas varma" : "ĝi estas varma"
"Cxu sxi sxatas katojn aux hundojn?" : "Ĉu ŝi ŝatas katojn aŭ hundojn?"
"Uxcxsxabcd(hxSx)efg{};" : "Ŭĉŝabcd(ĥŜ)efg{};"
"qwertyuiop" : "qwertyuiop"
" " : " "
"" : ""
"x" : "x"
"xc" : "xc"
"xcx" : "xĉ"
"cxx" : "ĉx"

Scoring

This is . Answers are scored by smallest bytecount in the language's default encoding.

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=149292,OVERRIDE_USER=47670;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Good luck, have fun, and feel free to suggest improvements!

Clarifications:

  • You only need to worry about printable ASCII characters.

  • You only need to output a character that looks like the correct output. Yes, this means you can tack the accent onto the standard character.

\$\endgroup\$
11
  • \$\begingroup\$ ASCII here means 20-7E printable characters, 00-7F, or what? \$\endgroup\$
    – DELETE_ME
    Nov 28, 2017 at 2:06
  • \$\begingroup\$ All the printable ones. \$\endgroup\$
    – AAM111
    Nov 28, 2017 at 2:07
  • \$\begingroup\$ Note: I added a clarification that you can use the letter and the modifier accent. \$\endgroup\$
    – AAM111
    Nov 28, 2017 at 2:15
  • 6
    \$\begingroup\$ Combining circumflex is at 0302 ̂, and combining breve is at 0306 ̆. \$\endgroup\$
    – DELETE_ME
    Nov 28, 2017 at 2:23
  • 1
    \$\begingroup\$ @EriktheOutgolfer Why would a language purist care for different representations of the same grapheme? \$\endgroup\$ Nov 28, 2017 at 21:01

28 Answers 28

9
\$\begingroup\$

QuadR, 65 bytes

.x
3::⍵M⋄'ĉĝĥĵŝŭĈĜĤĴŜŬ'['cghjsuCGHJSU'⍳⊃⍵M]

Try it online!

.x replace any char followed by "x" with

3::⍵M upon indexing error, return the match unmodified
 now try:
'ĉĝĥĵŝŭĈĜĤĴŜŬ'[] index into this string with
  ⍵M the match's
   first letter's
   index
  'cghjsuCGHJSU' in this string

This is equivalent to the Dyalog APL tacit function:

'.x'⎕R{3::⍵.Match⋄'ĉĝĥĵŝŭĈĜĤĴŜŬ'['cghjsuCGHJSU'⍳⊃⍵.Match]}
\$\endgroup\$
3
  • \$\begingroup\$ Nice answer! +1 \$\endgroup\$
    – AAM111
    Nov 28, 2017 at 1:28
  • \$\begingroup\$ I'm not sure how bytes are counted here. Isn't the straightforward use of ⎕R shorter? ('cghjsuCGHJSU',¨'x')⎕r(,¨'ĉĝĥĵŝŭĈĜĤĴŜŬ') \$\endgroup\$
    – ngn
    Nov 28, 2017 at 7:26
  • \$\begingroup\$ @ngn It is, but my battery ran out before I had a chance to post that. \$\endgroup\$
    – Adám
    Nov 28, 2017 at 7:35
7
\$\begingroup\$

Retina, 27 bytes

iT`x`̂`[cghjs]x
iT`x`̆`ux

Try it online!

This program is composed by two transliterations. Due to having combining characters in the code this doesn't render too well, the first line should actually look similar to iT`x`^`[cghjs]x, where ^ stands for the circumflex accent combining character. What this is saying is that it should Transliterate (ignoring case) all the xs in the input into a ^, whenever they are following any letter in [cghjs].


Note: TIO incorrectly measures this code as 25 bytes. Actually, this Retina program uses UTF-8 encoding (other programs can use UTF-32 or ISO 8859-1) and the two combining characters present cost 2 bytes each.

\$\endgroup\$
5
\$\begingroup\$

C,  173  154 bytes

Thanks to @Colera Su for saving 17 bytes!

p,c,i;f(char*s){for(char*l="cghjsuCGHJSU";p=*s;~c&&putchar(p))for(c=*++s,i=0;c=='x'&&l[i];++i)l[i]-p||write(1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+i*2,2,c=-1,++s);}

Try it online!

Explanation:

p,c,i;
f(char*s)
{
    // The outer loop and an array of characters that are modified by a trailing 'x'.
    // The array/string is used for getting the index for the accented character later.
    for (char*l="cghjsuCGHJSU";

                                // Store the current character of the input string in 'p'.
                                // If it is '\0', the loop terminates.
                                p=*s;

                                      // The last statement in the loop.
                                      // If 'c==-1', it outputs the char stored in 'p'. 
                                      ~c&&putchar(p))

        // Store the character following 'p' in 'c' and increment the string pointer.
        for(c=*++s, i=0;

                        // If 'c' is not the letter 'x', the inner loop terminates
                        // immediately. Otherwise it loops through the characters of
                        // string 'l'.
                        c=='x'&&l[i]; ++i)

            // If the character stored in 'p' is found inside the string 'l'...
            l[i]-p ||

                      // ...then print the accented character corresponding to 'p'.
                      // 'i' is the index of 'p' in 'l', and, because the characters
                      // with accents are two bytes each, the index is multiplied by 2.
                      write(1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+i*2,2,

                      // Finally set 'c' to -1 so that the non-accented character doesn't
                      // get printed too, and increment the string pointer so that the
                      // letter 'x' doesn't get printed either.
                                                    c=-1, ++s);
}
\$\endgroup\$
4
  • \$\begingroup\$ Nice! Can I have an explanation please? \$\endgroup\$
    – AAM111
    Nov 28, 2017 at 2:10
  • \$\begingroup\$ Probably you can use literal null byte instead of \0? \$\endgroup\$
    – DELETE_ME
    Nov 28, 2017 at 2:16
  • \$\begingroup\$ (but that unfortunately doesn't work on TIO) \$\endgroup\$
    – DELETE_ME
    Nov 28, 2017 at 2:17
  • \$\begingroup\$ You can use write(1,"..."+i*2,2) to save 17 bytes. Try it online! \$\endgroup\$
    – Colera Su
    Nov 28, 2017 at 5:52
5
\$\begingroup\$

Python 3, 81 bytes

lambda s,T="cĉgĝhĥjĵsŝuŭ":eval("s"+".replace('%sx',%r)"*12%(*T+T.upper(),))

Try it online!

Generates and evaluates the string:

s.replace('cx','ĉ').replace('gx','ĝ').replace('hx','ĥ').replace('jx','ĵ').replace('sx','ŝ').replace('ux','ŭ').replace('Cx','Ĉ').replace('Gx','Ĝ').replace('Hx','Ĥ').replace('Jx','Ĵ').replace('Sx','Ŝ').replace('Ux','Ŭ')

Erik the Outgolfer saved a byte.

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

///, 75 bytes

/,/\/\///>/x\,/c>ĉ,g>ĝ,h>ĥ,j>ĵ,s>ŝ,u>ŭ,C>Ĉ,G>Ĝ,H>Ĥ,J>Ĵ,S>Ŝ,U>Ŭ/

Note: Because the OP request all printable characters must be processed, my "special characters" chosen must not be printable. So I chosen tab and newline instead of , which does not change my bytecount or code functionality. The code would look like:

/
/\/\/// /x\
/c  ĉ
g   ĝ
h   ĥ
j   ĵ
s   ŝ
u   ŭ
C   Ĉ
G   Ĝ
H   Ĥ
J   Ĵ
S   Ŝ
U   Ŭ/

However that requires the input must not contains tab or newlines.

Try it online!

Because /// can't take input, you should put the input after the code.

Pretty straightforward. I guess it can't be shorter because /// need special handling of each character.

Explanation:

/,/\/\//       Replace all `,` in the code by `//`
               (two slashes are represented as two backslash-ed slashes)
/>/x\,         (in original code) becomes
/>/x\//        (because `,` is replaced by `//`) - replace all occurence of 
               `>` by `x/`.
/cx/ĉ//gx/ĝ//hx/ĥ//jx/ĵ//sx/ŝ//ux/ŭ//Cx/Ĉ//Gx/Ĝ//Hx/Ĥ//Jx/Ĵ//Sx/Ŝ//Ux/Ŭ/
               ^ The remaining part of the code should look like this.
               Straightforward replacement.
\$\endgroup\$
2
\$\begingroup\$

Python 3, 95 bytes

f=lambda x,v="cĉgĝhĥjĵsŝuŭCĈGĜHĤJĴSŜUŬ":v and f(x.replace(v[0]+"x",v[1]),v[2:])or x

Try it online!

-10 bytes thanks to WhatToDo
-1 byte thanks to Colera Su

\$\endgroup\$
6
  • \$\begingroup\$ 96 bytes Try it online! \$\endgroup\$
    – user76292
    Nov 28, 2017 at 2:22
  • \$\begingroup\$ @user507295 oh smart idea. thanks! \$\endgroup\$
    – hyper-neutrino
    Nov 28, 2017 at 2:23
  • \$\begingroup\$ Use and-or trick to save one byte: Try it online! \$\endgroup\$
    – Colera Su
    Nov 28, 2017 at 2:37
  • \$\begingroup\$ @ColeraSu oh cool, thanks. not sure why that trick vanished D: \$\endgroup\$
    – hyper-neutrino
    Nov 28, 2017 at 3:19
  • \$\begingroup\$ @HyperNeutrino Because I didn't know about that trick. Sorry! \$\endgroup\$
    – user76292
    Nov 28, 2017 at 3:30
2
\$\begingroup\$

Retina, 55 bytes

iT`CG\HJSUcg\hjsux`ĈĜĤĴŜŬĉĝĥĵŝŭ_`[cghjsux]x

Try it online! Non-combining approach. Bytes could be saved if not for the standalone x test cases.

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

Perl 5, 101 + 1 (-p) = 102 bytes

%k=qw/c ĉ g ĝ h ĥ j ĵ s ŝ u ŭ C Ĉ G Ĝ H Ĥ J Ĵ S Ŝ U Ŭ/;$"=join"|",keys%k;s/($")x/$k{$1}/g

Try it online!

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

JavaScript (ES6), 92 bytes

s=>[..."cghjsuCGHJSU"].reduce((a,v,i)=>a.split(v+"x").join("ĉĝĥĵŝŭĈĜĤĴŜŬ"[i]),s)

Try it online!

Used split-join method recommended in here to reduce byte counts because the new RegExp(/*blah*/) constructor took up too many bytes.

Comparison:

Original: a.replace(new RegExp(v+"x", "g"), "ĉĝĥĵŝŭĈĜĤĴŜŬ"[i])
New     : a.split(v+"x").join("ĉĝĥĵŝŭĈĜĤĴŜŬ"[i])

Shorter, combining accent approach (63 bytes), but with some artifacts visible.

s=>s.replace(/([cghjs])x/gi," ̂$1").replace(/(u)x/gi," ̌$1");

Footnote: I'm claiming my answer 92 bytes because the 63-byte solution has artifacts that may affect the output.

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

APL (Dyalog Unicode), 57 bytes

Anonymous tacit function. Usages:

  1. Prefix function to string. This transliterates the string.

  2. Prefix function to list of strings. This transliterates the strings.

  3. Infix function with input file tie number as right argument and output file tie number as left argument. This populates the output file with the transliterated content of the input file.

('cghjsuCGHJSU',¨'x')⎕R(,¨'ĉĝĥĵŝŭĈĜĤĴŜŬ')

()⎕R() PCRE Replace

'cghjsuCGHJSU' these letters

,¨'x' each followed by an x

 … with…

,¨'ĉĝĥĵŝŭĈĜĤĴŜŬ' each of these letters as strings

Try it online!

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

J, 64 63 bytes

rplc((_2]\'ĉĝĥĵŝŭĈĜĤĴŜŬ');~"1'cghjsuCGHJSU',.'x')"0

How it works:

With _2]\ I rearrange the string 'ĉĝĥĵŝŭĈĜĤĴŜŬ' into a 12-row column in order to fit the shape of the other string.

,. adds 'x' to each character of the 'cghjsuCGHJSU' string and makes a 12 row by 2 columns array

;~"1' makes a list of boxed pairs of the above, "1 - rank 1 - apply to each row.

┌──┬──┐
│cx│ĉ │
├──┼──┤
│gx│ĝ │
├──┼──┤
│hx│ĥ │
├──┼──┤
│jx│ĵ │
├──┼──┤
│sx│ŝ │
├──┼──┤
│ux│ŭ │
├──┼──┤
│Cx│Ĉ │
├──┼──┤
│Gx│Ĝ │
├──┼──┤
│Hx│Ĥ │
├──┼──┤
│Jx│Ĵ │
├──┼──┤
│Sx│Ŝ │
├──┼──┤
│Ux│Ŭ │
└──┴──┘

rplc uses these boxed items to replace each occurrence of the left boxed item from a pair with the right one.

Try it online!

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

Befunge, 2x48 +1 = 99 bytes

>~:1+!#@_:"x"-v>$ 11p0"cghjsuCGHJSU"1\ >\31p11g-v
^ # #, : ++$\ _^#1"x"0*4!-"u"g11*"ʊ"!\_^#!:\*g13<

Try It Out (TIO is super weird about Befunge and I couldn't get any of my solutions to work on it)

How it works

>~:1+!@_

Gets input and checks if it's the end. End program if it is.

          "x"-v>
^ # #, : ++$\ _^

Checks if the character is an "x". If not, keep a copy of the character and print it.

               >$ 11p0"cghjsuCGHJSU"1\

Store the last character at (1,1). Puts all the characters to check into the stack.

                                       >\31p11g-v
                                      _^#!:\*g13<

Compare the last character against all the values in the stack.

                 1"x"0*4!-"u"g11*"ʊ"!\

Multiply the check (0 or 1) by ʊ (unicode value 650). Check whether the character was a u (for the breve) and adds 4 to the stack if so. Finally, add the ascii value of x (100) as well. The total adds up to the correct accent if needed or just an "x" if not.

>~:1+!#@_  
^ # #, : ++$\ _^#

Add all the values in the stack together, print it and keep a duplicate. Go back up for the next input.

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

R, 75 70 bytes

function(s)gsub('([cghjs])x','\\1\U302',gsub('(u)x','\\1\U306',s,T),T)

Try it online!

-5 bytes thanks to Giuseppe

Explanation

  • gsub('(u)x','\\1\U306',s,T): replace in s every occurrence of an uppercase or lowercase "u" (by using ignore.case=TRUE via the fourth argument T) followed by an "x" the "u" followed by the unicode for a breve
  • gsub('([cghjs])x','\\1\U302',gsub('(u)x','\\1\U306',s,T),T): take the result of that and replace every occurrence of an uppercase or lowercase (by using ignore.case=TRUE via the fourth argument T) "c", "g", "h", "j", or "s" followed by an "x" with the letter followed by the unicode for a circumflex
\$\endgroup\$
2
  • \$\begingroup\$ using argument order rather than naming saves 3 bytes, and another two getting rid of the leading zero in \U0302 and \U0306: Try it online! \$\endgroup\$
    – Giuseppe
    Nov 28, 2017 at 19:18
  • \$\begingroup\$ @Giuseppe -- great idea, thanks! \$\endgroup\$
    – duckmayr
    Nov 28, 2017 at 20:34
1
\$\begingroup\$

QuadR, 25 bytes

Combining diacritics edition.

ux
([cghjs])x
 ̆&
 ̂\1

i flag

Try it online!

Replace…

(u)x         u followed by x and
([cghjs])x   any of these letters followed by x …
 ̆\1          by a breve followed by the first group (the u) and
 ̂\1          a circumflex followed by the first group (the letter)

case insensitively

Equivalent to the following Dyalog APL code:

'(u)x' '([cghjs])x'⎕R' ̆\1' ' ̂\1'
\$\endgroup\$
5
  • \$\begingroup\$ Why is this 28 and not 24 bytes? \$\endgroup\$ Nov 28, 2017 at 21:07
  • \$\begingroup\$ @EriktheOutgolfer TIO's SBCS counter confused me. Fixed. Thanks. Wait, does that mean I win? \$\endgroup\$
    – Adám
    Nov 28, 2017 at 21:36
  • \$\begingroup\$ Huh, now it looks like it's 27 bytes (copied from TIO), but 24 bytes when copied from here. What is QuadR's encoding, and which is correct? \$\endgroup\$ Nov 28, 2017 at 21:40
  • \$\begingroup\$ @EriktheOutgolfer Both links report 24 on my FFQ/Win10. QuadR uses Dyalog Classic or any Unicode. \$\endgroup\$
    – Adám
    Nov 28, 2017 at 23:27
  • \$\begingroup\$ So it's 24 bytes or what? \$\endgroup\$ Nov 29, 2017 at 12:22
1
\$\begingroup\$

C, 145 144 bytes

Another C approach. Return by overwriting the input, using the fact that circumflex / breve are 2 bytes.

-1 bytes thanks to Steadybox.

i,t;f(char*s){for(t=1;*s;s++)if(*s^'x')for(i=12,t=1;i--;)t="cghjsuCGHJSU"[i]-*s?t:i*2;else t^1&&memcpy(s-1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+t,2),t=1;}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Using t^1&&memcpy(s-1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+t,2),t=1; instead of t^1?memcpy(s-1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+t,2),t=1:0; saves one byte. Try it online! \$\endgroup\$
    – Steadybox
    Nov 28, 2017 at 15:59
1
\$\begingroup\$

Mathematica, 81 bytes or 57 bytes

StringReplace[RemoveDiacritics@#<>"x"->#&/@Characters@"ĉĝĥĵŝŭĈĜĤĴŜŬ"]

It applies a replacement rule where the letter without the hat together with an "x" is replaced by the letter.

Here is an alternative using the added accents character: StringReplace[{"ux"->"ŭ","Ux"->"Ŭ",c_~~"x":>c<>"̂"}]

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

Perl 5, 49 + 2 (-p -C) = 61 51 bytes

s/[CGHJScghjs]\Kx/\x{0302}/g;s/[Uu]\Kx/\x{0306}/g

Try it online!

Saved 10 bytes thanks to Nahuel Fouilleul

\$\endgroup\$
3
  • \$\begingroup\$ could save 7 bytes: s/[CGHJScghjs]\Kx/\x{0302}/g;s/[Uu]\Kx/\x{0306}/g \$\endgroup\$ Nov 28, 2017 at 11:04
  • \$\begingroup\$ seems it works also just with -C and without -C with warning (Wide character in print) \$\endgroup\$ Nov 28, 2017 at 11:11
  • 1
    \$\begingroup\$ from perlrun -C on its own (not followed by any number or option list), or the empty string "" for the PERL_UNICODE environment variable, has the same effect as -CSDL. \$\endgroup\$ Nov 28, 2017 at 11:15
1
\$\begingroup\$

sed, 40 bytes (38 chars)

s/([cghjsCGHJS])x/\1̂/g
s/(u|U)x/\1̆/g

Try it online!

I believe this is different enough from iBug's answer.

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

Lexurgy, 60 48 bytes

a:
x=>̂/{c,g,h,j,s,C,G,H,J,S} _
x=>̆/{U,u} _

Replaces x with the correct combining diacritic based on the preceding character.

  • -12 bytes for removing the Class.
\$\endgroup\$
0
\$\begingroup\$

CJam, 51 bytes

q"ĉĝĥĵŝŭĈĜĤĴŜŬ""cghjsuCGHJSU".{'x+@\/*}

Try it online!

Explanation:

q                   Read input
"ĉĝĥĵŝŭĈĜĤĴŜŬ"      String literal
"cghjsuCGHJSU"      Another string literal
.{                  Iterate over the strings in parallel
  'x+                 Add an 'x to the normal character
  @                   Rotate to bring the input to the top of stack
  \                   Swap to bring the "cx" to the top
  /                   Split the input on instances of "cx"
  *                   Join the input on instances of the accented character
}
\$\endgroup\$
3
  • \$\begingroup\$ Is this really 39 bytes? I count 39 characters and I don't think CJam have a special encoding. \$\endgroup\$
    – DELETE_ME
    Nov 28, 2017 at 2:20
  • \$\begingroup\$ @user202729 Changed (TIO counted bytes as characters for some reason) \$\endgroup\$ Nov 28, 2017 at 2:23
  • \$\begingroup\$ Because TIO believe that all golfing languages have special character codepage, and it doesn't bother check if all characters are in the correct codepage. \$\endgroup\$
    – DELETE_ME
    Nov 28, 2017 at 2:25
0
\$\begingroup\$

PowerShell, 58 bytes

It's 54 characters and saving it in PowerShell ISE makes it UTF-8 + BOM for 58 bytes. It doesn't render as nicely in a browser:

$args-replace'(?<=u)x','̆'-replace'(?<=[cghjs])x','̂'

regex replaces the x with the combining Unicode characters from @user202729's comment.

e.g.

PS C:\> .\eo.ps1 "Cxu vi sxatas la cxapelliterojn? Mi ankaux."
Ĉu vi ŝatas la ĉapelliterojn? Mi ankaŭ.
\$\endgroup\$
0
\$\begingroup\$

Clojure, 126 115 bytes

-11 bytes by changing the replacement map to a partition of a string.

#(reduce(fn[a[f r]](clojure.string/replace a(str f\x)(str r)))%(partition 2"cĉgĝhĥjĵsŝuŭCĈGĜHĤJĴSŜUŬ")) 

A reduction over a map of replacements to look for, and what to replace them with.

Still working on a way to compress the replacement map.

(defn translate [^String esperanto]
  (reduce (fn [acc [f r]] (clojure.string/replace
                            acc ; Replace the translation so far by
                            (str f \x) ; adding a x after each character, search for it in the string,
                            (str r))) ; and replace it with a stringified accented char

          esperanto ; Before the reduction happens, the accumulator is the original string

          ; A list of [char-to-find what-to-replace-with] pairs
          (partition 2"cĉgĝhĥjĵsŝuŭCĈGĜHĤJĴSŜUŬ")))))
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 91 bytes

(i,s='cĉgĝhĥjĵsŝuŭCĈGĜHĤJĴSŜUŬ')=>i.replace(/.x/g,m=>s[1+s.search(m[0])||s]||m)

Try it online!

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

Scala, 110 bytes

Boring regex solution:

def?(s:String)="(.)x".r.replaceAllIn(s,m=>m.group(0)(0)+(if(m.group(0)(0).toUpper=='U')"\u0306"else"\u0302"))

Old scala solution (116 bytes)

def?(s:String)=s.foldLeft("")((r,c)=>if(c=='x')r.init+r.last+(if(r.last.toUpper=='U')"\u0306"else"\u0302")else r+c)

Ungolfed

def?(s:String)=
  s.foldLeft("")((r,c)=>  // 'Fold' string with empty string as first result
    if(c=='x')            // If current character is x
      r.init+             // Take the every character from result but the last
        r.last+           // The last character from result and add
          (if(r.last.toUpper=='U')
            "\u0306"      // combining breve if 'u' or 'U'
          else"\u0302")   // combining circumflex in any other case
 else r+c                 // Otherwise return result + character
)
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 35 chars, 36 bytes

s=>s.replace(/([cghjsu])x/gi,"$1̂")
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I don't think that works because ux should convert to ŭ, not û. \$\endgroup\$
    – bb94
    Feb 3, 2021 at 20:48
0
\$\begingroup\$

Raku, 57 50 bytes

{S:g:i/(<[cghjsu]>)x/{$0~chr 770+4*("u"eq$0.lc)}/}

Try it online!

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

Zsh, 71 bytes

for 2 3 (`fold -1<<<${a=cĉgĝhĥjĵsŝuŭ}${a:u}`)1=${1//$2x/$3}
<<<$1

Try it online!

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

sed, 108 bytes

s/cx/ĉ/g
s/gx/ĝ/g
s/hx/ĥ/g
s/jx/ĵ/g
s/sx/ŝ/g
s/ux/ŭ/g
s/Cx/Ĉ/g
s/Gx/Ĝ/g
s/Hx/Ĥ/g
s/Jx/Ĵ/g
s/Sx/Ŝ/g
s/Ux/Ŭ/g
\$\endgroup\$
3
  • \$\begingroup\$ You should format the code as code by `...` or <pre><code>...</code></pre> or 4 indents. \$\endgroup\$
    – DELETE_ME
    Nov 28, 2017 at 14:04
  • \$\begingroup\$ @user202729 I obviously knew that. I was submitting from my Android phone so I didn't format it correctly. \$\endgroup\$
    – iBug
    Nov 28, 2017 at 15:20
  • 3
    \$\begingroup\$ This looks like it's 119 bytes long. \$\endgroup\$ Nov 28, 2017 at 19:11

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.