29
\$\begingroup\$

There are a bunch of different casing conventions, like camelCase, PascalCase, snake_case etc. It's annoying juggling all of these, so instead of choosing one like a sensible person, why not cursedly mix all of them together?

Your challenge is to, given a list of words (only containing lowercase letters), convert them to backwardS_hybriD-snakE_kebaB-cameL_case. To do so:

  • The words are joined by alternating underscores and hyphens, starting with underscores.
  • Capitalise the last letter of every word but the last.

This is , shortest wins!

Testcases

These are formatted as space-separated words

hello world -> hellO_world
beans -> beans
one two three four -> onE_twO-threE_four
backwards hybrid snake kebab camel case -> backwardS_hybriD-snakE_kebaB-cameL_case
test three words -> tesT_threE-words
o n e l e t t e r -> O_N-E_L-E_T-T_E-r
\$\endgroup\$
8
  • \$\begingroup\$ Can we take the words as an underscore-delimited string? \$\endgroup\$
    – Adám
    Commented Jun 20, 2022 at 22:27
  • 8
    \$\begingroup\$ @Adám I'm going to say no to that one as it's too similar to the output. \$\endgroup\$
    – emanresu A
    Commented Jun 20, 2022 at 22:31
  • 2
    \$\begingroup\$ There are so many casing conventions... So I choose to use CJK characters for a variable name. \$\endgroup\$
    – tsh
    Commented Jun 21, 2022 at 2:56
  • 1
    \$\begingroup\$ mmmm, snake kebab \$\endgroup\$ Commented Jun 21, 2022 at 12:53
  • 1
    \$\begingroup\$ @Arnauld That sounds reasonable, and I think it's in the standard I/O rules, so sure. \$\endgroup\$
    – emanresu A
    Commented Jun 21, 2022 at 22:16

28 Answers 28

13
\$\begingroup\$

Python, 72 bytes

lambda s:re.sub(" (.*?) ",r"_\1-",s+"x ")[::-1].title()[:1:-1]
import re

Attempt This Online!

How?

Uses regular expression to substitute pairs of spaces. To make sure every space is handled the auxiliary string "x " is appended. The result is reversed, title cased and reversed back. The auxiliary string (which has absorbed one unwanted title casing) is removed.

\$\endgroup\$
11
\$\begingroup\$

JavaScript (ES6), 50 bytes

Expects and returns a list of ASCII codes.

a=>a.map((c,i)=>a[i+1]^32?c^32?c:C^=114:c^32,C=45)

Try it online!

Commented

a =>              // a[] = list of ASCII codes
a.map((c, i) =>   // for each value c at position i in a[]:
  a[i + 1] ^ 32 ? //   if the next character is not a space:
    c ^ 32 ?      //     if the current character is not a space:
      c           //       leave it unchanged
    :             //     else:
      C ^= 114    //       make C switch between '-' and '_' and use it
  :               //   else:
    c ^ 32,       //     inverse the case of the current character
  C = 45          //   start with C = 45 (i.e. '-')
)                 // end of map()
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Since you're allowed take in strings as an array of characters, are you also allowed to take it in as a Buffer of characters? \$\endgroup\$ Commented Jun 21, 2022 at 18:30
  • \$\begingroup\$ @Samathingamajig Thank you for the suggestion. The OP has confirmed that we can take/return a list of ASCII codes, which is even easier/shorter than using Buffer. \$\endgroup\$
    – Arnauld
    Commented Jun 21, 2022 at 22:22
7
\$\begingroup\$

Retina, 13 bytes

Y`l  `L\_-`. 

Try it online! Link includes test cases. Explanation: Cyclically transliterates each space and the lower case letter before it. Since the two transliteration strings are the same length and the lower case letters appear exactly once each (via the shorthand l) they are simply transliterated to the upper case letters (L), however, there are two spaces in the transliteration string so they get alternately transliterated to _ (which needs to be escaped in a transliteration) and - (which fortunately doesn't need to be escaped at the end of a string.)

The best I could do in Retina 0.8.2 was 23 bytes:

T`l `L\_`. 
(_.+?)_
$1-

Try it online! Link includes test cases. Explanation: Since Retina doesn't have cyclic transliteration I just transliterate all of the spaces to _s and then fix up alternate _s to -s afterwards (which has to be done longhand as Retina 0.8.2 doesn't have step limits either).

