# Daily Challenge #210 - Separate Capitalization

Given a string, capitalize the letters that occupy even indexes and odd indexes separately, and return as shown below. Index 0 will be considered even.

For example, capitalize("abcdef") = ['AbCdEf', 'aBcDeF']. The input will be a lowercase string with no spaces.

#### Tests

capitalize("dev")
capitalize("method")
capitalize("hello")

Good luck!

This challenge comes from kenkamau on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Posted on by:

### dev.to staff

The hardworking team behind dev.to ❤️

### Discussion

Python 3.8+ solution (bc type hints) using nested function and enumeration.

from typing import List, Literal

def capitalize(text: str) -> List[str]:
def _change_case(text: str, posi: Literal["even", "odd"]):
# Default to even index
remainder = {"odd": 1}.get(posi, 0)
return  "".join(
v.upper() if i % 2 == remainder else v
for i, v in enumerate(text)
)

return [_change_case(text, "even"), _change_case(text, "odd")]


Alternate Python 3.6+ (ish?) version that uses a lambda function and functools.partial. This was my initial idea and I finally got it. 😅

from functools import partial
from typing import Tuple

def capitalize(text: str) -> Tuple[str, str]:
# Create a lambda function that performs the casing
_changer = lambda text, change_even: "".join(
v.upper() if i % 2 != int(change_even) else v
for i, v in enumerate(text)
)

# Produce a partial function that prefills the given text
_change_even_casing = partial(_changer, text)

# Using our partial function, alter the strings
return (_change_even_casing(True), _change_even_casing(False))


If you return like this return _change_even_casing(True), _change_even_casing(False) python will understand that it's already a tuple

Oh, I know. I put the parenthesis because it helps me better understand what is happening. 😉😉

SQL:

[local] dian#dian= WITH seq AS (
SELECT regexp_split_to_table('string', '') AS c
), capitalized AS (
SELECT
CASE
WHEN row_number() OVER () % 2 = 0 THEN upper(c)
ELSE lower(c)
END AS even,
CASE
WHEN row_number() OVER () % 2 = 1 THEN upper(c)
ELSE lower(c)
END AS odd
FROM seq
)
SELECT
string_agg(even, '') AS even,
string_agg(odd, '') AS odd
FROM capitalized;
even  │  odd
────────┼────────
sTrInG │ StRiNg
(1 row)

Time: 0.613 ms


Break the string down into a table with one character per row, use the row_number window function to capitalize it each way, then reassemble the final product; the latter two steps can't be combined because window functions can't be nested in aggregate functions.

The split to rows + window function approach is 🥰

## Scala

A good old fold and I use the Next type to know which side to capitalize next.

sealed trait Next
case object Left extends Next
case object Right extends Next

def capitalize (str: String): (String, String) = {
val (l, r, _) = str.foldLeft(("", "", Left: Next)) {
case ((l, r, n), c) => n match {
case Left  => (l :+ c.toUpper, r :+ c.toLower, Right)
case Right => (l :+ c.toLower, r :+ c.toUpper, Left)
}
}
(l, r)
}

println(capitalize("abcdef")) // ("AbCdEf", "aBcDeF")


function capitalize(str) {
return str.split("").reduce((acc, cur, i) => {
const
odd = i % 2,
upper = cur.toUpperCase();
acc[0] += !odd ? upper : cur;
acc[1] += odd ? upper : cur;
return acc;
}, ["", ""]);
}


Interesting JS solution....I haven't seen ternary operators used so haphazardly before, I'm not comfortable with them still.

Elm

Note: returning a tuple because returning a List String would mean it can be a list of 0 element as it can be a list of 10, 100, 1000, Infinity elements. Returning a Tuple gives the information to the user that this function will always return two elements in this case, which is suggested by the goal of this challenge. It will be then possible to extract them easily with the Tuple.first & Tuple.second functions.

even : Int -> Bool
even integer =
modBy 2 integer == 0

odd : Int -> Bool
odd integer =
not <| even integer

upperIf : ( Int -> Bool ) -> Int -> Char -> Char
upperIf predicate index character =
if predicate index then
Char.toUpper character

else
character

capitalizeIf : ( Int -> Bool ) -> String -> String
capitalizeIf predicate string =
string
|> String.toList
|> List.indexedMap ( upperIf predicate )
|> String.fromList

capitalize : String -> ( String, String )
capitalize string =
( capitalizeIf even string, capitalizeIf odd string )


This is a hallmark of proper functional programming. Elm looks intimidating than more traditional grammars but it's essentially strongly-typed function composition. I love it, and the outer function reads like english.

I won't lie, since this was my first real functional programming language, it was tough, really tough. And this is essentially due to the fact that I was not used to no parens (or not at the same position at least) and function composition mainly.

