0

I worked on the Prime Generator problem for almost 3 days.

I want to make a Scala functional solution(which means "no var", "no mutable data"), but every time it exceed the time limitation.

My solution is:

object Main {

  def sqrt(num: Int) = math.sqrt(num).toInt

  def isPrime(num: Int): Boolean = {
    val end = sqrt(num)
    def isPrimeHelper(current: Int): Boolean = {
      if (current > end) true
      else if (num % current == 0) false
      else isPrimeHelper(current + 1)
    }
    isPrimeHelper(2)
  }

  val feedMax = sqrt(1000000000)
  val feedsList = (2 to feedMax).filter(isPrime)
  val feedsSet = feedsList.toSet

  def findPrimes(min: Int, max: Int) = (min to max) filter {
    num => if (num <= feedMax) feedsSet.contains(num)
    else feedsList.forall(p => num % p != 0 || p * p > num)
  }

  def main(args: Array[String]) {
    val total = readLine().toInt
    for (i <- 1 to total) {
      val Array(from, to) = readLine().split("\\s+")
      val primes = findPrimes(from.toInt, to.toInt)
      primes.foreach(println)
      println()
    }
  }
}

I'm not sure where can be improved. I also searched a lot, but can't find a scala solution(most are c/c++ ones)

Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
Freewind
  • 177,284
  • 143
  • 381
  • 649
  • I haven't really examined all your logic, but I think there's got to be a way to use an `unfold` on a `Stream`, passing along a set of known primes to act as a sieve – acjay May 29 '14 at 15:04
  • http://stackoverflow.com/questions/20985539/scala-erastothenes-is-there-a-straightforward-way-to-replace-a-stream-with-an#comment31606932_20986428 – Will Ness May 31 '14 at 23:28

3 Answers3

0

Here is a nice fully functional scala solution using the sieve of eratosthenes: http://en.literateprograms.org/Sieve_of_Eratosthenes_(Scala)#chunk def:ints

Lodewijk Bogaards
  • 18,519
  • 2
  • 25
  • 49
  • I tried that one out of curiosity, and I maxed out memory on n=10^6, and it took way more than 6 secs. I'm thinking stack of `filter`s on the `Stream` is busting the heap. Probably best to modify that to use a more specialized data structure for the sieve. – acjay May 29 '14 at 16:26
0

Check out this elegant and efficient one liner by Daniel Sobral: http://dcsobral.blogspot.se/2010/12/sieve-of-eratosthenes-real-one-scala.html?m=1

Odd
  • 409
  • 3
  • 4
0
lazy val unevenPrimes: Stream[Int] = {
  def nextPrimes(n: Int, sqrt: Int, sqr: Int): Stream[Int] =
    if (n > sqr) nextPrimes(n, sqrt + 1, (sqrt + 1)*(sqrt + 1)) else
    if (unevenPrimes.takeWhile(_ <= sqrt).exists(n % _ == 0)) nextPrimes(n + 2, sqrt, sqr)
    else n #:: nextPrimes(n + 2, sqrt, sqr)
  3 #:: 5 #:: nextPrimes(7, 3, 9)
}
Georg
  • 764
  • 6
  • 22