\$\endgroup\$
7
\$\begingroup\$

JavaScript, 52 bytes

-3 bytes by emanresu A; -2 bytes by Arnauld.

s=>s.replace(/. /g,c=>c[0].toUpperCase()+'-_'[s^=1])

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Save a byte with ^= \$\endgroup\$
    – emanresu A
    Commented Jun 21, 2022 at 2:55
  • \$\begingroup\$ Another two with type abuse \$\endgroup\$
    – emanresu A
    Commented Jun 21, 2022 at 2:57
  • \$\begingroup\$ @Arnauld Not ever noticed that after rerun. Thanks for pointing out this. \$\endgroup\$
    – tsh
    Commented Jun 21, 2022 at 9:11
5
\$\begingroup\$

Vyxal s, 12 bytes

ṫ$RǐR₅‛_-ẎYp

Try it Online!

-5 bytes thanks to emanresuA

How?

ṫ$RǐR₅‛_-ẎYp
ṫ            # Tail extract, push a[:-1] and a[-1]
 $           # Swap
  R          # Reverse each
   ǐ         # Capitalize first letter of each
    R        # Reverse each
     ₅       # Push length without popping
      ‛_-    # Push "_-"
         Ẏ   # Extend this string to the length
          Y  # Interleave the list of words and each character of this string together
           p # Append the last item of the input (pushed earlier by tail extract) to this list
             # s flag joins this list to a string
\$\endgroup\$
1
  • \$\begingroup\$ 12 \$\endgroup\$
    – emanresu A
    Commented Jun 20, 2022 at 22:34
5
\$\begingroup\$

APL (Dyalog Extended), 25 bytes

Anonymous tacit prefix function. Takes list of words.

1⌊⍢⊃⍤↓⍢⌽∘∊⌈⍢⊃⍢⌽¨,¨'_-'⍴⍨≢

Try it online!

 tally of words

'_-'⍴⍨ use that to cyclically reshape this string

 concatenate each of those to each of the following:

 …¨ on each word:

  …⍢⌽ while reversed (reverse back again when done):

   …⍢⊃ while the first character is extracted (put it back again when done):

     uppercase

∘∊enlist (flatten), and then:

 …⍢⌽ while reversed (reverse back again when done):

  1⍤↓ drop the first character, and then:

   …⍢⊃ while the first character is extracted (put it back again when done):

     lowercase

\$\endgroup\$
4
\$\begingroup\$

Pyth, 16 bytes

ts.e+@"-_"k_r_b3

Try it online!

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 13 bytes

í™í`l)„_-ÞøS¨

Input as a list of words; output as a list of characters.

Try it online or verify all test cases.

Explanation:

í             # Reverse each word in the (implicit) input-list
 ™            # Titlecase each reversed word
  í           # Reverse each back
   `          # Pop the list, and push all words separated to the stack
    l         # Lowercase the last/top one
     )        # Wrap the stack back into a list
      „_-     # Push string "_-"
         Þ    # Cycle it indefinitely: ["_","-","_","-","_","-",...]
          ø   # Create pairs of the two lists, ignoring trailing items of the
              # longer (in this case infinite) list
           S  # Convert this list of pairs to a flattened list of characters
            ¨ # Remove the trailing "_"/"-"
              # (after which the result is output implicitly)
\$\endgroup\$
3
\$\begingroup\$

Python, 86 80 bytes

lambda s,i=0:"".join("_-"[i:=~i]+w.title()for w in s[::-1].split())[:1:-1]+s[-1]

Attempt This Online!

-6 bytes thanks to @xnor

\$\endgroup\$
3
  • 1
    \$\begingroup\$ It looks like (i:=i<1) can be i:=~i. The current version of Python has improved parsing so that the parens aren't required there. \$\endgroup\$
    – xnor
    Commented Jun 20, 2022 at 22:12
  • \$\begingroup\$ Oh that's a good improvement, I should probably update Python on my PC... \$\endgroup\$
    – jezza_99
    Commented Jun 20, 2022 at 22:19
  • 1
    \$\begingroup\$ Saving a few bytes with .title() \$\endgroup\$
    – xnor
    Commented Jun 20, 2022 at 22:23