But functional programming is like a muscle. The best competitors are working hard to obtain a great physical condition. This is the same thing for people like you and me that are used to procedural or oriented-object programming. It requires a lot of practices to get out of our habits.

But when you practiced enough, you'll start to love functional programming and that is the only certainty you have. The rest is up to you. And actually, since I'm a Web Developer, and doing most of my stuff in JavaScript at work (I hope I get to include Elm one day) this has made me a better overall JavaScript developer. There is no time wasted on learning this language, trust me.

Kinda silly solution using 2 mutually recursive functions (Haskell)

import Data.Char (toUpper, toLower)

skip :: String -> String
skip [] = []
skip (c:cs) = c : capitalize' cs

capitalize' :: String -> String
capitalize' [] = []
capitalize' (c:cs) = toUpper c : skip cs

capitalize :: String -> (String, String)
capitalize cs = (capitalize' cs, skip cs)


Ooh, clever! I like it!

I'm a bit late to the party, but here's my Elixir solution:

defmodule Letters do
import Integer, only: [ is_even: 1, is_odd: 1 ]

def capitalise(str) do
str
|> String.split("", trim: true)
|> Enum.with_index
|> Enum.map(&_mapper/1)
|> Enum.unzip
|> _join
end

defp _mapper({ letter, idx })
when is_even(idx) do
{ String.capitalize(letter), String.downcase(letter) }
end
defp _mapper({ letter, idx })
when is_odd(idx) do
{ String.downcase(letter), String.capitalize(letter) }
end
defp _join({ a, b }), do: { Enum.join(a), Enum.join(b) }
end


Here's a fun little OCaml version:

open Base

let capitalize s =
String.to_list s
|> List.mapi ~f:(fun i c ->
if i % 2 = 0
then Char.(uppercase c, lowercase c)
else Char.(lowercase c, uppercase c))
|> List.unzip
|> fun (a, b) -> String.of_char_list a, String.of_char_list b


#!/bin/sh

ARR=$(seq 0$(( ${#1} - 1 ))) LOWER=$(echo "$1" | tr '[:upper:]' '[:lower:]') for x in$ARR; do
(( $x % 2 == 0 )) && ARR_EVEN+=$(echo "${LOWER:$x:1}" | tr '[:lower:]' '[:upper:]') || ARR_EVEN+=$(echo "${LOWER:$x:1}") (($x % 2 )) && ARR_ODD+=$(echo "${LOWER:$x:1}" | tr '[:lower:]' '[:upper:]') || ARR_ODD+=$(echo "${LOWER:$x:1}")
done

echo ${ARR_EVEN[@]}${ARR_ODD[@]}


Here is some shit I wrote using shellscript

One more Python solution:

def capitalize(s: str) -> list:
cap_s_even, cap_s_odd = "", ""
for i in range(0, len(s)):
if i % 2 == 0:
cap_s_even+=s[i].upper()
cap_s_odd+=s[i]
else:
cap_s_even+=s[i]
cap_s_odd+=s[i].upper()
return [cap_s_even, cap_s_odd]


import Data.Char (toUpper)

capitalize :: String -> [String]
capitalize str = folder skipCase <\$> [("",0),("",1)] <*> pure str
where
folder fn init = fst . foldr fn init
skipCase :: Char -> (String, Int) -> (String, Int)
skipCase c (cs, i) | i mod 2 == 1 = ((toUpper c):cs, i+1)
| otherwise      = (c:cs, i+1)


The skipCase folding function takes care of upcasing every 2. letter. The folder is a makes it easier to map the function over both capitalization variations, which then can be applied to the input string.

Ruby

method = ->(s) { s.each_char.with_index.map { |c,i| [c.downcase,c.upcase].rotate(i[0])}.transpose.map(&:join)}

method.call 'dev'
=> ["dEv", "DeV"]

method.call 'method'
=> ["mEtHoD", "MeThOd"]

method.call 'hello'
=> ["hElLo", "HeLlO"]


Any Python version 2.7+.

>>> MiXeD = lambda s: ''.join(x.upper() if i&1==m else x for m in (0,1) for i, x in enumerate(s+' ')).split()
>>> MiXeD('abcdef')
['AbCdEf', 'aBcDeF']


😳 😱

This is the magic of python. Short. I just love it. 💗

var capitalize = (word) => {
const split = word.split('');
const firstWord = split.map( (a, i) => i%2 === 0 ? a.toUpperCase() : a)
const secondWord = split.map( (a, i) => i%2 !== 0 ? a.toUpperCase() : a)
return [firstWord.join(''), secondWord.join('')];
}

capitalize('abcdef')