BigBrainKotlin#6: The Morse Code π€«
I have a secret code for you to crack detective! π΅οΈββοΈ
originally published on https://chetangupta.net/bbk-main/
Donβt be a Java-ish dev in Kotlin-ish world, improve your knowledge about Koltin Standard Library and write better Kotlin code. βπ» If your Java dev migrating to Kotlin this will help you learn alot!
This quiz was suggested by Rohan Singh on Twitter, sorry for the delay mate!
Question
: You have received a secret message! unfortunately, you canβt just read it, it is encoded in Morse code. Your task is to implement a function that would take the morse code as input and return a human-readable string. 3 spaces are used to separate words and
Extra spaces before or after the code have no meaning and should be ignored.
Message : -. β β β ..- β¦. .- β¦- . .- -β¦ .. β . -β¦ .-. .- .. -. ..-. β β .-. -.- β β β .-.. .. -.
val morseCode = "-.-- --- ..- .... .- ...- . .- -... .. --. -... .-. .- .. -. ..-. --- .-. -.- --- - .-.. .. -." // write a function that converts this MorseCode to English fun decodeMorse(morseCode:String):String{
// .. do stuff
}
Given Morse Code Decoder
val morseDecoder = mapOf<String, String>(
".-" to "A",
"-..." to "B",
"-.-." to "C",
"-.." to "D",
"." to "E",
"..-." to "F",
"--." to "G",
"...." to "H",
".." to "I",
".---" to "J",
"-.-" to "K",
".-.." to "L",
"--" to "M",
"-." to "N",
"---" to "O",
".--." to "P",
"--.-" to "Q",
".-." to "R",
"..." to "S",
"-" to "T",
"..-" to "U",
"...-" to "V",
".--" to "W",
"-..-" to "X",
"-.--" to "Y",
"--.." to "Z",
".----" to "1",
"..---" to "2",
"...--" to "3",
"....-" to "4",
"....." to "5",
"-...." to "6",
"--..." to "7",
"---.." to "8",
"----." to "9",
"-----" to "0",
"" to " ",
".-.-.-" to ".",
"--..--" to ",",
"---..." to ".",
"..--.." to "?",
"-.-.--" to "!",
"...---..." to "SOS",
"-....-" to "''",
"-..-." to "/",
"-.--.-" to "()",
".--.-." to "@",
"-...-" to "="
)
Try it put yourself :
π¨π»βπ»π https://www.codewars.com/kata/54b724efac3d5402db00065e/train/kotlin
Solution 1:
Same old imperative way. πͺ
fun decodeMorse(code: String): String {
val morseWords = code.split(" ")
val humanized = StringBuilder()
for (morseWord in morseWords) {
val morseChars = morseWord.split(" ")
for (morseChar in morseChars) {
if (morseChar.isNotEmpty()) {
humanized.append(morseDecoder.get(morseChar))
}
}
humanized.append(" ")
}
return humanized.toString()
}// π¨π»βπ§ complexity : O(n^2)
// β± performance : took 509.0 us on my machine
Btw there is nothing wrong in this way, just the loops make it very expressive, there is no issue of mutations and accidental updates in it. ππ»
Checkout why accumulator pattern in imperative style is bad.π‘
Solution 2:
Imperative equivalent code in functional style | Stdlib function
fun decodeMorse(code: String): String {
return code.trim()
.split(" ")
.joinToString(separator = " ") { word ->
word.split(" ")
.map { letter -> morseDecoder[letter] ?: "" }
.joinToString(separator = "")
}
}// π¨π»βπ§ complexity : O(n^2)
// β± performance : took 639.0 us on my machine
The performance hit of there is due to joinToString
operation one at the outer loop and multiple times into the inner loop, not good! dood (dude)...βΉοΈ
learn joinToString and itβs advanced use cases π‘
Solution 3:
What if we call it once? , if we eliminate the nesting, i.e flatten our words to char?
π¨π»βπ» Letβs flatten our List
using FlatMap
fun decodeMorse(code: String) = code
.split(" ")
.flatMap { it.split(" ") }
.map { morseDecoder.get(it)?:" " }
.joinToString("")// π¨π»βπ§ complexity : O(n)
// β± performance : took 464.0 us us on my machine
Whola!
Solution 4:
Or Change the way you are solving this problem πββοΈ
fun decodeMorse(code: String): String {
return code.trim()
.replace(" ", " ")
.split(" ")
.map { MorseCode[it]?:" " }
.joinToString("")
}
// π¨π»βπ§ complexity : O(n)
// β± performance : took 441.0 us on my machine
Donβt get attached to a solution!
Conclusion
The aim of these articles is not hated on Java, but to help people learn various ways in which they can write the same logic better and more Kotlin standard library-focused way.
Hope you find it informative and if you have any feedback or post request or want to subscribe to my mailing list forms are below.
Until next time. Happy Hacking! π©βπ»