3
\$\begingroup\$

Charcoal, 24 bytes

⭆θ⎇⁼ §θ⊕κ↥ι⎇⁼ ι§_-№…θκ ι

Try it online! Link is to verbose version of code. Explanation: Similar approach to @Arnauld's JavaScript answer.

 θ                          Input string
⭆                           Map over characters and join
  ⎇⁼ §θ⊕κ                   If next character is a space then
         ↥ι                 Current character uppercased
           ⎇⁼ ι             Else if current character is a space then
               §_-          Literal string `_-` cyclically indexed by
                  №…θκ      Number of spaces in current prefix
                       ι    Else current character
                            Implicitly print

I also tried an approach based on splitting and joining but I wasn't able to get it below 26 bytes.

\$\endgroup\$
3
  • \$\begingroup\$ Since the specification says "given a list of words", might you be able to take in a pre-split list as input in order to shorten the splitting and joining approach? \$\endgroup\$ Commented Jun 21, 2022 at 2:24
  • \$\begingroup\$ @DanielSchepler Well, I guess it would get me to the same byte-count, so it could add it as an alternative approach in that case. Assuming I can remember what I did.... \$\endgroup\$
    – Neil
    Commented Jun 21, 2022 at 8:11
  • \$\begingroup\$ @DanielSchepler Unfortunately because I had reversed the string before splitting to save me a byte, taking a list as input is still 25 bytes. \$\endgroup\$
    – Neil
    Commented Jun 21, 2022 at 9:18
3
\$\begingroup\$

MathGolf, 19 bytes

mxδmxhû_-*▒^\£<─~;!

Input as a list of words.

Try it online.

Explanation:

mx                  # Reverse each words in the (implicit) input-list
  δ                 # Titlecase each word
   mx               # Reverse each word back
     h              # Push the length of the list (without popping)
      û_-           # Push string "_-"
         *          # Repeat it the length amount of times
          ▒         # Convert it to a list ["_","-","_","-",...]
           ^        # Zip the two lists together, creating pairs
                    # (including trailing ["_"],["-"] items) 
            \       # Swap to get the input-list again
             £      # Pop and push its length
              <     # Only leave that many items (to only keep the pairs, and
                    # removing the trailing ["_"],["-"] items)
               ─    # Flatten this list of pairs
                ~   # Dump all strings separated to the stack
                 ;  # Discard the top ("_"/"-") one
                  ! # Lowercase the last/top word
                    # (implicitly join and output the entire stack)
\$\endgroup\$
3
\$\begingroup\$

brev, 161 150 bytes

(fn(strse x (: word(neg-look-ahead eos))(as-list(fn `(,@(butlast x) ,(char-upcase(last x)))))(: ($ word)" "($ word)" ")(conc(m 1)"_"(m 2)"-")'" ""_"))

325 with white space and test cases added:

(map
 (fn (strse x (: word (neg-look-ahead eos))
            (as-list (fn `(,@(butlast x) ,(char-upcase (last x)))))
        (: ($ word) " " ($ word) " ")
        (conc (m 1) "_" (m 2) "-")
        '" " "_"))
 '("hello world"
   "beans"
   "one two three four"
   "backwards hybrid snake kebab camel case"
   "test three words"
   "o n e l e t t e r"))
\$\endgroup\$
3
\$\begingroup\$

Python 3, 165 bytes

This is my first time having a go at this, so my answer is not gonna be great, but I found this really fun

lambda w:"".join([b if not i%2 else b[1:-1] for i,b in enumerate("_/-".join([s[::-1].title()[::-1] for s in w[:-1]]+[w[-1]]).split("/"))])+w[-1][::-1][:(len(w)+1)%2]
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! You can remove the space between ] and for. \$\endgroup\$
    – emanresu A
    Commented Jun 24, 2022 at 20:04
2
\$\begingroup\$

QuadR 2g, 37 30 29 bytes

Takes space-separated words.

(\S) 
_(.*)(\S)_
\u1_
_\1\u2-

Try it online!

PCRE Replace as follows, 2 times, with non-greedy patterns:

Target Replacement
(\S)  non-space followed by space \u1_ uppercased non-space followed by underscore
(.*?)(\S)_ any run of characters followed by a non-space and an underscore _\1\u2- an underscore, the run, the uppercased non-space, an underscore
\$\endgroup\$
2
\$\begingroup\$

