Solving the “Mexican Wave” Challenge Using Java


The challenge

Task

Your task is to create a function that turns a string into a Mexican Wave. You will be passed a string and you must return that string in an array where an uppercase letter is a person standing up.

Rules

1.  The input string will always be lowercase but may be empty.
2.  If the character in the string is whitespace then pass over it as if it was an empty seat.

Example

wave("hello") => []string{"Hello", "hEllo", "heLlo", "helLo", "hellO"}

Test cases

import static org.junit.Assert.assertArrayEquals;
import org.junit.Test;
import org.junit.runners.JUnit4;
import java.util.Arrays;

public class SolutionTest {

    @Test
    public void basicTest1() {
        String[] result = new String[] { "Hello", "hEllo", "heLlo", "helLo", "hellO" };
        assertArrayEquals("it should return '" + Arrays.toString(result) + "'", result, MexicanWave.wave("hello"));
    }
    
   @Test
    public void basicTest2() {
        String[] result = new String[] { "Codewars", "cOdewars", "coDewars", "codEwars", "codeWars", "codewArs", "codewaRs", "codewarS" };
        assertArrayEquals("it should return '" + Arrays.toString(result) + "'", result, MexicanWave.wave("codewars"));
    }
    
    @Test
    public void basicTest3() {
        String[] result = new String[] { };
        assertArrayEquals("it should return '" + Arrays.toString(result) + "'", result, MexicanWave.wave(""));
    }
    
    @Test
    public void basicTest4() {
        String[] result = new String[] { "Two words", "tWo words", "twO words", "two Words", "two wOrds", "two woRds", "two worDs", "two wordS" };
        assertArrayEquals("it should return '" + Arrays.toString(result) + "'", result, MexicanWave.wave("two words"));
    }
    
    @Test
    public void basicTest5() {
        String[] result = new String[] { " Gap ", " gAp ", " gaP " };
        assertArrayEquals("it should return '" + Arrays.toString(result) + "'", result, MexicanWave.wave(" gap "));
    }
    
}

The solution in Java

public class MexicanWave {

    public static String[] wave(String str) {
      
        // get the length of the string without spaces
        int lenwos = str.replaceAll("\\s","").length();
      
        // the final answer
        String[] out = new String[lenwos];
      
        // the counter to populate to
        int j=0;
      
        // while looping through the input string
        for (int i=0; i<str.length(); i++) {
            // if we detect a space, just increment our character counter
            while (Character.toString(str.charAt(i)).equals(" ")) {
                // return if about to be out of bounds
                if ((i+1)>=str.length()) return out;
                i++;
            }
          
            // create our new string
            StringBuilder sb = new StringBuilder(str);
            // uppercase the correct character
            sb.setCharAt(i, Character.toUpperCase(str.charAt(i)));
            // convert to string
            out[j] = sb.toString();
            // increment the answer counter
            j++;
        }
      
        // return the answer
        return out;
    }
    
}

You could also do the whole thing in an IntStream as follows:

import java.util.stream.IntStream;

public class MexicanWave {

    public static String[] wave(String str) {
        return IntStream
                .range(0, str.length())
                .mapToObj(x -> new StringBuilder(str).replace(x, x+1, String.valueOf(str.charAt(x)).toUpperCase()).toString())
                .filter(x -> !x.equals(str))
                .toArray(String[]::new);
    }
    
}