xring
xring

Reputation: 767

How to Make Prime Generator Code More Efficient

As a beginner in Scala, I got a problem in SPOJ:

Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!

Input

The input begins with the number t of test cases in a single line (t<=10). In each of the next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.

Output

For every test case print all prime numbers p such that m <= p <= n, one number per line, test cases separated by an empty line.

Example

Input:
2
1 10
3 5

Output:
2
3
5
7

3
5
` Warning: large Input/Output data, be careful with certain languages (though most should be OK if the algorithm is well designed)

Run environment and requirement:

Added by: Adam Dzedzej
Date: 2004-05-01
Time limit: 6s
Source limit: 50000B
Memory limit: 1536MB
Cluster: Cube (Intel Pentium G860 3GHz)
Languages: All except: NODEJS PERL 6 SCM chicken

My code is here:

import math.sqrt

object Pro_2 {
  def main(args: Array[String]) {

    // judge whether a Long is a prime or not
    def isPrime(num: Long): Boolean = {
      num match {
        case num if (num < 2) => false
        case _ => {
          2 to (sqrt(num) toInt) forall (num % _ != 0)
        }
      }
    }

    // if a Long is a prime print it in console
    def printIfIsPrime(num: Long) = {
      if (isPrime(num))
        println(num)
    }

    // get range
    def getInput(times: Int) = {
      for (input <- 0 until times) yield {
        val range = readLine().split(" ")
       (range(0) toLong, range(1) toLong)
      }
    }

    val ranges = getInput(readInt())
    for (time <- 0 until ranges.length) {
      (ranges(time)._1 to ranges(time)._2).foreach(printIfIsPrime(_))
      if (time != ranges.length - 1)
        println()
    }

  }
}

When I run my code in SPOJ, I got a result: time limit exceeded

I need make my code more efficient, could you please help me?

Any help would be greatly appreciated.

Upvotes: 0

Views: 336

Answers (1)

Tesseract
Tesseract

Reputation: 8139

isPrime could be written in a lower level style. Also you can increase the speed of the println method.

def main(args: Array[String]) {
  val out = new java.io.PrintWriter(System.out, false)

  def isPrime(n: Long): Boolean = {
    if(n <= 3) return n > 1
    else if(n%2 == 0 || n%3 == 0) return false
    else {
      var i = 5
      while(i*i <= n) {
        if(n%i == 0 || n%(i+2) == 0) return false
        i += 6
      }
      return true
    }
  }

  def printIfIsPrime(num: Long) = {
    if (isPrime(num)) {
      out.println(num)
    }
  }
  ...
  val ranges = getInput(readInt())
  for (time <- 0 until ranges.length) {
    (ranges(time)._1 to ranges(time)._2).foreach(printIfIsPrime(_))
    if (time != ranges.length - 1)
      out.println()
  }
  out.flush()
}

Upvotes: 2

Related Questions