Factor, 89 84 75 bytes

[ unclip [ odd? "-""_"? rot 1 cut* >upper append -rot glue ] reduce-index ]

Try it online!

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

Zsh, 61 bytes

g()<<<${${4+${3%?}${3[-1]:u}$1`g $2 $1 ${@:4}`}:-$3}
g _ - $@

Try it online!

Recursive solution:

g() # define function g (braces optional since body is one line)
    <<<${${4+${3%?}${3[-1]:u}$1`g $2 $1 ${@:4}`}:-$3}
#        ${4+                                  }      # if $4 is set, substitute
#            ${3%?}                                   #   $3, remove last character
#                  ${3[-1]:u}                         #   upper last character of $3
#                            $1                       #   $1 (either _ or -)
#                              `g $2 $1 ${@:4}`       #   recurse, swapping _ and -
#      ${${                                   }:-$3}  # else substitute $3 unchanged
#   <<<                                               # print
g _ - $@   # seed initial arguments
\$\endgroup\$
2
\$\begingroup\$

Python 3, 95 bytes

Honestly not a great submission, but I can't figure out a way to make it any smaller with this approach.

lambda l:''.join('-_'[i%2]+w[:-1]+(w[-1].upper(),w[-1])[i>len(l)-2]for i,w in enumerate(l))[1:]

Try it online!

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

Perl 5 + -p055, 26 bytes

s!(.) !uc$1.($|--?$/:_)!eg

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ $|--?$/:_ can be written as < r>^$/ \$\endgroup\$
    – Sisyphus
    Commented Jun 30, 2022 at 6:52
2
\$\begingroup\$

C (gcc), 109 91 bytes

-18 bytes thanks to @ceilingcat

main(c,v)char**v;{for(;1[++v];c=!c)strlen(*v)[*v-1]-=32,printf(c?"%s_":"%s-",*v);puts(*v);}

Try it online!

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

><>, 32 30 bytes

55*ii:48*=?\$o30.
-{:0$-}"F"+\

Try it online

Explanation

55*i               # init stack with 25 and first input
    i:48*=?\       # if next input is 32, move to row 2
            $o30.  # else print previous input and jump to next input handling
-                  # subtract 32 from previous input (switch to uppercase)
 {:0$-}            # get the 25 from bottom of stack and negate a copy for next iteration
       "F"+        # add "F" to get either "-" or "_" depending on sign of the 25
           \       # move back to row 1 to print
\$\endgroup\$
3
  • 1
    \$\begingroup\$ How the hell did you make ><> so competitive???? \$\endgroup\$ Commented Nov 16, 2022 at 9:12
  • 1
    \$\begingroup\$ @null There were some neat tricks available here that helped a lot. Like using the space between words to convert to uppercase and the fact that there was an even amount of charcodes between _ and -. \$\endgroup\$
    – Emigna
    Commented Nov 16, 2022 at 9:24
  • \$\begingroup\$ Thank you for explaining! I think this is the kind of code golf everyone is expecting to see. If possible, I will learn to golf in ><> in the future as well. \$\endgroup\$ Commented Nov 16, 2022 at 10:32
1
\$\begingroup\$

BQN, 30 bytes

1↓·∾≠⊸⥊⟜"-_"∾¨-⟜32⌾⊏⌾⌽¨⌾(¯1⊸↓)

Try it here!

Explanation

  • ...¨⌾(¯1⊸↓) for each non-last word of the input...
    • -⟜32⌾⊏⌾⌽ uppercase last letter (literally by reversing and subtracting 32 from the first char)
  • ≠⊸⥊⟜"-_"∾¨ couple each word with alternations of - and _
  • 1↓·∾ join and drop first character
\$\endgroup\$
1
\$\begingroup\$

sed w/ -E flag, 43 bytes

s/(.) /\U\1_/g
s/([^_]*_){2}/\0-/g
s/_-/-/g

Attempt This Online!

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

Ly, 25 37 bytes

i0"_-"rsp[' =:' *lf-o[Ifprfr0]psp]>lo

Try it online!

Revised code... I didn't read the rule saying space has to be translated to - and _ alternating.

