DEV Community

loading...
Cover image for Kotlin - Smart Solutions #0

Kotlin - Smart Solutions #0

henrique_horbovyi profile image Henrique Horbovyi ・2 min read

Hello World, this is the first post of a series in which I want to share to you some cool Kotlin features.

The Problem (Make Array Consecutive)

I've faced this problem at Code Signal (it's a code challenge site). The code challenge description is the follows:

  • "Ratiorg got statues of different sizes as a present from CodeMaster for his birthday, each statue having a non-negative integer size. Since he likes to make things perfect, he wants to arrange them from smallest to largest so that each statue will be bigger than the previous one exactly by 1. He may need some additional statues to be able to accomplish that. Help him figure out the minimum number of additional statues needed."

There is one example to make things more clear

For statues = [6, 2, 3, 8], the output should be
makeArrayConsecutive(statues) = 3.

Ratiorg needs statues of sizes 4, 5 and 7.

The Solution πŸ’‘

So basically, we need to sort all statues and count the number of missing statues between each one, but how? Take a minute to think about it and then check the solution in the code snippet below.

The Solution

Debugging and Understanding πŸ‘¨β€πŸ’»

  • First thing, we need to sort all statues to guarantee that
    [6, 2, 3, 8] will become [2, 3, 6, 8]

  • Next, I used subtract() method to remove the original list items from a new list which consists in a range between statues.first() and statues.last(), which is: statues.first()..statues.last()

    This range operation will return an int iterable like:
    [2, 3, 4, 5, 6, 7, 8]
    Then, after subtract() it will result in this list:
    [4, 5, 7], and that's awesome, these are the missing numbers in the original statues list.

  • Now, we need to count() the returned list and we have the final result. Simple no? :D

Conclusion

In this article, we explored range operator, subtract, and count functions of Kotlin, how to use it and apply it in a problem.

And if you have some questions, any suggestions, a better solution or even some new ideas for the next Kotlin Smart Solutions post, don't be shy, let me know and leave me a comment. ;D

I hope you learned something new around here.
Thank you!
#KeepLearning

Discussion

pic
Editor guide
Collapse
amitkusrivastava profile image
Amit

Thanks for sharing the post. The same could have being achieved using zipNext and summing the difference between each pair. Wondering which solution will be more optimized behind the scene.

Collapse
henrique_horbovyi profile image
Henrique Horbovyi Author

That's awesome! Could you type some snippets? I'm very interested to compare these two solutions.
Thanks for the answer! :D

Collapse
amitkusrivastava profile image
Amit

Something like following:

fun main() {
    println(listOf(6, 2, 3, 8).sorted().zipWithNext().sumBy { (smallerStatueHeight, biggerStatueHeight) ->  biggerStatueHeight - smallerStatueHeight - 1})
}
Thread Thread
henrique_horbovyi profile image
Henrique Horbovyi Author

Great solution dude.
I'm comparing both solutions using measureTimeMillis()

Code

Thread Thread
henrique_horbovyi profile image
Henrique Horbovyi Author

I executed several times, and the result is always Time(caseA) < Time(caseB) :D
And nevermind the order of execution it will take more or less the same time for both

First Execution
Second Execution

Thread Thread
henrique_horbovyi profile image
Henrique Horbovyi Author

But the scenario changes a bit when I executed on Kotlin Playground
The results tend to be more approximated