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
- Start with an empty result.
var solution = ""is avarbecause it will be reassigned as it grows. - Loop over the characters.
for (c in input)gives each element of a string as aChar, in order. - Test for
'a'. Ifcequals'a', append'4'. Single quotes make aCharliteral, which is the same type asc. - 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'. Anelse ifis checked only when all conditions above it were false, so exactly one branch runs for each character. - Keep everything else. The final
elseappendscunchanged, so spaces, punctuation, digits and other letters survive. - 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'meanssolution = solution + '4'.String.plusaccepts any value, so appending aCharworks. It creates a new string and assigns it to the variable, which is whysolutionmust be avar.CharagainstString.'a'is aCharand"a"is aString. Comparingc == "a"does not compile, becauseCharandStringcan never be equal. Use single quotes for single characters.- Case matters. The comparisons are exact, so an uppercase
Ais 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. AStringBuilderappends in place and is the usual choice for large strings:sb.append('4'), thensb.toString()at the end. whenas an alternative. Awhen (c)block with branches such as'a' -> ...expresses the same five cases more compactly than anelse ifchain. 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
ifstatements. With a chain of independentifs and a finalelseattached only to the last one, the finalelsewould also append the original letter after the replacements. Theelse ifchain 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".