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 code-golf, 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
-
\$\begingroup\$ Can we take the words as an underscore-delimited string? \$\endgroup\$Adám– Adám2022年06月20日 22:27:12 +00:00Commented 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– emanresu A2022年06月20日 22:31:56 +00:00Commented 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– tsh2022年06月21日 02:56:10 +00:00Commented Jun 21, 2022 at 2:56
-
1\$\begingroup\$ mmmm, snake kebab \$\endgroup\$htmlcoderexe– htmlcoderexe2022年06月21日 12:53:09 +00:00Commented 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– emanresu A2022年06月21日 22:16:45 +00:00Commented Jun 21, 2022 at 22:16
28 Answers 28
Python, 72 bytes
lambda s:re.sub(" (.*?) ",r"_1円-",s+"x ")[::-1].title()[:1:-1]
import re
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.
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)
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()
-
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\$Samathingamajig– Samathingamajig2022年06月21日 18:30:06 +00:00Commented 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– Arnauld2022年06月21日 22:22:22 +00:00Commented Jun 21, 2022 at 22:22
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).
JavaScript, 52 bytes
-3 bytes by emanresu A; -2 bytes by Arnauld.
s=>s.replace(/. /g,c=>c[0].toUpperCase()+'-_'[s^=1])
-
\$\begingroup\$ Save a byte with
^=\$\endgroup\$emanresu A– emanresu A2022年06月21日 02:55:39 +00:00Commented Jun 21, 2022 at 2:55 -
\$\begingroup\$ Another two with type abuse \$\endgroup\$emanresu A– emanresu A2022年06月21日 02:57:27 +00:00Commented Jun 21, 2022 at 2:57
-
\$\begingroup\$ @Arnauld Not ever noticed that after rerun. Thanks for pointing out this. \$\endgroup\$tsh– tsh2022年06月21日 09:11:04 +00:00Commented Jun 21, 2022 at 9:11
Vyxal s, 12 bytes
ṫ$RǐR5‛_-ẎYp
-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
-
\$\begingroup\$ 12 \$\endgroup\$emanresu A– emanresu A2022年06月20日 22:34:20 +00:00Commented Jun 20, 2022 at 22:34
APL (Dyalog Extended), 25 bytes
Anonymous tacit prefix function. Takes list of words.
1⌊⍢⊃⍤↓⍢⌽∘∊⌈⍢⊃⍢⌽ ̈, ̈'_-'⍴⍨≢
≢ 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
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)
Python, (削除) 86 (削除ここまで) 80 bytes
lambda s,i=0:"".join("_-"[i:=~i]+w.title()for w in s[::-1].split())[:1:-1]+s[-1]
-6 bytes thanks to @xnor
-
1\$\begingroup\$ It looks like
(i:=i<1)can bei:=~i. The current version of Python has improved parsing so that the parens aren't required there. \$\endgroup\$xnor– xnor2022年06月20日 22:12:52 +00:00Commented Jun 20, 2022 at 22:12 -
\$\begingroup\$ Oh that's a good improvement, I should probably update Python on my PC... \$\endgroup\$jezza_99– jezza_992022年06月20日 22:19:06 +00:00Commented Jun 20, 2022 at 22:19
-
1\$\begingroup\$ Saving a few bytes with
.title()\$\endgroup\$xnor– xnor2022年06月20日 22:23:22 +00:00Commented Jun 20, 2022 at 22:23
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.
-
\$\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\$Daniel Schepler– Daniel Schepler2022年06月21日 02:24:23 +00:00Commented 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– Neil2022年06月21日 08:11:57 +00:00Commented 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– Neil2022年06月21日 09:18:23 +00:00Commented Jun 21, 2022 at 9:18
MathGolf, 19 bytes
mxδmxhû_-*▒^\£<─~;!
Input as a list of words.
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)
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"))
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]
-
1\$\begingroup\$ Welcome to Code Golf, and nice first answer! You can remove the space between ] and for. \$\endgroup\$emanresu A– emanresu A2022年06月24日 20:04:42 +00:00Commented Jun 24, 2022 at 20:04
QuadR 2g, (削除) 37 (削除ここまで) (削除) 30 (削除ここまで) 29 bytes
Takes space-separated words.
(\S)
_(.*)(\S)_
\u1_
_1円\u2-
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 |
Zsh, 61 bytes
g()<<<${${4+${3%?}${3[-1]:u}1ドル`g 2ドル 1ドル ${@:4}`}:-3ドル}
g _ - $@
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
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:]
-
1\$\begingroup\$
$|--?$/:_can be written as< r>^$/\$\endgroup\$Sisyphus– Sisyphus2022年06月30日 06:52:12 +00:00Commented Jun 30, 2022 at 6:52
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);}
><>, (削除) 32 (削除ここまで) 30 bytes
55*ii:48*=?\$o30.
-{:0$-}"F"+\
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
-
1\$\begingroup\$ How the hell did you make ><> so competitive???? \$\endgroup\$TwilightSparkle– TwilightSparkle2022年11月16日 09:12:20 +00:00Commented 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– Emigna2022年11月16日 09:24:05 +00:00Commented 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\$TwilightSparkle– TwilightSparkle2022年11月16日 10:32:31 +00:00Commented Nov 16, 2022 at 10:32
BQN, 30 bytes
1↓·∾≠⊸⥊⟜"-_"∾ ̈-⟜32⌾⊏⌾⌽ ̈⌾( ̄1⊸↓)
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
Ly, (削除) 25 (削除ここまで) 37 bytes
i0"_-"rsp[' =:' *lf-o[Ifprfr0]psp]>lo
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
-
1\$\begingroup\$ Your output only contains
_, instead of alternating between_and-. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2022年06月21日 06:42:44 +00:00Commented 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– cnamejj2022年06月21日 09:24:21 +00:00Commented Jun 21, 2022 at 9:24
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''}
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
}
-
\$\begingroup\$ Welcome! Code-golf is a competition to solve a particular problem in the fewest bytes of source code. See also Tips for golfing in PowerShell. \$\endgroup\$mazzy– mazzy2022年06月22日 15:38:14 +00:00Commented Jun 22, 2022 at 15:38
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
Japt -hP, 16 bytes
Takes input as a 2D character array.
ÇiUËouÃíUî"_-"1c
Ç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
Japt, 18 bytes
®ou qÃov
ò mq'_ q-
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