Reputation: 2288
I want to generate sequance of all fibonacci numbers, that less then 10000
For example, this will generate 40 fibonacci numbers. But i want to stop generate them with some condition. How can i do this?
def main(args: Array[String]) {
val fibonacciSequence = for(i <- 1 to 40) yield fibonacci(i)
println(fibonacciSequence)
}
def fibonacci(i: Int) : Int = i match {
case 0 => 0
case 1 => 1
case _ => fibonacci(i - 1) + fibonacci(i - 2);
}
I want something like this: for(i <- 1 to ?; stop if fibonacci(i) > 100000)
Upvotes: 0
Views: 69
Reputation: 16308
This method, involving lazy infinite collection calculation, could produce suitable result:
import scala.Numeric.Implicits._
def fibonacci[N: Numeric](a: N, b: N): Stream[N] = a #:: fibonacci(b, a + b)
so
fibonacci(0L,1L).takeWhile(_ < 1000L).toList
yields
List(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987)
If you don't want to use intermediate value to cache collection of proper type and init, you could just declare a val
like this:
val fib: Stream[Long] = 0 #:: 1 #:: (fib zip fib.tail map { case (a, b) => a + b })
Upvotes: 3
Reputation: 20415
Using iterators and memoization (computing the current result based in the latest ones, not recomputing what has already been done), (method from Rosetta, similar to Odomontois's streams),
def fib() = Iterator.iterate((0,1)){ case (a,b) => (b,a+b)}.map(_._1)
To get the first nth values consider for instance,
def nfib(n: Int) = fib().zipWithIndex.takeWhile(_._2 < n).map(_._1).toArray
To get consecutive values up to a given condition or predicate,
def pfib(p: Int => Boolean) = fib().takeWhile(p).toArray
Thus, for example
nfib(10)
Array(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
pfib( _ < 55)
Array(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
Upvotes: 1