12Nov/094
SPOJ Problem 2: Prime Generator (PRIME1)
Problem: Prime Generator
Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!
Concept The idea behind every solution here (with some variation) is to generate all the prime numbers that could be factors of numbers up to the maximum endpoint 1 billion. That square root happens to be around 32000. Using this array, do a bounded Sieve of Eratosthenes only in the range requested. In languages like php and python, it turns out that it's more efficient to build an associative array and check if the index is set than it is to generate a huge boolean array.
Code
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /// PRIME1 - C++ (g++) // AC Time: 2.52s // NOTE: I am aware that the use of vector and set actually // makes this code run _slower_ // I used vector and set simply as a way of practicing STL #include <iostream> #include <cmath> #include <vector> #include <set> using namespace std; int main() { vector<int> primes; primes.push_back(2); for (int i = 3; i <= 32000; i+=2) { bool isprime = true; int cap = sqrt(i) + 1; vector<int>::iterator p; for (p = primes.begin(); p != primes.end(); p++) { if (*p >= cap) break; if (i % *p == 0) { isprime = false; break; } } if (isprime) primes.push_back(i); } int T,N,M; cin >> T; for (int t = 0; t < T; t++) { if (t) cout << endl; cin >> M >> N; if (M < 2) M = 2; int cap = sqrt(N) + 1; set<int> notprime; notprime.clear(); vector<int>::iterator p; for (p = primes.begin(); p != primes.end(); p++) { if (*p >= cap) break; int start; if (*p >= M) start = (*p)*2; else start = M + ((*p - M % *p) % *p); for (int j = start; j <= N; j += *p) { notprime.insert(j); } } for (int i = M; i <= N; i++) { if (notprime.count(i) == 0) { cout << i << endl; } } } return 0; } |
C99
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | // PRIME1 - C99 (gcc) // AC Time: 0.07s #include <stdio.h> #include <string.h> #include <stdbool.h> #include <math.h> int main() { int primes[4000]; int numprimes = 0; primes[numprimes++] = 2; for (int i = 3; i <= 32000; i+=2) { bool isprime = true; int cap = sqrt(i)+1; for (int j = 0; j < numprimes; j++) { if (primes[j] >= cap) break; if (i % primes[j] == 0) { isprime = false; break; } } if (isprime) primes[numprimes++] = i; } int T,N,M; scanf("%d",&T); for (int t = 0; t < T; t++) { if (t) printf("\n"); scanf("%d %d",&M,&N); if (M < 2) M = 2; int cap = sqrt(N) + 1; bool isprime[100001]; memset(isprime,true,sizeof(isprime)); for (int i = 0; i < numprimes; i++) { int p = primes[i]; if(p >= cap) break; int start; if (p >= M) start = p*2; else start = M + ((p - M % p) % p); for (int j = start; j <= N; j += p) { isprime[j - M] = false; } } int start = (M % 2)?M:M+1; if (M == 2) { printf("2\n"); } for (int i = start; i <= N; i+=2) { if (isprime[i-M]) printf("%d\n",i); } } return 0; } |
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <? // PRIME1 - PHP // AC Time: 5.73 $primes = array(2); $numprimes = 1; for ($i = 3; $i <= 32000; $i+=2) { $isprime = true; $cap = sqrt($i)+1; for ($j = 0; $j < $numprimes; ++$j) { if ($j >= $cap) break; if (!($i % $primes[$j])) { $isprime = false; break; } } if ($isprime) $primes[$numprimes++] = $i; } fscanf(STDIN,"%d",$T); $output = ""; for ($t = 0; $t < $T; $t++) { if ($t) $output .= "\n"; fscanf(STDIN,"%d %d",$M,$N); if ($M < 2) $M = 2; $isprime = array(); $cap = sqrt($N)+1; $i = 0; while($i < $numprimes) { $p = $primes[$i]; if ($p >= $cap) break; if ($p >= $M) { $start = $p*2; } else { $start = $M + (($p - $M % $p) % $p); } for ($j = $start; $j <= $N; $j += $p) { $isprime[$j - $M] = false; } ++$i; } for ($i = $M; $i <= $N; ++$i) { if (!isset($isprime[$i-$M])) { $output .= "$i\n"; } } } echo $output; ?> |
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # PRIME1 - Python # AC Time: 3.10s from math import sqrt primes = [2] for i in range(3,32000,2): isprime = True cap = sqrt(i)+1 for j in primes: if (j >= cap): break if (i % j == 0): isprime = False break if (isprime): primes.append(i) T = input() output = "" for t in range(T): if (t > 0): output += "\n" M,N = raw_input().split(' ') M = int(M) N = int(N) cap = sqrt(N)+1 if (M < 2): M = 2 isprime = [True]*100001 for i in primes: if (i >= cap): break if (i >= M): start = i*2 else: start = M + ((i - M % i)%i) # The two below, obscure lines create a continuous # block of false elements in order to set all # elements correspnding to numbers divisible by i # in isprime to be false # In turns out that this runs substantially faster # than setting the elements individually using loops falseblock = [False] * len(isprime[start-M:N+1-M:i]); isprime[start-M:N+1-M:i] = falseblock for i in range(M,N+1): if (isprime[i-M] == True): output += str(i) + "\n" print output[:-1] |
Bash
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # PRIME1 Incomplete - BASH # This is not a complete solution # The speed of bash parsing makes getting an # AC submission infeasible # The following code is a working prime generator # Giving enough time, it will output all prime # numbers from 0 to 32000 # ..which is the first step in the solution to PRIME1 let PRIMES[0]=2 let NUMPRIMES=1 for i in {3..32000}; do let ISPRIME=1 #for j in {0..$NUMPRIMES}; do for (( j = 0;j<$NUMPRIMES;j++ )); do let CURPRIME=${PRIMES[$j]} if [[ $CURPRIME*$CURPRIME -gt $i ]]; then break fi let MOD=$[$i % $CURPRIME] if [ $MOD -eq 0 ]; then let ISPRIME=0 break fi done if [ $ISPRIME -eq 1 ]; then echo $i let PRIMES[NUMPRIMES]=$i let NUMPRIMES=NUMPRIMES+1 fi done |
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # PRIME1 - Ruby # AC Time: 4.65s # # While I would have liked to use more # Ruby idioms such as for p in primes # or primes.each do |p| (used once), # the difference in runtime between # the use of loops like these and while # loops was non-negligible primes = [2] 3.step(32000,2) do |i| isprime = true cap = Math.sqrt(i) + 1 primes.each do |p| if (p >= cap) break end if (i % p == 0) isprime = false break end end if isprime primes << i end end numprimes = primes.length T = gets.to_i output = "" t = 0 while t < T print "\n" if t > 0 line = gets.split(" ") m = line[0].to_i n = line[1].to_i m = 2 if m < 2 cap = Math.sqrt(n) + 1 notprime = {} i = 0 while i < numprimes p = primes[i] i+=1 if (p >= cap) break end if (p >= m) start = p*2 else start = m + ((p - m % p)%p) end j = start while j <= n notprime[j] = true j += p end end i = m while (i <= n) if (notprime[i] == nil) print i,"\n" end i+=1 end t += 1 end |
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | // PRIME1 - Java // AC Time: 2.20 import java.io.*; import java.util.*; import java.lang.Math.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int[] primes = new int[4000]; int numprimes = 0; primes[numprimes++] = 2; for (int i = 3; i <= 32000; i+=2) { boolean isprime = true; double cap = Math.sqrt(i) + 1.0; for (int j = 0; j < numprimes; j++) { if (j >= cap) break; if (i % primes[j] == 0) { isprime = false; break; } } if (isprime) primes[numprimes++] = i; } int T,N,M; T = in.nextInt(); for (int t = 0; t < T; t++) { if (t > 0) System.out.println(""); M = in.nextInt(); N = in.nextInt(); if (M < 2) M = 2; boolean[] isprime = new boolean[100001]; for (int j = 0; j < 100001; j++) { isprime[j] = true; } for (int i = 0; i < numprimes; i++) { int p = primes[i]; int start; if (p >= M) start = p*2; else start = M + ((p - M % p)%p); for (int j = start; j <= N; j += p) { isprime[j - M] = false; } } for (int i = M; i <= N; i++) { if (isprime[i-M]) System.out.println(i); } } } } |
Perl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | # PRIME1 - Perl # AC Time: 4.28s @primes = (2); for ($i = 3; $i <= 32000; $i+=2) { $isprime = 1; $cap = sqrt($i) + 1; foreach $p (@primes) { if ($p >= $cap) { last; } if ($i % $p == 0) { $isprime = 0; last; } } if ($isprime == 1) { push(@primes,$i) } } $T = <STDIN>; for ($t = 0; $t < $T; $t++) { if ($t > 0) { print ""; } $in = <STDIN>; @line = split(/ /,$in); $M = $line[0]; $N = $line[1]; if ($M < 2) { $M = 2; } $cap = sqrt($N) + 1; @isprime = ((1) x 100001); foreach $p (@primes) { if ($p >= $cap) { last; } if ($p >= $M) { $start = $p*2; } else { $start = $M + (($p - $M % $p) % $p); } for ($j = $start; $j <= $N; $j += $p) { $isprime[$j-$M] = 0; } } for ($i = $M; $i <= $N; $i++) { if ($isprime[$i-$M] == 1) { print "$i\n"; } } } |
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | // PRIME1 - C# (gmcs) // AC Time: 1.50s using System; class PRIME1 { static void Main() { int[] primes = new int[4000]; int numprimes = 0; primes[numprimes++] = 2; for (int i = 3; i <= 32000; i+=2) { bool isprime = true; double cap = Math.Sqrt(i) + 1.0; for (int j = 0; j < numprimes; j++) { if (j >= cap) break; if (i % primes[j] == 0) { isprime = false; break; } } if (isprime) primes[numprimes++] = i; } int T,N,M; T = int.Parse(Console.ReadLine()); for (int t = 0; t < T; t++) { if (t > 0) Console.WriteLine(""); string[] parts = Console.ReadLine().Split(' '); M = int.Parse(parts[0]); N = int.Parse(parts[1]); if (M < 2) M = 2; double cap = Math.Sqrt(N)+1; bool[] isprime = new bool[100001]; for (int i = 0; i < 100001; i++) isprime[i] = true; for (int i = 0; i < numprimes; i++) { int p = primes[i]; if (p >= cap) break; int start; if (p >= M) start = p*2; else start = M + ((p - M % p)%p); for (int j = start; j <= N; j+= p) { isprime[j - M] = false; } } for (int i = M; i <= N; i++) { if (isprime[i-M] == true) Console.WriteLine(i); } } } } |
GNU Pascal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | { PRIME1 - GNU Pascal AC Time: 0.54 } program PRIME1; var primes: array[1..4000] of integer; numprimes: integer; i,j: integer; cap: double; isprime: boolean; T,N,M: integer; isp: array[0..100001] of boolean; p,start: integer; begin primes[1] := 2; numprimes := 1; for i := 3 to 32000 do begin isprime := true; cap := sqrt(i) + 1; for j := 1 to numprimes do begin if primes[j] >= cap then break; if (i MOD primes[j] = 0) then begin isprime := false; break; end end; if isprime = true then begin numprimes := numprimes + 1; primes[numprimes] := i end end; read(T); for t := 1 to T do begin if t > 0 then writeln(''); read(M); read(N); if M < 2 then M := 2; cap := sqrt(N) + 1; for i := 0 to 100001 do isp[i] := true; for i := 1 to numprimes do begin p := primes[i]; if p >= cap then break; if p >= M then start := (p * 2); if p < M then start := M + ((p - (M MOD p)) MOD p); j := start; while j <= N do begin isp[j - M] := false; j := j + p; end; end; for i := M to N do begin if isp[i-M] = true then writeln(i); end; end; end. |
November 13th, 2009 - 22:11
Wow you have a lot of time – very impressive! I’d like to see you continue this for those graph theory, convex hull, optimized-brute-force, etc. problems.
Also, check out Google’s Go programming language just released a few days ago: http://en.wikipedia.org/wiki/Go_%28programming_language%29
January 14th, 2010 - 19:58
can you please tell me why my code generates runtime error??
link : http://codeviewer.org/view/code:b18
Thanks , i tried your cpp code and it worked well
.
January 14th, 2010 - 20:01
and how i can fix it ??
January 14th, 2010 - 20:25
Check this link not the other one : http://codeviewer.org/view/code:b19