Problem overview
ConvertToHackerSpeak(string input) returns a coded copy of input in which five letters are swapped for look-alike digits:
| Letter | Becomes |
|---|---|
a | 4 |
e | 3 |
i | 1 |
o | 0 |
s | 5 |
Every other character, including spaces, stays as it is. For example, "become a coder" turns into "b3c0m3 4 c0d3r", and "javascript is cool" turns into "j4v45cr1pt 15 c00l".
Approach: build a new string one character at a time
The plan is to walk through the input from left to right. For each character, decide what to put in the result: the matching digit if it is one of the five letters, or the character itself otherwise. The decision is a chain of "is it an a? otherwise, is it an e?" questions, and exactly one branch applies to each character.
The result has to be a new string, because C# strings are immutable: once created, a string can't be changed. Writing input[4] = '4' is a compile error, since the indexer is read-only. So the method starts with an empty string and extends it as the loop goes.
Step by step
- Start with an empty string.
string solution = "";collects the encoded text. - Loop over the characters. The lesson uses
foreach (char c in input.ToCharArray()).ToCharArray()copies the string into achar[], andforeachthen gives you eachcharin turn. - Handle
'a'. Ifc == 'a', append'4'. Single quotes make acharliteral, which is the same type asc, so the comparison is between two characters. - Handle
'e','i','o'and's'. Each is anelse ifin the same chain, appending'3','1','0'and'5'. Anelse ifis only tested when every condition above it was false, so one character triggers one branch. - Keep everything else. The final
elseappendscunchanged, so spaces, consonants, digits and punctuation survive. - Return the result after the loop, once every character has been processed.
The solution in C#
class Solution {
public string ConvertToHackerSpeak(string input) {
string solution = "";
foreach (char c in input.ToCharArray()) {
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:
+=on a string creates a new string.solution += '4'builds a new string that is one character longer and stores it back insolution. The old string is discarded. Appending acharto astringworks, and the character is added as text.- Single quotes versus double quotes.
'a'is acharand"a"is astring. Comparingc == "a"doesn't compile, because acharand astringcan't be compared with==. - The
ToCharArray()call is optional. Astringis already a sequence ofcharvalues, soforeach (char c in input)behaves the same and skips the copy. - Digits are not added as numbers. The results here are the characters
'4','3'and so on. Writingsolution += 4with anintwould also append the text "4", but mixing acharwith anintin arithmetic, such as'a' + 1, produces the number 98. It is safest to stay with characters and strings. - A shorter way to write the chain. A
switchstatement does the same job, with onecasefor each letter. Theifchain keeps the lesson's focus on conditions in a loop.
Why repeated += can be slow
Because each += copies the whole string so far, building a long result this way takes quadratic time: copying 1 character, then 2, then 3, up to n. For typical lesson inputs this is invisible. For very long texts, System.Text.StringBuilder is the standard answer: its Append method adds to an internal buffer, and ToString() produces the final string once.
Here is the same logic written with a switch and a StringBuilder. It follows the same plan, and it builds the output without copying the string on every step:
using System.Text;
StringBuilder result = new StringBuilder();
foreach (char c in input) {
switch (c) {
case 'a': result.Append('4'); break;
case 'e': result.Append('3'); break;
case 'i': result.Append('1'); break;
case 'o': result.Append('0'); break;
case 's': result.Append('5'); break;
default: result.Append(c); break;
}
}
return result.ToString();
On the input "become a coder is easy" this version returns "b3c0m3 4 c0d3r 15 345y". Each case must end with break, because C# does not allow execution to fall from one case into the next.
Complexity
Time. The loop runs n times, once per character, and the checks inside are constant time. With the string concatenation as written, the copying makes the real cost up to O(n²) in the worst case. With a StringBuilder it is O(n).
Space: O(n). The result has the same length as the input, plus the copy made by ToCharArray().
Edge cases and common mistakes
- Uppercase letters. The comparisons are case-sensitive, so
"Apple Sauce"becomes"Appl3 S4uc3": the capitalAandSare left alone. The lesson only asks for lowercase letters. - Empty string. The loop doesn't run, and the method returns an empty string.
- Unchanged characters. Leaving out the final
elsewould drop every space and consonant from the output. - Using separate
ifstatements instead ofelse if. Eachifwould be tested on its own, and the finalelsewould belong only to the last one (the test for's'). Every character exceptswould then also be appended unchanged, so'a'would produce both4anda. Theelse ifchain ties all the branches together so that exactly one runs. - Trying to modify the input. Strings can't be changed in place, and the method has to return a new one.
Testing
"javascript is cool"gives"j4v45cr1pt 15 c00l"."programming is fun"gives"pr0gr4mm1ng 15 fun"."become a coder"gives"b3c0m3 4 c0d3r"."xyz"gives"xyz", since none of its letters are replaced.""gives"".