DEV Community 👩‍💻👨‍💻 staff staff

Posted on

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.



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 with your suggestions!

Top comments (23)

aminnairi profile image
Amin • Edited on


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


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

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

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.

aminnairi profile image
Amin • Edited on

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.

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

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

avalander profile image
Avalander • Edited on


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")
dmfay profile image
Dian Fay


[local] dian#dian= WITH seq AS (
  SELECT regexp_split_to_table('string', '') AS c
), capitalized AS (
      WHEN row_number() OVER () % 2 = 0 THEN upper(c)
      ELSE lower(c)
    END AS even,
      WHEN row_number() OVER () % 2 = 1 THEN upper(c)
      ELSE lower(c)
    END AS odd
  FROM seq
  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.

craigmc08 profile image
Craig McIlwrath

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) 
avalander profile image

Ooh, clever! I like it!

savagepixie profile image
SavagePixie • Edited on

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
      |> String.split("", trim: true)
      |> Enum.with_index
      |> Enum.unzip
      |> _join

  defp _mapper({ letter, idx })
    when is_even(idx) do
      { String.capitalize(letter), String.downcase(letter) }
  defp _mapper({ letter, idx })
    when is_odd(idx) do
      { String.downcase(letter), String.capitalize(letter) }
  defp _join({ a, b }), do: { Enum.join(a), Enum.join(b) }
ksyula profile image
Ksenia • Edited on

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:
    return [cap_s_even, cap_s_odd]
lordapple profile image

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}")

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

Here is some shit I wrote using shellscript

nilbert profile image


method = ->(s) { { |c,i| [c.downcase,c.upcase].rotate(i[0])}} 'dev'
=> ["dEv", "DeV"] 'method'
=> ["mEtHoD", "MeThOd"] 'hello'
=> ["hElLo", "HeLlO"]
cipharius profile image
Valts Liepiņš

Solution in Haskell using folding:

import Data.Char (toUpper)

capitalize :: String -> [String]
capitalize str = folder skipCase <$> [("",0),("",1)] <*> pure str
    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.

jhermann profile image
Jürgen Hermann • Edited on

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']

😳 😱

muhimen123 profile image

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

rafaacioly profile image
Rafael Acioly

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

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

Image description

Join the One Year Club

You can earn this badge by being a registered member of the DEV Community for at least one year. Create an account and get started today.