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
asked Jun 20, 2022 at 21:24
\$\endgroup\$
8
  • \$\begingroup\$ Can we take the words as an underscore-delimited string? \$\endgroup\$ 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\$ 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\$ 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\$ 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.

answered Jun 20, 2022 at 23:19
\$\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()
answered Jun 20, 2022 at 21:58
\$\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\$ 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).

answered Jun 20, 2022 at 23:57
\$\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!

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

Vyxal s, 12 bytes

ṫ$RǐR5‛_-ẎYp

Try it Online!

-5 bytes thanks to emanresuA

How?

ṫ$RǐR5‛_-ẎYp
ṫ # Tail extract, push a[:-1] and a[-1]
 $ # Swap
 R # Reverse each
 ǐ # Capitalize first letter of each
 R # Reverse each
 5 # 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
answered Jun 20, 2022 at 21:54
\$\endgroup\$
1
  • \$\begingroup\$ 12 \$\endgroup\$ 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

answered Jun 20, 2022 at 22:30
\$\endgroup\$
4
\$\begingroup\$

Pyth, 16 bytes

ts.e+@"-_"k_r_b3

Try it online!

answered Jun 21, 2022 at 0:59
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 13 bytes

íTMí`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
 TM # 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)
answered Jun 21, 2022 at 6:56
\$\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

answered Jun 20, 2022 at 21:59
\$\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\$ Commented Jun 20, 2022 at 22:12
  • \$\begingroup\$ Oh that's a good improvement, I should probably update Python on my PC... \$\endgroup\$ Commented Jun 20, 2022 at 22:19
  • 1
    \$\begingroup\$ Saving a few bytes with .title() \$\endgroup\$ Commented Jun 20, 2022 at 22:23
3
\$\begingroup\$

Charcoal, 24 bytes

⭆θ⎇= §θ⊕κ↥ι⎇= ι§_-No...θκ ι

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
 No...θκ 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.

answered Jun 21, 2022 at 0:16
\$\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\$ 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\$ 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)
answered Jun 21, 2022 at 8:06
\$\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"))
answered Jun 21, 2022 at 9:59
\$\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]
answered Jun 24, 2022 at 7:02
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! You can remove the space between ] and for. \$\endgroup\$ 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
answered Jun 20, 2022 at 21:59
\$\endgroup\$
2
\$\begingroup\$

Factor, (削除) 89 84 (削除ここまで) 75 bytes

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

Try it online!

answered Jun 20, 2022 at 21:56
\$\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
answered Jun 21, 2022 at 14:15
\$\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!

answered Jun 24, 2022 at 4:30
\$\endgroup\$
2
\$\begingroup\$

Perl 5 + -p055, 26 bytes

s!(.) !uc1ドル.($|--?$/:_)!eg

Try it online!

answered Jun 25, 2022 at 19:09
\$\endgroup\$
1
  • 1
    \$\begingroup\$ $|--?$/:_ can be written as < r>^$/ \$\endgroup\$ 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!

answered Jun 20, 2022 at 22:16
\$\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
answered Nov 14, 2022 at 14:37
\$\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\$ 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
answered Jun 21, 2022 at 12:57
\$\endgroup\$
1
\$\begingroup\$

sed w/ -E flag, 43 bytes

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

Attempt This Online!

answered Jun 21, 2022 at 13:29
\$\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
answered Jun 21, 2022 at 3:15
\$\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\$ 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
 }
answered Jun 22, 2022 at 14:57
\$\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
answered Jun 22, 2022 at 17:45
\$\endgroup\$
1
\$\begingroup\$

Ruby -p, 39 bytes

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

Attempt This Online!

answered Nov 14, 2022 at 16:31
\$\endgroup\$
1
\$\begingroup\$

Japt -hP, 16 bytes

Takes input as a 2D character array.

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

Try it

ÇiUËouÃíUî"_-"1c :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
 1 : End prepend
 c : Flatten
 :Implicitly join and output last element
answered Nov 15, 2022 at 11:00
\$\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
answered Nov 14, 2022 at 21:46
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.