i                                     - read input as codepoints
 0"_-"                                - push "0" and delimiters
      r                               - reverse stack
       sp                             - save last and delete
         [                      p]    - loop over the 2-N chars
          ' =                         - push 0|1 from comparing curr char to " "
             :                        - duplicate result
              ' *                     - multiply result w/ " " (32)            
                 lf                   - pull prev char, flip top stack entries
                   -                  - capitalizes if the curr char is " "
                    o                 - write out char codepoint as a char
                     [      0]p       - if/then, true if " " is curr char
                      I               - copy second to bottom stack entry                fp             - pull " " forward, delete
                         rfr          - reverse bottom two entries
                               s      - stash "_" or "-"
                                  >   - switch stacks
                                   lo - load last char and print
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Your output only contains _, instead of alternating between _ and -. \$\endgroup\$ Commented Jun 21, 2022 at 6:42
  • \$\begingroup\$ Yikes! I missed that in the contest description... I'll remove the entry until I can fix it. \$\endgroup\$
    – cnamejj
    Commented Jun 21, 2022 at 9:24
1
\$\begingroup\$

PowerShell Core, 154 bytes

filter f([char[]]$r){$s="_","-"
($r|%{[string]$c=$_
if(" "-eq$r[$i+1]){$c.ToUpper()}elseif(" "-eq$_){$s[$x+0]
$x=($x+1)%2}else{$c.ToLower()}$i++})-join''}

Try it online!

Ungolfed:

filter f (
    [char[]]$r                     # coerce input string to character array
) {
    $s = "_","-"                   # initialize space array to replace " " with "_" and "-"
    (                              # () needed for -join '' 
        $r | ForEach-Object{
            [string]$c=$_          # [char] lacks .ToUpper(), .ToLower() - coerce back to [string] 
            if(" " -eq $r[$i+1]){  # if next character in array is a space
                $c.ToUpper()       # RETURN uppercase
            }
            elseif(" " -eq $_){    # if space is the current character
                $s[$x+0]           # RETURN indexof space array. incl. "+0" in the index depth so we don't need to initialize $x
                $x=($x+1)%2        # x++ but modulus 2
            }
            else{
                $c.ToLower()       # RETURN lowercase
            }
            $i++                   # increment $i for lookahead
         }
     )-join''                      # [char[]] back to [string]. implicit RETURN from function
 }
\$\endgroup\$
1
1
\$\begingroup\$

Pip, 20 bytes

aR`. `{UC@a."_-"@Uv}

Takes input as a single command-line argument with words space-separated. Attempt This Online!

Explanation

aR`. `{UC@a."_-"@Uv}
a                     Command-line argument
 R                    Replace
  `. `                matches of this regex: any character followed by a space
      {            }  With this callback function:
          a             The matched string
         @              's first character
       UC               Uppercased
           .            Concatenated to
                  v       A number, initially -1
                 U        Increment
                @         and use as a cyclical index into
            "_-"          That string
\$\endgroup\$
0
\$\begingroup\$

Ruby -p, 39 bytes

gsub(/(.) /){$1.upcase+"_-"[($.+=1)%2]}

Attempt This Online!

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

Japt, 18 bytes

®ou qÃov
ò mq'_ q-

Try it

Input as an array of character arrays.

Explanation:

®ou qÃov  
®    Ã    # For each word in the input:
 ou       #  Convert the last letter to uppercase
    q     #  Join to a string
      o   # For the last word:
       v  #  Convert it to lowercase
          # Save as U

ò mq'_ q- 
ò         # Cut U into pairs of words
  m       # For each pair:
   q'_    #  Join to a single string with "_" in between
       q- # Join all those strings with "-" between
\$\endgroup\$
0
\$\begingroup\$

Japt -hP, 16 bytes

Takes input as a 2D character array.

ÇiUËouÃíUî"_-"¹c

Try it

ÇiUËouÃíUî"_-"¹c     :Implicit input of 2D character array U
Ç                    :Pop last element, pass it through the following function & push back
 i                   :  Prepend
  UË                 :    Map the remaining elements of U
    o                :      Modify last
     u               :        Uppercase
      Ã              :    End map
       í             :    Interleave
        Uî"_-"       :      Mould "_-" to length of U
              ¹      :  End prepend
               c     :  Flatten
                     :Implicitly join and output last element
\$\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.