我正在解决一些关于Euler的问题,以练习我的Scala。对于问题7,我必须找到10001st素数。我有一个可行的解决方案,但感觉不到它的功能。
def first_n_primes(n: Long) : List[Long] = {
var last_prime = 1L
(1L to n).map(x => {last_prime = get_next_prime(x, last_prime); last_prime}).toList
}
具体来说,我认为可能有一种方法可以摆脱var last_prime,但是我不知道如何将第n个映射评估的结果用作n + 1评估的输入。我该怎么做呢?
答案 0 :(得分:2)
您正在寻找scanLeft
:
(1l to n).scanLeft(1) { case (x, last) => get_next_prime(x, last) }
或者只是(1l to n).scanLeft(1)(get_next_prime)
但是请注意,这不是查找素数的很好算法,因为可以节省很多重复的工作(要找到下一个素数,您需要重新发现所有先前的素数)。
使用递归流在scala中更好地完成此类任务:
lazy val primes: Stream[Long] = 2 #:: Stream.iterate(3l)(_+1).filter { n =>
val stop = math.sqrt(n)
primes.takeWhile { _ <= stop }.forall { k => n % k != 0 }
}
primes.take(n).toList