BBK#3: Mumbling...

problemsolving Nov 19, 2020

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!

Question: This time no story, no theory. The examples below show you how to do

mummble("abcd") -> "A-Bb-Ccc-Dddd"
mummble("RqaEzty") -> "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy"
mummble("cwAt") -> "C-Ww-Aaa-Tttt"

Try it put yourself :
👨🏻‍💻👉  https://www.codewars.com/kata/5667e8f4e3f572a8f2000039/train/kotlin



This solution requires accumulator pattern, read through my article on this it will help you out a lot!

Accumulator Pattern for beginners | Fold vs Reduce | AndroidBites
Accumulator pattern in kotlin | kotlin how to reduce | kotlin how to fold | reduce vs fold | best practice to reduce | transformation in kotlin | collection transformation | java vs koltin | java for loop anti patterns

Solution 1:

fun mummble(input: String): String {
    val words = input.toCharArray()
    val mumble = StringBuilder()
    for ((index,word) in words.withIndex()) {
        mumble.append(word.toUpperCase())
        repeat(index){
            mumble.append(word.toLowerCase())
        }
        if(index != words.size -1){
            mumble.append("-")
        }
    }
    return mumble.toString()
}

// Performance : took ~ 1.187 ms on my machine

OR

fun mummble(input: String): String {
    var result = ""
    input.toCharArray().forEachIndexed{ index,item->
        result = "$result${item.toUpperCase()}"
        repeat(index){
            result = "$result${item.toLowerCase()}"
        }
        if(input.length-1 != index){
            result = "$result-"
        }
    }
    return result
}

// Performance : took ~ 0.631 ms on my machine

forEach under the hood is same as for, it's giving more performance because I have used StringBuilder in one and other uses String Object

Solution 2:

Using fold, checkout :

Accumulator Pattern for beginners | Fold vs Reduce | AndroidBites
Accumulator pattern in kotlin | kotlin how to reduce | kotlin how to fold | reduce vs fold | best practice to reduce | transformation in kotlin | collection transformation | java vs koltin | java for loop anti patterns
fun mummble(input: String): String {
    val answer = input.toCharArray().foldIndexed(""){ index,acc,item->
        var result = "$acc${item.toUpperCase()}"
        repeat(index){
            result = "$result${item.toLowerCase()}"
        }
        if((input.length - 1) != index){
            result = "$result-"
        }
        result
    }
    return answer
}

// Performance : took ~ 0.180 ms on my machine

Solution 3:

Using JoinToString, Checkout advance stuff we can do with it!

Snippets | List to String with Examples | Androidbites
kotlin string | kotlin variable in string | kotlin join strings with delimiter | kotlin map to string | kotlin string interpolation | kotlin string collection join | list to string and string to list kotlin | kotlin string format
fun mummble(words: String): String =
	words.mapIndexed { index, word -> 
   "${word.toUpperCase()}${word.toString().toLowerCase().repeat(index)}"}
    .joinToString("-")


// Performance : took ~ 13.525 ms on my machine

Thou, this approach is fancy functional/fluent but have hit due join Operation.


Community Submission

Contributed by ShreyasPatil

const val DELIMETER_CHAR = "-"

fun main() {
    println(mummble("cwAt"))
}

fun mummble(word: String): String {
    val mummbleBuilder = StringBuilder()

    return with(mummbleBuilder) {
        word.forEachIndexed { index, char ->
            repeat(index + 1) { count ->
                val newChar = if (count == 0) char.toUpperCase() else char.toLowerCase()
                append(newChar)
            }.also { append(DELIMETER_CHAR) }
        }.also { deleteCharAt(mummbleBuilder.lastIndex) }

        mummbleBuilder.toString()
    }
}

Cons

It's bit more nested, Nesting hurt readability of the code.

Pros

Never know there was a deleteCharAt(index) function, it delete character at an index on a StringBuilder object,  but has been Deprecated in-favour of deleteAt(index: Int), they can throw index-out-of-bound exception so be careful while using these.

Contributed by Shahbaz

Pros

Cleaner alternative to Solution 3 by using capitalize reduced the noise related to String Concatenation



Conclusion

Aim of these articles is not hate on Java, but to help people learn various ways in which they can write 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! 👩‍💻

Solve Previous:

BigBrainKotlin - Find Max Min
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 a lot!

Enjoy the Post?

a clap is much appreciated if you enjoyed. No sign up or cost associated :)




Chetan gupta

Hi there! call me Ch8n, I'm a mobile technology enthusiast! love Android #kotlinAlltheWay, CodingMantra: #cleanCoder #TDD #SOLID #designpatterns

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.