DEV Community

The DEV Team

Daily Challenge #34 - WeIrD StRiNg CaSe

thepracticaldev profile image staff ・1 min read

The goal of this challenge is to write a function that accepts a string and returns the same string with all even indexed characters uppercased and all odd indexed characters lowercased.

This indexing should be zero-based with the index in position zero being considered even. The input string will consist of only alphabetical characters and spaces. Spaces should only be present when there are multiple words.

to_weird_case('String'); # => returns 'StRiNg'
to_weird_case('Weird string case') # => returns 'WeIrD StRiNg CaSe'

Happy coding~!

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

Want to propose a challenge for a future post? Email with your suggestions!

Discussion (31)

Editor guide
ynndvn profile image
La blatte

Here goes a simple oneliner:


And the result:

toWeirdCase('String'); // "StRiNg"
toWeirdCase('Weird string case'); // "WeIrD StRiNg cAsE"
dance2die profile image
Sung M. Kim

I believe case should be printed as CaSe as first letter (index 0) should be always capitalized.

ynndvn profile image
La blatte

Indeed! Didn't catch that! Here is a little fix for that:

toWeirdCase=(a)=>a.split` `.map(s=>[...s].map((e,i)=>i%2?e.toLowerCase():e.toUpperCase()).join``).join` `;

which output is:

toWeirdCase('String'); // "StRiNg"
toWeirdCase('Weird string case'); // "WeIrD StRiNg CaSe"
kenbellows profile image
Ken Bellows

Index 0 refers to the first letter of the entire string; we don't need to consider each word separately, just the string as a whole

Thread Thread
dance2die profile image
Sung M. Kim

Sorry about that.
I meant it as index 0 of each word.

the example shows the result should be

to_weird_case('Weird string case') # => returns 'WeIrD StRiNg CaSe'
Thread Thread
kenbellows profile image
Ken Bellows • Edited

Ah, you're right, that's interesting. I hadn't noticed that discrepancy with the capital 'C' in 'CaSe'; that makes this a more interesting challenge!

The original post should probably call that out a little more clearly, because it raises additional questions: Should punctuation count as a word separator? e.g., should 'word-other' become 'WoRd-oThEr' or 'WoRd-OtHeR'? Or should we only worry about letters and spaces? What characters are we considering?

@thepracticaldev , any help here?

Thread Thread
dance2die profile image
Sung M. Kim

For some reason, CodeWars isn't loading for me so won't be able to check the edge cases... 🤔

inrsaurabh profile image
Saurabh Ranjan

In Js ( Many Optimised solutions are already given, just tried different way)

