Reputation: 11741
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)
Upvotes: 5
Views: 2316
Reputation: 147901
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).
Upvotes: 10