Start learning free

LESSON 144 OF 410 · LOOPS & GLOBAL VARIABLES

Hacker Speak in JavaScript: Replace Letters with Digits

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.
In many languages strings are immutable, so we don't change input in place. How does that affect us? How can we put this strategy into code?

In many languages strings are immutable, which means you cannot directly change a character of a string (for example, assigning '4' to the character at index 4 of input). So we create a new string where we will store the solution as we build 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:
  • Start with solution as an empty string.
  • For each character c of input: if c is 'a', append '4' to solution; if it is 'e', append '3'; if 'i', append '1'; if 'o', append '0'; if 's', append '5'; otherwise append c itself.
  • After the loop, 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).
(This assumes appending a character takes constant time. In languages where += on an immutable string copies the whole string each time, the running time can be closer to O(n2).)
STEP 1 OF 9
    Ctrl + Enter to check

    JAVASCRIPT · LOOPS & GLOBAL VARIABLES

    Hacker Speak in JavaScript, explained

    Problem overview

    The method convertToHackerSpeak(input) receives a string and returns a coded copy of it ("h4ck3r 5p34k"). Five lowercase letters are swapped for look-alike digits, and everything else stays as it is:

    LetterBecomes
    a4
    e3
    i1
    o0
    s5

    For "javascript is cool" the result is "j4v45cr1pt 15 c00l". Letters outside the table, spaces and punctuation are copied unchanged, and "programming is fun" becomes "pr0gr4mm1ng 15 fun".

    Approach

    A JavaScript string cannot be edited in place, so assigning to input[4] does nothing. The way around it is to build a new string while reading the old one. Start with an empty result and look at the input one character at a time. For each character, append its replacement if it has one, and the character itself if not. When the last character is handled, the result is complete.

    Every character is looked at once and appended once, so the work grows in step with the length of the input.

    Here is the idea on the word "cool". The result starts as "". The character c matches none of the five letters, so it is appended unchanged and the result is "c". Each o matches the fourth condition and appends 0, giving "c0" and then "c00". Finally l is appended as it is, and the method returns "c00l".

    If uppercase letters should be coded too, compare against the lowercase form of the character, as in c.toLowerCase() == 'a', while still appending the digit. The task names lowercase letters only, so the solution below compares c directly.

    Step by step

    1. Create solution as an empty string with let. It has to be let and not const, because += reassigns it each time it grows.
    2. Loop over the characters of input with for (let c of input). A for...of loop on a string gives the characters one by one, in order. (for...in would give the indexes instead.)
    3. Handle 'a' first. If c equals 'a', append '4'. JavaScript has no separate character type, so c is a string of length 1, and comparing it with 'a' is an ordinary string comparison.
    4. Chain an else if for 'e', appending '3'. An else if is tested only when every earlier condition was false.
    5. Chain one for 'i', appending '1'.
    6. Chain one for 'o', appending '0'.
    7. Chain one for 's', appending '5'. Only one branch of the chain runs for each character.
    8. Finish with a plain else, appending c unchanged. Spaces, punctuation, digits and all other letters take this path.
    9. Return solution after the loop, once every character has been processed.

    The solution in JavaScript

    class Solution {
        convertToHackerSpeak(input) {
            let solution = "";
            for (let c of 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;
        }
    }
    

    Details worth knowing:

    • Each += makes a new string. Strings are immutable, so solution += '4' builds a new string and stores it back in the variable. The original input is never changed.
    • Quote style. 'a' and "a" are the same string. The lesson uses single quotes for the characters and double quotes for the empty string.
    • == versus ===. Both sides are strings, so == works here. === is the safer habit in general.
    • Case matters. Only lowercase letters are replaced. "AEIOS" stays "AEIOS", and "AEIOS aeios" becomes "AEIOS 43105".
    • for...of reads code points, not UTF-16 units, so characters such as an emoji pass through as single items and are appended whole.

    Other ways to write it

    The chain of conditions works for five letters, but a lookup table is shorter and easier to extend. An object maps each letter to its digit, and the nullish operator ?? falls back to the original character when there is no entry:

    const digits = { a: '4', e: '3', i: '1', o: '0', s: '5' };
    
    function toHackerSpeak(input) {
      return [...input].map(c => digits[c] ?? c).join('');
    }
    
    console.log(toHackerSpeak("become a coder"));   // b3c0m3 4 c0d3r
    

    Reading a missing key of an object gives undefined, and undefined ?? c is c. This works for single characters. A regular expression with a callback is shorter still: input.replace(/[aeios]/g, c => digits[c]). Chaining replaceAll five times also works, but the loop in the lesson is the clearest way to see what happens to each character.

    Complexity

    Time: O(n), where n is the length of input. The loop runs once per character and each iteration does a fixed number of comparisons.

    Space: O(n). The result string ends up as long as the input. Because strings cannot be changed, a copy is needed anyway.

    Edge cases and common mistakes

    • Empty string. The loop never runs and the method returns "".
    • Nothing to replace. "xyz 123 !?" comes back unchanged.
    • Uppercase letters. "Sea" becomes "S34", because the uppercase S is not replaced.
    • Trying to edit the input. Writing input[i] = '4' does not change the string. Build a new one.
    • Using if instead of else if. With separate if statements, the final else would also run for the letters that were just replaced, and both the digit and the letter would be appended.
    • Declaring solution with const. The first += throws TypeError: Assignment to constant variable.

    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 JavaScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free