const to_weird_case = (string) => {
    let  newString = [];
    for( let i in string ) {
        if(i%2 == 0){
        } else {
    return newString.join('');

to_weird_case('Weird string case');
kenbellows profile image
Ken Bellows • Edited

Python solution:

toWeirdCase = lambda s: ''.join([c.lower() if i%2 else c.upper() for i,c in enumerate(s)])

print(toWeirdCase('String')) #=> StRiNg
print(toWeirdCase('Weird string case')) #=> WeIrD StRiNg cAsE

@dance2die pointed out in this comment that the multi-word example in the post seems to suggest that each word should be considered and cased separately, rather than the whole string. In that case, this becomes a bit more interesting.

Here's a simple modification to account only for spaces separating words:

toWeirdCase = lambda s: ' '.join([wordToWeirdCase(w) for w in s.split(' ')])
wordToWeirdCase = lambda s: ''.join([c.lower() if i%2 else c.upper() for i,c in enumerate(s)])

print(toWeirdCase('String')) #=> StRiNg
print(toWeirdCase('Weird string case')) #=> WeIrD StRiNg CaSe

But this could get a lot more complex if we need to account for things like punctuation and other whitespace characters.

As one last example, here's one that handles alternative whitespace characters using regular expressions:

import re

toWeirdCase = lambda s: (
  s['\S', s).start() if re.match(r'\s', s) else 0] +   # handle leading whitespace
    [wordToWeirdCase(w) for w in re.findall(r'\S+(?:\s+)?', s)]

wordToWeirdCase = lambda s: ''.join([c.lower() if i%2 else c.upper() for i,c in enumerate(s)])

print(toWeirdCase('String')) #=> 'StRiNg'
print(toWeirdCase('Weird string case')) #=> 'WeIrD StRiNg CaSe'
print(toWeirdCase('  hELLO world\tHOW\'S EVeryTHInG???')) #=> '  HeLlO WoRlD   HoW'S EvErYtHiNg???'
andy profile image
Andy Zhao (he/him)

Ruby, not optimal 🙃

def to_weird_case(string)
  if string.include? " "
    string.split(" ").map { |word| word.split("") }.each do |letter_array|
      letter_array.each_with_index do|letter, index|
        letter.upcase! if index % 2 == 0 }}.map(&:join).join(" ")
    string.split("").each_with_index do |letter, index|
      letter.upcase! if index % 2 == 0
alvaromontoro profile image
Alvaro Montoro • Edited


function formatText(message) {
    return message.split(" ")
                  .map(function(el) {
                    return el.split('')
                             .map(function(letter, idx) {
                               return idx % 2 === 0 ? letter.toLowerCase() : letter.toUpperCase();
                  .join(' ')

And as an extension, I used that function to create a Sponge Bob Mocking meme generator! (which is the first thing that I thought when I saw the challenge)

laurentiumolnar profile image

A simple solution in Javascript:

function toWeirdCase(string) {
  return string.split(' ')
    .map(word => {
      return word.split('')
        .map((char, index) => {
          if (index % 2 === 0) return char.toUpperCase()
          return char
    .join(' ')

console.log(toWeirdCase('Weird string  case'))
itsasine profile image
ItsASine (Kayla)

At work, we just call this serial killer case :P

brightone profile image
Oleksii Filonenko


defmodule Case do
  require Integer

  def weird(string) do
    |> String.graphemes()
    |> Enum.with_index()
      {char, i} when Integer.is_even(i) -> String.upcase(char)
      {char, _} -> String.downcase(char)
    |> Enum.join()
peter279k profile image

Here is the simple solution with PHP:

function toWeirdCase($string) {
    $strings = explode(' ', $string);

    $stringsIndex = 0;
    foreach ($strings as $string) {
      $index = 0;
      for (; $index < strlen($string); $index++) {
        if ($index % 2 === 0) {
          $string[$index] = strtoupper($string[$index]);
        } else {
          $string[$index] = strtolower($string[$index]);

      $strings[$stringsIndex] = $string;

    return implode(' ', $strings);
sebvaldez profile image

Heres my ruby example

def to_weird_case (str)
  raise "Incorrect input, expected String" if str.class != String
  str.split(/\s/).map{|w|{|c,i| i%2==0 ? c.upcase : c }.join }.join(' ')


to_weird_case('string') => "StRiNg"
to_weird_case('Weird string case') => "WeIrD StRiNg CaSe"
devparkk profile image
Dev Prakash • Edited
def weird_string (string) :
    result = ""
    for index in range(len(string)) :
        if index % 2 == 0 :
            result += string[index].upper()
        else :
            result += string[index].lower()
    return result

print (weird_string("Weird string case"))

Python one liner

def weird_string (string) :
    result = ("").join([string[i].lower() if i%2 else string[i].upper() for i in range(len(string))])
    return result

print(weird_string("Weird string case"))

kvharish profile image
K.V.Harish • Edited

My solution in js

const toWeirdCase = (str = '') => (str.split(' ').map((s) => ([...s].map((char, index) => (index % 2) ? char.toLowerCase() : char.toUpperCase())).join(''))).join(' ');
dance2die profile image
Sung M. Kim

I've implemented based off of La blatte's answer.

const caser = {
  0: c => c.toUpperCase(),
  1: c => c.toLowerCase()   
const mod = i => i % 2
const weirdCase = text => text.split(' ').map(word => 
    [...word].map((c, i) => caser[mod(i)](c)).join('')
).join(' ')

console.log(["String", "Weird string case"].map(weirdCase))


["StRiNg", "WeIrD StRiNg CaSe"]
kerrishotts profile image
Kerri Shotts

Here's mine -- I'll admit that it took a little to recognize that the index was supposed to be word-based, not for the entire string. But that's what test cases are for! :-)

    LOWER: String.prototype.toLowerCase,
    UPPER: String.prototype.toUpperCase

const transform = (v, which) => which.apply(v);

const weirdCase = str => 
 str.split(" ")
    .map((part) => Array.from(part)
                        .map((ch, idx) => transform(ch, idx & 1 ? TRANSFORMER.LOWER 
                                                                : TRANSFORMER.UPPER ))
    .join(" ");


tanguyandreani profile image
Tanguy Andreani • Edited

Ruby solution. Doesn’t use modulo.

Works with the strange edge case. Also sorry typed on tablet.

str = "Weird ,string case."

class << str
  def to_weird_case do |s|
      i = 0

      while i < self.length
        # work out with edge case
        if self[i] =~ /[^a-zA-Z]/
          s << self[i]
          i += 1

        # we add to_s because we may be out of bounds;
        # that way we get the empty string instead of nil
        # and an exception
        s << self[i].to_s.upcase
        s << self[i + 1].to_s.downcase
        i += 2

hanachin profile image
Seiei Miyagi
def to_weird_case(s) s.split(' ').map {
 { @2.even? ? @1.upcase : @1.downcase }.join }.join(' ') end
andy profile image
Andy Zhao (he/him)

Ah I tried map_with_index but that's not a method. Did not know there was a .map.with_index!

hanachin profile image
Seiei Miyagi

I'm glad to hear that. Enumerable has so many methods, which is useful but I take a little bit time to remember them.

room_js profile image
JavaScript Room

Solution in Dart. Simple and not the shortest one, I guess. But it works =)

toWeirdCase(String str) {
  var result = new List();

  for (int i = 0; i < str.length; i++) {
    result.add(i%2 == 0 ? str[i].toUpperCase() : str[i].toLowerCase());
  return result.join();

Link to the playground:

itsdarrylnorris profile image
Darryl Norris



 * Daily Challenge #34 - WeIrD StRiNg CaSe
 * @param  string $string
 * @return string
function toWeirdCase(string $string): string
  return implode(" ",array_map(function($word) {
    $splitWord = str_split($word);
    return implode("", array_map(function($value, $key) {
      return ($key % 2 === 0) ? strtoupper($value) : strtolower($value);
    }, $splitWord, array_keys($splitWord)));

  }, explode(" ", $string)));

echo toWeirdCase('Weird string case');
// Output: WeIrD StRiNg CaSe

craigmc08 profile image
Craig McIlwrath


import Data.Char (toLower, toUpper)
import Control.Applicative

toWeirdCase :: String -> String
toWeirdCase = unwords . map weirdifier . words
              where weirdifier = getZipList
                               . (ZipList [if even i then toUpper else toLower | i <- [0..]] <*>)
                               . ZipList

I used applicative functors here mostly for fun. I think it looks nicer to define weirdifier as

weirdifier = zipWith (\i -> if even i then toUpper else toLower) [0..]
hectorpascual profile image
Héctor Pascual

Python with a function :

def to_weird_case(string):
    weird_string = ''
    i = 0
    for c in string.lower():
        if i%2:
            weird_string += c
            weird_string += c.upper()
        i += 1
    return weird_string

One liner with list comprehension :

weird_case = ''.join([string[i].lower() if i%2 else string[i].capitalize() for i in range(0,len(string))])

carmenhchung profile image
Carmen Chung

Hey! We loved this challenge and actually got three developers to live code a solution in 15 minutes (with commentary):

We also release similar videos every week on other Javascript, HTML/CSS, Python and Ruby challenges, so don't forget to like and subscribe if you're interested! ♥️

dbalseiro profile image
Diego Balseiro

Here is a little Haskell one-liner

import Data.Char (toUpper, toLower)

toWeirdCase :: String -> String
toWeirdCase = unwords . map (zipWith ($) (cycle [toUpper, toLower])) . words
shaber profile image
ShaBer • Edited

A JS single line solution that works with multi-line texts:

Enter fullscreen mode Exit fullscreen mode