DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #263 - Reverse Words

Complete the function that accepts a string parameter, and reverses each word in the string. All spaces in the string should be retained.

Examples
"This is an example!" ==> "sihT si na !elpmaxe"
"double spaces" ==> "elbuod secaps"

Tests
reverseWords("The quick brown fox jumps over the lazy dog.")
reverseWords("double spaced words")

Good luck!


This challenge comes from jnicol 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!

Top comments (34)

Collapse
 
astagi profile image
Andrea Stagi

For Python, one line

def reverse_words(sentence: str) -> str:
    return ' '.join(sentence.split(' ')[::-1])[::-1]
Collapse
 
rafaacioly profile image
Rafael Acioly

Well done! It could also be

return ' '.join(word[::-1] for word in sentence.split() if not word.isspace())
Collapse
 
agtoever profile image
agtoever

I think this would fail with doubles spaces in a sentence...

Thread Thread
 
astagi profile image
Andrea Stagi • Edited

That's true :( looks like the right implementation is

def reverse_words(sentence: str) -> str:
    return ' '.join(word[::-1] for word in sentence.split())
Thread Thread
 
rafaacioly profile image
Rafael Acioly

you don't need to use (' ') to split by spaces :)

Thread Thread
 
astagi profile image
Andrea Stagi

That's what happens when you write too much js code 😅 edited thanks!

Collapse
 
astagi profile image
Andrea Stagi

Looks great :)

Collapse
 
aminnairi profile image
Amin • Edited

Haskell

import Data.List.Split (split, oneOf)


reverseWords :: String -> String
reverseWords = concatMap reverse . split (oneOf " ")


main :: IO ()
main = do
    print $ reverseWords "One space"        -- "enO ecaps"
    print $ reverseWords "Two  spaces"      -- "owT  secaps"
    print $ reverseWords "Three   spaces"   -- "eerhT   secaps"
Collapse
 
olekria profile image
Olek Ria

Very elegant.

Collapse
 
oleksandrriabukha profile image
Oleksandr Riabukha

Without libraries:
reverseWords = unwords . map reverse . words

Collapse
 
aminnairi profile image
Amin • Edited

This looks very clean, well done. I think I would have gone for that one if keeping spaces wasn't an issue, but it is in this challenge.

The second code example from this post is wrong in the sense that spaces must be kept, and only a few provided solutions here are working because the example was not clear enough on what was expected.

- "double spaces" ==> "elbuod secaps"
+ "double  spaces" ==> "elbuod  secaps"

I always lookup for the original challenge in Codewars to get a better specification to what I'm supposed to provide as a valid solution.

Original challenge specification.

Collapse
 
dry profile image
Hayden Mankin

Javascript

let reverseWords = (str) => str.replace(/\S+/g, word => [...word].reverse().join(""));

console.log(reverseWords("The quick brown fox jumps over the lazy dog.")); // ehT kciuq nworb xof spmuj revo eht yzal .god
console.log(reverseWords("double spaced words")); // elbuod decaps sdrow
console.log(reverseWords("🞀🞁🞂🞃")); // 🞃🞂🞁🞀

I avoided split("") as it breaks with non BMP characters. The spread operator works just as well for splitting strings into individual characters and won't break astral characters.

Notice how if I use split the output is messed up on my last test case.

let reverseWords = (str) => str.replace(/\S+/g, word => word.split("").reverse().join(""));

console.log(reverseWords("The quick brown fox jumps over the lazy dog.")); // ehT kciuq nworb xof spmuj revo eht yzal .god
console.log(reverseWords("double spaced words")); // elbuod decaps sdrow
console.log(reverseWords("🞀🞁🞂🞃")); // �🞂🞁🞀�
Collapse
 
hungthai1401 profile image
Thai Nguyen Hung

For php

function reverseWords($words) {
    $pattern = '/\S+/';
    return preg_replace_callback(
        $pattern,
        function ($word) {
            return strrev($word[0]);
        },
        $words
    );
}

echo reverseWords('The quick brown fox jumps over the lazy dog.');
echo reverseWords('double spaced words');
Collapse
 
sam_ferree profile image
Sam Ferree

Befunge-93

This version current works if the end of input pushes -1 on the stack (due to the interpreter I used), change 3 characters and it works for a carriage return

0v
 >~:01--!#v_:84*-!   #v_
 ^        >$84*>,:#v_@>,:#v_
               ^   <  ^   <
Collapse
 
chrsgrrtt profile image
Chris Garrett

ES6:

const reverseWords = (sentence) =>
  sentence
    .split(" ")
    .map((word) => [...word].reverse().join(""))
    .join(" ");

console.log(reverseWords("This is an example!"));
console.log(reverseWords("double  spaces"));
Collapse
 
boris profile image
Boris Quiroz

More python:

def reverseWords(words):
    r = ""
    for word in words.split():
        r += "{} ".format(word[::-1])

    print(r)

reverseWords("The quick brown fox jumps over the lazy dog.")
reverseWords("double spaced words")
Collapse
 
peter279k profile image
peter279k • Edited

Here are the PHP codes about using foreach and for loops to complete:

function reverseWords($str) {
  $strArray = explode(' ', $str);
  $reveresedArray = [];

  foreach($strArray as $string) {
    $reversedStr = '';
    for($index=strlen($string)-1; $index>=0; $index--) {
       $reversedStr .= $string[$index];
    }

    $reversedArray[] = $reversedStr;
  }

  return implode(' ', $reversedArray);
}
Collapse
 
dancouper profile image
Dan Couper • Edited

JavaScript (imperative & linear):

function reverseWords(str) {
  let wordbuf = "";
  let outbuf = "";

  for (let char of str) {
    // NOTE replace with `if (/\s/.test(char))`
    // if anything other than ASCII whitespace
    // char expected
    if (char === " ") {
      outbuf += (wordbuf + char);
      wordbuf = "";
    } else {
      wordbuf = char + wordbuf;
    }
  }
  outbuf += wordbuf;

  return outbuf;
}
Collapse
 
hans5958 profile image
Hans5958 • Edited

JavaScript (ES6) (golf)

const reverseWords = i=>i.split` `.map(w=>w.split``.sort(_=>1).join``).join` `
const reverseWords = i=>i.replace(/\w+/g,w=>[...w].sort(_=>1).join``)
Collapse
 
k776 profile image
Kieran Pilkington

Or more simply:

def reverse_words(str)
  str.split.map(&:reverse).join(" ")
end
Collapse
 
shivamgsg profile image
Shivam Gupta

For Java

public static String reverseWords(final String original)
  {
     String[] arr=original.split(" ");
     if(arr.length==0)
       return original;
     String result="";
     for(String word:arr){
         StringBuilder input = new StringBuilder();
         result+=input.append(word).reverse().toString()+" ";
     }

     return result.trim();
  }
Collapse
 
agtoever profile image
agtoever

Another Python:

def reverse_words(s):
 for word in s.split():
  s = s.replace(word, word[::-1])
 return s

Try it online!

Collapse
 
tallguy_hackett profile image
Dave Hackett

For Elixir

defmodule Challenge do
  def reverse_words(words) do
    words
    |> String.split(" ", trim: false)
    |> Enum.map(&String.reverse/1)
    |> Enum.join(" ")
  end
end
Collapse
 
dom111 profile image
Dom Hastings

Perl:

#!perl -040pl
$_=reverse

Try it online!