9
\$\begingroup\$

Story

In an unnamed company, some people use Java and some use C++. This was always a nuisance, and they kept on arguing which single language they should all be using. To settle the dispute, the management decided that they'll buy a translator program that will be able to rewrite their C++ programs to Java and vice versa. An important part of the translator will be a routine that will rewrite all the identifiers. This is because Java coders in the company write multiword identifiers in a different way than C++ coders in the company do. We will now describe both methods. In Java a multiword identifier is constructed in the following manner: the first word is written starting with a lowercase letter, and the following ones are written starting with an uppercase letter, no separators are used. All other letters are lowercase. Examples of Java identifiers are javaIdentifier, longAndMnemonicIdentifier, name and kSP.In C++ people use only lowercase letters in their identifiers. To separate words they use the underscore character '_'. Examples of C++ identifiers are cpp_identifier, long_and_mnemonic_identifier, name (here Java and C++ people agree), and k_s_p.

Task

Write the identifier translation routine/function/etc. Given an identifier, detect whether it is a Java identifier or C++ identifier (as defined below) and translate it to the other dialect. Translation must preserve the order of words and must only change the case of letters and/or add/remove underscores. You may assume all input to be valid, as checking was done for you in the superroutine.

More formally

A Java identifier only contains characters from [a-zA-Z] and starts with a lowercase letter. Every uppercase character is a word boundary.

A C++ identifier only contains characters from [a-z_] and additionally doesn't start or end with an underscore nor does it contain two adjacent underscores anywhere within. Every underscore is a word boundary.

Translation: switch every word boundary, that is, if it was an underscore, remove it and capitalize the following letter, if it was uppercase, prepend an underscore and lowercase the letter.

Input

The input consists of one line that contains an identifier. It consists of letters of the English alphabet and underscores. Other standard input styles are also valid.

Output

If the input identifier is a Java identifier, output/return its C++ version. If it is a C++ identifier, output/return its Java version. You may assume it will be at least one of those (both is possible).

Examples

long_boring_identifier  |  longBoringIdentifier
otherWay                |  other_way
same                    |  same
getHTTP                 |  get_h_t_t_p
invalid_Input           |  <undefined>

All the standard rules apply, none of the standard loopholes are allowed.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Closely related. \$\endgroup\$ Oct 26, 2019 at 23:53
  • \$\begingroup\$ Well, this also requires solving in the other way. \$\endgroup\$
    – user85052
    Oct 27, 2019 at 0:51
  • 3
    \$\begingroup\$ Even more closely related - given that the only difference is whether the first letter is lowercase or uppercase, I'd consider this a dupe. \$\endgroup\$
    – user45941
    Oct 27, 2019 at 2:17
  • \$\begingroup\$ @Mego Dang it, the people over in the Sandbox haven't found any dupes. And it's been there for quite a while as well. Partly due to me putting of making it live. Good catch! \$\endgroup\$ Oct 27, 2019 at 6:48
  • 1
    \$\begingroup\$ Somehow I had already forgotten, thanks for pointing out the other one! And sorry I didn't catch the dupe beforehand, you did basically everything right. \$\endgroup\$ Oct 27, 2019 at 14:00

5 Answers 5

4
\$\begingroup\$

QuadR, 19 bytes

_(.)
[A-Z]
\u1
_\l&

Try it online!

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

Node.js, 61 bytes

Contains the unprintable character \x7F.

s=>s.replace(/_.|[A-Z]/g,s=>Buffer(s[1]||''+s).map(x=>x^32))

Try it online!


JavaScript (ES6), 72 bytes

s=>s.replace(/_.|[A-Z]/g,s=>s[1]?s[1].toUpperCase():'_'+s.toLowerCase())

Try it online!

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

Retina, 40 34 bytes

([A-Z])
_$1
T`Ll`lL`_.
_([A-Z])
$1

Try it online!

Explanation

([A-Z])            # Replace all uppercase letters with
_$1                # an underscore followed by that same letter.
T`Ll`lL`_.         # Replace lowercase letters with uppercase letters and vice versa when after an underscore
_([A-Z])           # Replace an underscore followed by an uppercase letter
$1                 # with just that letter
\$\endgroup\$
2
\$\begingroup\$

Python 3.8, 95 bytes

First golf in a while. Comments welcome.

lambda s:"".join(["_"*(x!=(l:=x.lower()))+l,x.upper()][p=="_"]*(x!="_")for p,x in zip("."+s,s))
\$\endgroup\$
0
1
\$\begingroup\$

Zsh -oextendedglob, 82 69 51 bytes

<<<${1//(#m)(_?|[A-Z])/${${MATCH[2]:u}:-_$MATCH:l}}

Try it online! Try it online! Try it online!

Even if the flags count toward byte count, adding 14 bytes for -oextendedglob still undercuts the 82 byte program!

<<<${1//(#m)(_?|[A-Z])/${${MATCH[2]:u}:-_$MATCH:l}}
   ${1//              /                           }  # replacement
        (#m)                                         # enable $MATCH parameter
            (_?|[A_Z])                               # "?" matches any character
                         ${MATCH[2]:u}               # substitute 2nd char, uppercased
                       ${             :-_$MATCH:l}   # if empty, substitute "_" and lowercased match
<<<                                                  # print to stdout
\$\endgroup\$

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