Writing a Fibonacci sequence

The following is an initial implementation for a sequence that can yield the numbers on demand:

val fibonacci = buildSequence {
yield(1)
var current = 1
var next = 1
while (true) {
yield(next)
val tmpNext = current + next
current = next
next = tmpNext
}
}

The following is an explanation of how this code works:

  • The first thing that the sequence does is to yield the number one. This is useful because we don't want to actually have to calculate the first numbers of the sequence.
  • Once the first number is yielded, the sequence suspends.
  • Once the second number is requested, the sequence will create two variables, current and next. Each of them is initialized to the number one, given that 1 is the first and second number in the sequence.
  • Then we enter an infinite loop. This part is what allows the data source to emit as many numbers from the sequence as requested.
  • The next time that a number from the sequence is requested, the first thing that happens is that the value of next is yielded – so the sequence is suspended.
  • And from that point on, whenever a value is requested, both current and next are recalculated to contain the new values and next is yielded.

So let's test this code. Let's include a simple main function that prints the first 50 numbers in the sequence, separated by commas:

fun main(args: Array<String>) {
val fibonacci = buildSequence {
...
}

val indexed = fibonacci.take(50).withIndex()

for ((index, value) in indexed) {
println("$index: $value")
}
}
Similar to take(), withIndex() is an intermediate operation.

If you look at the last elements printed, you will notice that some of them are actually negative numbers:

This is because the sum of the elements with index 44 and 45 exceed the maximum value that an Int can hold. So it leads to an overflow. To add support for more numbers, we are simply going to change the implementation to use Long:

val fibonacci = buildSequence {
yield(1L)
var current = 1L
var next = 1L
while (true) {
yield(next)
val tmpNext = current + next
current = next
next = tmpNext
}
}

Notice that this implementation will have similar issues around element 92. But for now, it is good enough for us.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.123.73