Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin - Convert while loop to functional style

I have the following Kotlin function:

fun func(n: Int): Int {

    var count = 1

    var m = n
    while(m != 1) {

        m = if(m.isOdd()) 3 * m + 1 else m / 2

        count++
    }

    return count
}

I would like to write that simple algorithm in a "functional" style, using Kotlin's operators like map(), count(), etc. The closest thing I could come up with was this:

fun func(n: Int): Int {

    return n.toList()
            .map{ if(it.isOdd()) 3*it+1 else it/2 }
            .takeWhile { it != 1 }
            .count()

}

Obviously, the above code does not work because map is executed only once, but you get the idea of what I am trying to achieve.

PS: toList() is just an extension function that converts an int to a list containing that int:

fun Int.toList() = listOf(this)
like image 232
Bitcoin Cash - ADA enthusiast Avatar asked Aug 17 '17 00:08

Bitcoin Cash - ADA enthusiast


1 Answers

Since you do not know how many items there will be, you can construct a (possibly infinite) sequence where each item is calculated based on the previous one, then limit it with your condition it != 1 and count how many items there are:

return generateSequence(n) { if (it.isOdd()) 3 * it + 1 else it / 2 }
        .takeWhile { it != 1 }
        .count()

Here, generateSequence(n) { ... }, constructs a Sequence<Int> that has n for its first element, and each of the following elements is calculated by the code passed as a lambda (it is called on the previous element, and only when another item is queried, i.e. lazily).

like image 193
hotkey Avatar answered Oct 17 '22 01:10

hotkey