Start learning free

LESSON 142 OF 348 · LOOPS & GLOBAL VARIABLES

H4ck3r Sp34k in Kotlin: Encoding a String Character by Character

Practice Read the full explanation

Given a string, write a function that returns a coded (h4ck3r 5p34k) version of the string.

In order to work properly, the function should replace all "a"s with 4, "e"s with 3, "i"s with 1, "o"s with 0, and "s"s with 5.

Example 1:

Input:  "javascript is cool"

Output: "j4v45cr1pt 15 c00l"

Example 2:

Input:  "programming is fun"

Output: "pr0gr4mm1ng 15 fun"

Example 3:

Input:  "become a coder"

Output: "b3c0m3 4 c0d3r"
Hints:

We have to iterate through every character of input, check for each scenario and treat it accordingly:
  • Is it an 'a'? If so, replace with '4'. Otherwise:
  • Is it an 'e'? If so, replace with '3'. Otherwise:
  • Is it an 'i'? If so, replace with '1'. Otherwise:
  • Is it an 'o'? If so, replace with '0'. Otherwise:
  • Is it an 's'? If so, replace with '5'. Otherwise, keep it as it is.
Remember that strings are immutable. How does that affect us? How can we put this strategy into code?

Strings are immutable means you cannot directly change a character in a string like this: input[4] = '4'. This means we have to create a new string where we will store the solution as we create it. How can we translate these two hints in code?

Let's create a new string named solution, initially empty, where we will push all the encoded characters of input. We will use a for loop and a character variable c to iterate through input and treat the scenarios inside the loop:
solution = ""
for each c in input:
	if c == 'a':
        solution += '4'
    else if c == 'e':
        solution += '3'
    else if c == 'i':
        solution += '1'
    else if c == 'o':
        solution += '0'
    else if c == 's':
        solution += '5'
    else:
        solution += c
return solution


We have a for loop that performs exactly n iterations (n is the length of input), thus the Time Complexity is O(n).
The extra space we use is the extra string solution. Its length will be n in the end, thus the Extra Space used is also O(n).
STEP 1 OF 9
    Ctrl + Enter to check

    KOTLIN · LOOPS & GLOBAL VARIABLES

    Hacker Speak in Kotlin, explained

    Problem overview

    The function convertToHackerSpeak receives a String named input and returns a new string in which some letters are replaced by digits: every a becomes 4, e becomes 3, i becomes 1, o becomes 0 and s becomes 5. All other characters stay as they are.

    For "become a coder", the letters b, c, m, d and r are untouched, each e becomes 3, each o becomes 0 and the lone a becomes 4. The result is "b3c0m3 4 c0d3r". Spaces are copied unchanged, and "javascript is cool" turns into "j4v45cr1pt 15 c00l".

    Approach: build a new string

    You can't edit the input in place. Kotlin strings are immutable, so a statement like input[1] = '4' doesn't compile. The compiler reports that there is no set operator providing array access.

    So the plan is to start with an empty result and visit the characters of input from left to right. For each one, decide what to append: the replacement digit if the character is one of the five letters, or the character itself otherwise. When the loop ends, the result holds the whole encoded text.

    Take "fun is" as a short trace. The characters f, u and n match none of the five letters, so they are appended unchanged and the result is "fun". The space is also copied. Then i becomes 1 and s becomes 5, giving "fun 15". Every character produces exactly one character of output, in the same order, which is why the result is always as long as the input.

    A lookup table, such as a map from each letter to its digit, would also work and would scale better if the list of replacements grew. With only five fixed cases, a plain chain of comparisons is simpler to read.

    Step by step

    1. Start with an empty result. var solution = "" is a var because it will be reassigned as it grows.
    2. Loop over the characters. for (c in input) gives each element of a string as a Char, in order.
    3. Test for 'a'. If c equals 'a', append '4'. Single quotes make a Char literal, which is the same type as c.
    4. Chain the other letters with else if, one for 'e' and '3', one for 'i' and '1', one for 'o' and '0', and one for 's' and '5'. An else if is checked only when all conditions above it were false, so exactly one branch runs for each character.
    5. Keep everything else. The final else appends c unchanged, so spaces, punctuation, digits and other letters survive.
    6. Return after the loop, when every character has been handled.

    The solution in Kotlin

    class Solution {
        fun convertToHackerSpeak(input: String): String {
            var solution = ""
            for (c in input) {
                if (c == 'a') {
                    solution += '4'
                } else if (c == 'e') {
                    solution += '3'
                } else if (c == 'i') {
                    solution += '1'
                } else if (c == 'o') {
                    solution += '0'
                } else if (c == 's') {
                    solution += '5'
                } else {
                    solution += c
                }
            }
            return solution
        }
    }
    

    The Kotlin details behind it:

    • String += Char. solution += '4' means solution = solution + '4'. String.plus accepts any value, so appending a Char works. It creates a new string and assigns it to the variable, which is why solution must be a var.
    • Char against String. 'a' is a Char and "a" is a String. Comparing c == "a" does not compile, because Char and String can never be equal. Use single quotes for single characters.
    • Case matters. The comparisons are exact, so an uppercase A is not replaced. "AEIOS aeios" becomes "AEIOS 43105", which is what the rules say, since only the lowercase letters are listed.
    • Repeated concatenation copies. Each += builds a fresh string, so a long input does more copying than a single pass suggests. For this lesson that is acceptable. A StringBuilder appends in place and is the usual choice for large strings: sb.append('4'), then sb.toString() at the end.
    • when as an alternative. A when (c) block with branches such as 'a' -> ... expresses the same five cases more compactly than an else if chain. The lesson uses the chain so that each case is one visible step.

    Complexity

    Let n be the length of input.

    Time: O(n). The loop runs n times, and each pass makes at most five comparisons and one append. The lesson's budget treats each append as constant-time work. In practice, repeated String concatenation copies the text built so far, so the actual cost can grow faster than linearly for very long inputs, which a StringBuilder avoids.

    Space: O(n). The result has exactly as many characters as the input, because every replacement is one character for one character.

    Edge cases and common mistakes

    • An empty string. The loop never runs and the function returns "".
    • No special letters. "xyz 123!" comes back unchanged.
    • Uppercase letters. They are left alone, as shown above.
    • Using separate if statements. With a chain of independent ifs and a final else attached only to the last one, the final else would also append the original letter after the replacements. The else if chain avoids that.
    • Forgetting the final else. Without it, characters that need no change would be dropped from the output.
    • Double quotes for characters. c == "a" does not compile, as explained above.
    • Returning inside the loop. The function would stop after processing a single character.

    Testing

    • "javascript is cool" gives "j4v45cr1pt 15 c00l".
    • "programming is fun" gives "pr0gr4mm1ng 15 fun".
    • "become a coder" gives "b3c0m3 4 c0d3r".
    • "" gives "".
    • "AEIOS aeios" gives "AEIOS 43105".
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free