Prime number calculation fun - java

We're having a bit of fun here at work. It all started with one of the guys setting up a Hackintosh and we were wondering whether it was faster than a Windows Box of (nearly) same specs that we have. So we decided to write a little test for it. Just a simple Prime number calculator. It's written in Java and tells us the time it takes to calculate the first n Prime numbers.
Optimised version below - now takes ~6.6secs
public class Primes {
public static void main(String[] args) {
int topPrime = 150000;
int current = 2;
int count = 0;
int lastPrime = 2;
long start = System.currentTimeMillis();
while (count < topPrime) {
boolean prime = true;
int top = (int)Math.sqrt(current) + 1;
for (int i = 2; i < top; i++) {
if (current % i == 0) {
prime = false;
break;
}
}
if (prime) {
count++;
lastPrime = current;
}
if (current == 2) {
current++;
} else {
current = current + 2;
}
}
System.out.println("Last prime = " + lastPrime);
System.out.println("Total time = " + (double)(System.currentTimeMillis() - start) / 1000);
}
}
We've pretty much lost the plot of the whole Hackintosh vs PC thing and are just having some fun with optimising it. First attempt with no optimisations (the above code has a couple) ran around 52.6min to find the first 150000 prime numbers. This optimisation is running around 47.2mins.
If you want to have a go and post your results, then stick em up.
Specs for the PC I'm running it on are Pentium D 2.8GHz, 2GB RAM, running Ubuntu 8.04.
Best Optimisation so far has been the square root of current, first mentioned by Jason Z.

That's a bit worse than my sieve did on a 8 Mhz 8088 in turbo pascal in 1986 or so. But that was after optimisations :)

Since you're searching for them in ascending order, you could keep a list of the primes you've already found and only check for divisibility against them, since all non-prime numbers can be reduced to a list of lesser prime factors. Combine that with the previous tip about not checking for factors over the square root of the current number, and you'll have yourself a pretty darn efficient implementation.

Well I see a couple of quick optimizations that can be done.
First you don't have to try each number up to half of the current number.
Instead you only have try up to the square root of the current number.
And the other optimization was what BP said with a twist:
Instead of
int count = 0;
...
for (int i = 2; i < top; i++)
...
if (current == 2)
current++;
else
current += 2;
use
int count = 1;
...
for (int i = 3; i < top; i += 2)
...
current += 2;
This should speed things up quite a lot.
Edit:
More optimization courtesy of Joe Pineda:
Remove the variable "top".
int count = 1;
...
for (int i = 3; i*i <= current; i += 2)
...
current += 2;
If this optimization indeed increases speed is up to java.
Calculating the square root takes a lot of time compared to multiplying two numbers. However since we move the multiplication into the for loop this is done every single loop. So this COULD slow things down depending on how fast the square root algorithm in java is.

Here is a fast and simple solution:
Finding primes less than 100000; 9592 were found in 5 ms
Finding primes less than 1000000; 78498 were found in 20 ms
Finding primes less than 10000000; 664579 were found in 143 ms
Finding primes less than 100000000; 5761455 were found in 2024 ms
Finding primes less than 1000000000; 50847534 were found in 23839 ms
//returns number of primes less than n
private static int getNumberOfPrimes(final int n)
{
if(n < 2)
return 0;
BitSet candidates = new BitSet(n - 1);
candidates.set(0, false);
candidates.set(1, false);
candidates.set(2, n);
for(int i = 2; i < n; i++)
if(candidates.get(i))
for(int j = i + i; j < n; j += i)
if(candidates.get(j) && j % i == 0)
candidates.set(j, false);
return candidates.cardinality();
}

It takes us under a second (2.4GHz) to generate the first 150000 prime numbers in Python using Sieve of Eratosthenes:
#!/usr/bin/env python
def iprimes_upto(limit):
"""Generate all prime numbers less then limit.
http://stackoverflow.com/questions/188425/project-euler-problem#193605
"""
is_prime = [True] * limit
for n in range(2, limit):
if is_prime[n]:
yield n
for i in range(n*n, limit, n): # start at ``n`` squared
is_prime[i] = False
def sup_prime(n):
"""Return an integer upper bound for p(n).
p(n) < n (log n + log log n - 1 + 1.8 log log n / log n)
where p(n) is the n-th prime.
http://primes.utm.edu/howmany.shtml#2
"""
from math import ceil, log
assert n >= 13
pn = n * (log(n) + log(log(n)) - 1 + 1.8 * log(log(n)) / log(n))
return int(ceil(pn))
if __name__ == '__main__':
import sys
max_number_of_primes = int(sys.argv[1]) if len(sys.argv) == 2 else 150000
primes = list(iprimes_upto(sup_prime(max_number_of_primes)))
print("Generated %d primes" % len(primes))
n = 100
print("The first %d primes are %s" % (n, primes[:n]))
Example:
$ python primes.py
Generated 153465 primes
The first 100 primes are [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541]

In C#:
class Program
{
static void Main(string[] args)
{
int count = 0;
int max = 150000;
int i = 2;
DateTime start = DateTime.Now;
while (count < max)
{
if (IsPrime(i))
{
count++;
}
i++;
}
DateTime end = DateTime.Now;
Console.WriteLine("Total time taken: " + (end - start).TotalSeconds.ToString() + " seconds");
Console.ReadLine();
}
static bool IsPrime(int n)
{
if (n < 4)
return true;
if (n % 2 == 0)
return false;
int s = (int)Math.Sqrt(n);
for (int i = 2; i <= s; i++)
if (n % i == 0)
return false;
return true;
}
}
Output:
Total time taken: 2.087 seconds

Keeping in mind that there are better ways to look for primes...
I think that you can take this loop:
for (int i = 2; i < top; i++)
and make it so that your counter variable i goes from 3 and only tries to do the mod on odd numbers, since all primes other than 2 are never divisible by any even numbers.

Does the re-declaration of the variable prime
while (count < topPrime) {
boolean prime = true;
within the loop make it inefficient? (I assume it doesn't matter, since I would think Java would optimize this)
boolean prime;
while (count < topPrime) {
prime = true;

C#
Enhancement to Aistina's code:
This makes use of the fact that all primes greater than 3 are of the form 6n + 1 or 6n - 1.
This was about a 4-5% speed increase over incrementing by 1 for every pass through the loop.
class Program
{
static void Main(string[] args)
{
DateTime start = DateTime.Now;
int count = 2; //once 2 and 3
int i = 5;
while (count < 150000)
{
if (IsPrime(i))
{
count++;
}
i += 2;
if (IsPrime(i))
{
count++;
}
i += 4;
}
DateTime end = DateTime.Now;
Console.WriteLine("Total time taken: " + (end - start).TotalSeconds.ToString() + " seconds");
Console.ReadLine();
}
static bool IsPrime(int n)
{
//if (n < 4)
//return true;
//if (n % 2 == 0)
//return false;
int s = (int)Math.Sqrt(n);
for (int i = 2; i <= s; i++)
if (n % i == 0)
return false;
return true;
}
}

My take at optimization, avoiding too cryptic tricks. I use the trick given by I-GIVE-TERRIBLE-ADVICE, which I knew and forgot... :-)
public class Primes
{
// Original code
public static void first()
{
int topPrime = 150003;
int current = 2;
int count = 0;
int lastPrime = 2;
long start = System.currentTimeMillis();
while (count < topPrime) {
boolean prime = true;
int top = (int)Math.sqrt(current) + 1;
for (int i = 2; i < top; i++) {
if (current % i == 0) {
prime = false;
break;
}
}
if (prime) {
count++;
lastPrime = current;
// System.out.print(lastPrime + " "); // Checking algo is correct...
}
if (current == 2) {
current++;
} else {
current = current + 2;
}
}
System.out.println("\n-- First");
System.out.println("Last prime = " + lastPrime);
System.out.println("Total time = " + (double)(System.currentTimeMillis() - start) / 1000);
}
// My attempt
public static void second()
{
final int wantedPrimeNb = 150000;
int count = 0;
int currentNumber = 1;
int increment = 4;
int lastPrime = 0;
long start = System.currentTimeMillis();
NEXT_TESTING_NUMBER:
while (count < wantedPrimeNb)
{
currentNumber += increment;
increment = 6 - increment;
if (currentNumber % 2 == 0) // Even number
continue;
if (currentNumber % 3 == 0) // Multiple of three
continue;
int top = (int) Math.sqrt(currentNumber) + 1;
int testingNumber = 5;
int testIncrement = 2;
do
{
if (currentNumber % testingNumber == 0)
{
continue NEXT_TESTING_NUMBER;
}
testingNumber += testIncrement;
testIncrement = 6 - testIncrement;
} while (testingNumber < top);
// If we got there, we have a prime
count++;
lastPrime = currentNumber;
// System.out.print(lastPrime + " "); // Checking algo is correct...
}
System.out.println("\n-- Second");
System.out.println("Last prime = " + lastPrime);
System.out.println("Total time = " + (double) (System.currentTimeMillis() - start) / 1000);
}
public static void main(String[] args)
{
first();
second();
}
}
Yes, I used a labeled continue, first time I try them in Java...
I know I skip computation of the first few primes, but they are well known, no point to recompute them. :-) I can hard-code their output if needed! Beside, it doesn't give a decisive edge anyway.
Results:
-- First
Last prime = 2015201
Total time = 4.281
-- Second
Last prime = 2015201
Total time = 0.953
Not bad. Might be improved a bit, I suppose, but too much optimization can kill good code.

You should be able to make the inner loop twice as fast by only evaluating the odd numbers. Not sure if this is valid Java, I'm used to C++, but I'm sure it can be adapted.
if (current != 2 && current % 2 == 0)
prime = false;
else {
for (int i = 3; i < top; i+=2) {
if (current % i == 0) {
prime = false;
break;
}
}
}

I decided to try this in F#, my first decent attempt at it. Using the Sieve of Eratosthenes on my 2.2Ghz Core 2 Duo it runs through 2..150,000 in about 200 milliseconds. Each time it calls it self it's eliminated the current multiples from the list, so it just gets faster as it goes along. This is one of my first tries in F# so any constructive comments would be appreciated.
let max = 150000
let numbers = [2..max]
let rec getPrimes sieve max =
match sieve with
| [] -> sieve
| _ when sqrt(float(max)) < float sieve.[0] -> sieve
| _ -> let prime = sieve.[0]
let filtered = List.filter(fun x -> x % prime <> 0) sieve // Removes the prime as well so the recursion works correctly.
let result = getPrimes filtered max
prime::result // The filter removes the prime so add it back to the primes result.
let timer = System.Diagnostics.Stopwatch()
timer.Start()
let r = getPrimes numbers max
timer.Stop()
printfn "Primes: %A" r
printfn "Elapsed: %d.%d" timer.Elapsed.Seconds timer.Elapsed.Milliseconds

I bet Miller-Rabin would be faster. If you test enough contiguous numbers it becomes deterministic, but I wouldn't even bother. Once a randomized algorithm reaches the point that its failure rate is equal to the likelihood that a CPU hiccup will cause a wrong result, it just doesn't matter any more.

Here's my solution... its fairly fast... it calculates the primes between 1 and 10,000,000 in 3 seconds on my machine (core i7 # 2.93Ghz) on Vista64.
My solution is in C, but I am not a professional C programmer. Feel free to criticize the algorithm and the code itself :)
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
//5MB... allocate a lot of memory at once each time we need it
#define ARRAYMULT 5242880
//list of calculated primes
__int64* primes;
//number of primes calculated
__int64 primeCount;
//the current size of the array
__int64 arraySize;
//Prints all of the calculated primes
void PrintPrimes()
{
__int64 i;
for(i=0; i<primeCount; i++)
{
printf("%d ", primes[i]);
}
}
//Calculates all prime numbers to max
void CalcPrime(__int64 max)
{
register __int64 i;
double square;
primes = (__int64*)malloc(sizeof(__int64) * ARRAYMULT);
primeCount = 0;
arraySize = ARRAYMULT;
//we provide the first prime because its even, and it would be convenient to start
//at an odd number so we can skip evens.
primes[0] = 2;
primeCount++;
for(i=3; i<max; i+=2)
{
int j;
square = sqrt((double)i);
//only test the current candidate against other primes.
for(j=0; j<primeCount; j++)
{
//prime divides evenly into candidate, so we have a non-prime
if(i%primes[j]==0)
break;
else
{
//if we've reached the point where the next prime is > than the square of the
//candidate, the candidate is a prime... so we can add it to the list
if(primes[j] > square)
{
//our array has run out of room, so we need to expand it
if(primeCount >= arraySize)
{
int k;
__int64* newArray = (__int64*)malloc(sizeof(__int64) * (ARRAYMULT + arraySize));
for(k=0; k<primeCount; k++)
{
newArray[k] = primes[k];
}
arraySize += ARRAYMULT;
free(primes);
primes = newArray;
}
//add the prime to the list
primes[primeCount] = i;
primeCount++;
break;
}
}
}
}
}
int main()
{
int max;
time_t t1,t2;
double elapsedTime;
printf("Enter the max number to calculate primes for:\n");
scanf_s("%d",&max);
t1 = time(0);
CalcPrime(max);
t2 = time(0);
elapsedTime = difftime(t2, t1);
printf("%d Primes found.\n", primeCount);
printf("%f seconds elapsed.\n\n",elapsedTime);
//PrintPrimes();
scanf("%d");
return 1;
}

Here is my take on it. The program is writtern in C and takes 50 milliseconds on my laptop(Core 2 Duo, 1 GB Ram). I am keeping all the calculated primes in an array and trying divisibility only till sqrt of number. Of course, this doesnt work when we need very large number of primes(tried with 100000000) as array grows too big and gives seg fault.
/*Calculate the primes till TOTALPRIMES*/
#include <stdio.h>
#define TOTALPRIMES 15000
main(){
int primes[TOTALPRIMES];
int count;
int i, j, cpr;
char isPrime;
primes[0] = 2;
count = 1;
for(i = 3; count < TOTALPRIMES; i+= 2){
isPrime = 1;
//check divisiblity only with previous primes
for(j = 0; j < count; j++){
cpr = primes[j];
if(i % cpr == 0){
isPrime = 0;
break;
}
if(cpr*cpr > i){
break;
}
}
if(isPrime == 1){
//printf("Prime: %d\n", i);
primes[count] = i;
count++;
}
}
printf("Last prime = %d\n", primes[TOTALPRIMES - 1]);
}
$ time ./a.out
Last prime = 163841
real 0m0.045s
user 0m0.040s
sys 0m0.004s

# Mark Ransom - not sure if this is java code
They will moan possibly but I wished to rewrite using paradigm I have learned to trust in Java and they said to have some fun, please make sure they understand that spec says nothing that effects ordering on the returned result set, also you would cast result set dot values() to a list type given my one-off in Notepad before taking a short errand
=============== begin untested code ===============
package demo;
import java.util.List;
import java.util.HashSet;
class Primality
{
int current = 0;
int minValue;
private static final HashSet<Integer> resultSet = new HashSet<Integer>();
final int increment = 2;
// An obvious optimization is to use some already known work as an internal
// constant table of some kind, reducing approaches to boundary conditions.
int[] alreadyKown =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541
};
// Trivial constructor.
public Primality(int minValue)
{
this.minValue = minValue;
}
List calcPrimes( int startValue )
{
// eliminate several hundred already known primes
// by hardcoding the first few dozen - implemented
// from prior work by J.F. Sebastian
if( startValue > this.minValue )
{
// Duh.
current = Math.abs( start );
do
{
boolean prime = true;
int index = current;
do
{
if(current % index == 0)
{
// here, current cannot be prime so break.
prime = false;
break;
}
while( --index > 0x00000000 );
// Unreachable if not prime
// Here for clarity
if ( prime )
{
resultSet dot add ( or put or whatever it is )
new Integer ( current ) ;
}
}
while( ( current - increment ) > this.minValue );
// Sanity check
if resultSet dot size is greater that zero
{
for ( int anInt : alreadyKown ) { resultSet.add( new Integer ( anInt ) );}
return resultSet;
}
else throw an exception ....
}
=============== end untested code ===============
Using Hash Sets allows searching results as B-Trees, thus results could be stacked up until the machine begins to fail then that starting point could be used for another block of testing == the end of one run used as a Constructor value for another run, persisting to disk work already accomplished and allowing incremental feed-forward designs. Burnt out right now, loop logic needs analysis.
patch (plus add sqrt) :
if(current % 5 == 0 )
if(current % 7 == 0 )
if( ( ( ( current % 12 ) +1 ) == 0) || ( ( ( current % 12 ) -1 ) == 0) ){break;}
if( ( ( ( current % 18 ) +1 ) == 0) || ( ( ( current % 18 ) -1 ) == 0) ){break;}
if( ( ( ( current % 24 ) +1 ) == 0) || ( ( ( current % 24 ) -1 ) == 0) ){break;}
if( ( ( ( current % 36 ) +1 ) == 0) || ( ( ( current % 36 ) -1 ) == 0) ){break;}
if( ( ( ( current % 24 ) +1 ) == 0) || ( ( ( current % 42 ) -1 ) == 0) ){break;}
// and - new work this morning:
package demo;
/**
*
* Buncha stuff deleted for posting .... duh.
*
* #author Author
* #version 0.2.1
*
* Note strings are base36
*/
public final class Alice extends java.util.HashSet<java.lang.String>
{
// prints 14551 so it's 14 ½ seconds to get 40,000 likely primes
// using Java built-in on amd sempron 1.8 ghz / 1600 mhz front side bus 256 k L-2
public static void main(java.lang.String[] args)
{
try
{
final long start=System.currentTimeMillis();
// VM exhibits spurious 16-bit pointer behaviour somewhere after 40,000
final java.lang.Integer upperBound=new java.lang.Integer(40000);
int index = upperBound.intValue();
final java.util.HashSet<java.lang.String>hashSet
= new java.util.HashSet<java.lang.String>(upperBound.intValue());//
// Arbitraily chosen value, based on no idea where to start.
java.math.BigInteger probablePrime
= new java.math.BigInteger(16,java.security.SecureRandom.getInstance("SHA1PRNG"));
do
{
java.math.BigInteger nextProbablePrime = probablePrime.nextProbablePrime();
if(hashSet.add(new java.lang.String(nextProbablePrime.toString(Character.MAX_RADIX))))
{
probablePrime = nextProbablePrime;
if( ( index % 100 ) == 0x00000000 )
{
// System.out.println(nextProbablePrime.toString(Character.MAX_RADIX));//
continue;
}
else
{
continue;
}
}
else
{
throw new StackOverflowError(new String("hashSet.add(string) failed on iteration: "+
Integer.toString(upperBound.intValue() - index)));
}
}
while(--index > 0x00000000);
System.err.println(Long.toString( System.currentTimeMillis() - start));
}
catch(java.security.NoSuchAlgorithmException nsae)
{
// Never happen
return;
}
catch(java.lang.StackOverflowError soe)
{
// Might happen
System.out.println(soe.getMessage());//
return;
}
}
}// end class Alice

I found this code somewhere on my machine when I started reading this blog entry about prime numbers.
The code is in C# and the algorithm I used came from my head although it is probably somewhere on Wikipedia. ;)
Anyway, it can fetch the first 150000 prime numbers in about 300ms. I discovered that the sum of the n first odd numbers is equal to n^2. Again, there is probably a proof of this somewhere on wikipedia. So knowing this, I can write an algorithm that wil never have to calculate a square root but I have to calculate incrementally to find the primes. So if you want the Nth prime, this algo will have to find the (N-1) preceding primes before! So there it is. Enjoy!
//
// Finds the n first prime numbers.
//
//count: Number of prime numbers to find.
//listPrimes: A reference to a list that will contain all n first prime if getLast is set to false.
//getLast: If true, the list will only contain the nth prime number.
//
static ulong GetPrimes(ulong count, ref IList listPrimes, bool getLast)
{
if (count == 0)
return 0;
if (count == 1)
{
if (listPrimes != null)
{
if (!getLast || (count == 1))
listPrimes.Add(2);
}
return count;
}
ulong currentSquare = 1;
ulong nextSquare = 9;
ulong nextSquareIndex = 3;
ulong primesCount = 1;
List dividers = new List();
//Only check for odd numbers starting with 3.
for (ulong curNumber = 3; (curNumber (nextSquareIndex % div) == 0) == false)
dividers.Add(nextSquareIndex);
//Move to next square number
currentSquare = nextSquare;
//Skip the even dividers so take the next odd square number.
nextSquare += (4 * (nextSquareIndex + 1));
nextSquareIndex += 2;
//We may continue as a square number is never a prime number for obvious reasons :).
continue;
}
//Check if there is at least one divider for the current number.
//If so, this is not a prime number.
if (dividers.Exists(div => (curNumber % div) == 0) == false)
{
if (listPrimes != null)
{
//Unless we requested only the last prime, add it to the list of found prime numbers.
if (!getLast || (primesCount + 1 == count))
listPrimes.Add(curNumber);
}
primesCount++;
}
}
return primesCount;
}

Here's my contribution:
Machine: 2.4GHz Quad-Core i7 w/ 8GB RAM # 1600MHz
Compiler: clang++ main.cpp -O3
Benchmarks:
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 100
Calculated 25 prime numbers up to 100 in 2 clocks (0.000002 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 1000
Calculated 168 prime numbers up to 1000 in 4 clocks (0.000004 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 10000
Calculated 1229 prime numbers up to 10000 in 18 clocks (0.000018 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 100000
Calculated 9592 prime numbers up to 100000 in 237 clocks (0.000237 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 1000000
Calculated 78498 prime numbers up to 1000000 in 3232 clocks (0.003232 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 10000000
Calculated 664579 prime numbers up to 10000000 in 51620 clocks (0.051620 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 100000000
Calculated 5761455 prime numbers up to 100000000 in 918373 clocks (0.918373 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 1000000000
Calculated 50847534 prime numbers up to 1000000000 in 10978897 clocks (10.978897 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$ ./a.out 4000000000
Calculated 189961812 prime numbers up to 4000000000 in 53709395 clocks (53.709396 seconds).
Caelans-MacBook-Pro:Primer3 Caelan$
Source:
#include <iostream> // cout
#include <cmath> // sqrt
#include <ctime> // clock/CLOCKS_PER_SEC
#include <cstdlib> // malloc/free
using namespace std;
int main(int argc, const char * argv[]) {
if(argc == 1) {
cout << "Please enter a number." << "\n";
return 1;
}
long n = atol(argv[1]);
long i;
long j;
long k;
long c;
long sr;
bool * a = (bool*)malloc((size_t)n * sizeof(bool));
for(i = 2; i < n; i++) {
a[i] = true;
}
clock_t t = clock();
sr = sqrt(n);
for(i = 2; i <= sr; i++) {
if(a[i]) {
for(k = 0, j = 0; j <= n; j = (i * i) + (k * i), k++) {
a[j] = false;
}
}
}
t = clock() - t;
c = 0;
for(i = 2; i < n; i++) {
if(a[i]) {
//cout << i << " ";
c++;
}
}
cout << fixed << "\nCalculated " << c << " prime numbers up to " << n << " in " << t << " clocks (" << ((float)t) / CLOCKS_PER_SEC << " seconds).\n";
free(a);
return 0;
}
This uses the Sieve of Erastothenes approach, I've optimised it as much as I can with my knowledge. Improvements welcome.

Related

What edits to my code should I make to handle the error?

I wrote a program where function isHappy takes in a long value and returns a statement of either True or False based on what the output number is... (1 means True; 4 means false).
The way my program reaches the output is by squaring each digit of the input n and adding them repeatedly until the output is only 1 digit
For instance, if n = 19, the code would return 1 because:
1^2 + 9^2 = 82, from which digits 8 and 2 would do: 8^2 + 2^2 = 68, from which digits 6^2 + 8^2 = 100, from which 1^2 + 0^2 + 0^2 = 1. <== 1 is only one digit, therefore, it shall be the answer.
Please note that every input I get will end up with either 1 or 4
Anyways, here is my code so far,
public class Happy
{
public static void main(String args[])
{
System.out.println(isHappy(989));
}
public static boolean isHappy(long n) {
long sum = 0;
boolean l = true;
boolean j = false;
while (n != 0) {
sum = sum + ((n % 10) * (n % 10));
n = n / 10;
}
if (sum == 1) {
return l;
} else {
return j;
}
}
}
When my plug in test case inputs like isHappy(100), isHappy(111), isHappy(1234), the program seems to work where
1 = True, 4 means false
isHappy(100) == true
isHappy(111) == false
isHappy(1234) == false
However, when I plug in specific numbers like isHappy(989), the program should be true since
9^2 + 8^2 + 9^2 = 226; 2^2 + 2^2 + 6^2 = 44; 4^2 + 4^2 = 32; 3^2 + 2^2 = 13; 1^2 + 3^2 = 10 and lastly 1^2 + 0^2 = 1; which is True.
However, after running my code, my output prints false instead.
I've tried debugging my code but I can't seem to find a problem. Any help on what changes to my code do I have to make would be greatly appreciated :)
You're mixing the two parts of the algorithm: calculating the sum of squared digits and verifying if the number is a "happy number".
After calculating the sum for the given number in case when the sum is naughtier 1, no 4, the sum becomes a new number to check, and we need to continue with calculating its sum.
So basically we need two loops, or two separate methods.
That that's how it can be implemented.
public static boolean isHappy(long n) {
while (n != 1 && n != 4) { // given number is naughtier `1`, no `4`
n = getHappySum(n); // calculating the sum
}
return n == 1;
}
public static int getHappySum(long n) {
int sum = 0;
while (n != 0) {
sum += Math.pow(n % 10, 2);
n /= 10;
}
return sum;
}
main()
public static void main(String[] args) {
System.out.println(isHappy(100));
System.out.println(isHappy(111));
System.out.println(isHappy(1234));
}
Output:
true
false
false

Prime numbers - I need clarification on code implementation

This is the code I know:
bool checkPrime(int n) {
bool prime = true;
for (int i = 2; i < n; i++) {
if ((n%i) == 0) {
prime = false;
}
}
return prime;
}
But is this ok if you’re looking for prime numbers:
List<int> arr = [2, 3, 5, 7]; // Already known
int n = 30; // Between 1 to 30. It could be any number
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0) {
arr.add(i);
}
// Then maybe some code for numbers less than 8
}
print(arr);
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
And also is there much difference in time complexity?
Your code is incorrect.
This code only works because you are taking the value of n as 30, for a greater number like 1000 this will produce an incorrect result.
List arr = [2,3,5,7]; // already known
int n = 1000; // between 1 to 1000 it could be any number
List<int> arr = [2,3,5,7];
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0){
arr.add(i);
}
//Then maybe some code for numbers less than 8
}
print(arr);
Your code will return 231 prime numbers when there are actually only 168 prime numbers.
This is because you are not considering the future prime numbers that can only be divided by a prime number between 7 to that number.
eg: 121 will be returned by you as prime but it is a multiple of 11
Extending your pattern.
Though this will be faster since it has reduced a number of division operations but due to two loops, it will still be N square.
Here I am simply only dividing numbers from the existing prime numbers collection and adding them in the collection if prime is found tobe used in next iteration for division.
List < int > arr = [2]; // taking 2 since this is the lowerst value we want to start with
int n = 30; // n can between 2 to any number
if (n < 3) {
print(arr); // can return from here.
}
// since we already have added 2 in the list we start with next number to check that is 3
for (int i = 3; i < n; i++) {
bool isPrime = true;
for (int j = 0; j < arr.length; j++) { // we iterate over the current prime number collection only [2] then [2,3]...
if (i % arr[j] == 0) { // check if number can be divided by exisiting numbers
isPrime = false;
}
}
if (isPrime) { // eg: 2 cant divide 3 so we 3 is also added
arr.add(i)
}
}
print(arr);
You can look a faster pattern here.
Which is the fastest algorithm to find prime numbers?

Random - nextInt(int y) isn't able to give me 18 even integers in a row when 'int y' % 2 == 0 && 'int y' != a power of 2

sorry for that title but I wanted to pack as much information about my problem in as little space as possible without being too confusing.
So, I have a loop which runs n times and each time it uses a = r.nextInt(int y); to generate an int and if all n integers generated are even numbers, then the program "returns true".
The weird thing is: if I chose n to be 18 or higher while y is and even number which is not a power of 2, then the programm will not "termintate successfully".
I love to help you help me, and can take a heavy dose of criticism.
(I know I'm asking about the Random/nextInt(int) topic but I will also take tips for better coding)
EDIT: I looked into the Documentation for Java8 befor I posted here and for powers of two the method uses a different way of producing the random number.
What I don't understand is why is 18 the breakpoint for consecutive even numbers and why does it work with odd numbers for nextInt(int)?
So the following code will work with howManyInts = 16 or 17 but not 18 (or higher) when nextIntValue is an even number which is not a power of two (6,10,12...)
It works with howManyInts = 25 and nextIntValue = 8 in less than 20 seconds
import java.util.*;
class test{
public static void main(String[] args) {
boolean win = false;
int areEven = 0;
long loopCounter = 0; // The loopCounter is used to control the maximum number of loops should be run incase the loop is endless
int howManyInts = 18;
int nextIntValue = 6; // nextIntValue = 6 or 10 won't work while all powers of 2 work fine
// also, I don't want an odd value as that would change to odds towards odd values...
while(win == false){
loopCounter += 1;
areEven = 0;
Random r = new Random();
int[] num = new int[howManyInts];
for(int a = 0; a < num.length; a++){
num[a] = r.nextInt(nextIntValue);
if(num[a] % 2 == 0){
areEven += 1;
}
}
if(areEven == num.length || loopCounter >= 10000000){
win = true;
System.out.println("It took " + loopCounter + " loops to get " + num.length + " random values which are all even.");
}
}
}
}
If you use SecureRandom instead of Random, your program will finish fairly quickly.
Another way would be to use nextDouble instead
num[a] = (int) (r.nextDouble() * nextIntValue);
The problem with Random.nextInt(int n) is I believe hidden within its implementation and you can read about it in its javadoc.
The algorithm is slightly tricky. It rejects values that would result
in an uneven distribution (due to the fact that 2^31 is not divisible
by n). The probability of a value being rejected depends on n. The
worst case is n=2^30+1, for which the probability of a reject is 1/2,
and the expected number of iterations before the loop terminates is 2.
The algorithm treats the case where n is a power of two specially: it
returns the correct number of high-order bits from the underlying
pseudo-random number generator. In the absence of special treatment,
the correct number of low-order bits would be returned. Linear
congruential pseudo-random number generators such as the one
implemented by this class are known to have short periods in the
sequence of values of their low-order bits. Thus, this special case
greatly increases the length of the sequence of values returned by
successive calls to this method if n is a small power of two.
The implementation looks like this:
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
return val;
}
While the next method looks like this (I've replaced the constants with literals)
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
(I suppose that 48-31 == 17 is purely coincidental)
Interesting question!
I have added some statistic-gathering to the code:
import java.util.*;
public class J {
static Random r = new Random();
private static class Stats {
long s[];
public Stats(int n) { this.s = new long[n]; }
public String toString() {
return Arrays.toString(s);
}
}
public static void test(int target, int options) {
boolean win = false;
Stats s = new Stats(target);
for (long iterations = 0; !win; iterations ++) {
int even = 0;
for (int i = 0; i < target; i++) {
if ((r.nextInt(options) % 2) != 0) {
s.s[i] ++;
break;
} else {
even ++;
}
}
if (even == target) {
win = true;
System.out.println(
"It took " + iterations + " loops to get " + target
+ " random values which are all even. Stats: " + s);
} else if (iterations >= 1E8) {
win = true;
System.out.println(iterations + ": " + s);
}
}
}
public static void main(String args[]) {
test(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
}
}
The code now ends if no sequence is found after 100M tries; and always stores how far it managed to get before failing (= drawing an odd number).
These are some runs:
18 9: It took 57235 loops to get 18 random values which are all even. Stats: [25401, 14081, 7864, 4328, 2508, 1366, 747, 390, 263, 126, 76, 38, 28, 4, 8, 4, 2, 1]
18 8: It took 48612 loops to get 18 random values which are all even. Stats: [24285, 12336, 6066, 2981, 1436, 738, 385, 197, 95, 43, 23, 10, 8, 7, 1, 0, 0, 1]
18 7: It took 23302 loops to get 18 random values which are all even. Stats: [10062, 5712, 3174, 1877, 1101, 590, 331, 190, 98, 59, 44, 31, 18, 8, 5, 2, 0, 0]
18 6: Aborted after 100000000 tries: [49997688, 24993911, 12503043, 6272129, 3113557, 1544194, 788879, 393680, 205236, 89264, 45016, 35858, 5340, 9155, 763, 1525, 0, 763]
So, for those particular values (100M attempts at runs of 18 even numbers, throwing 6-sided dice), there were 0 cases where the run bailed out because of the 17th number, but 763(!) where it bailed out because of the last number!
It definitely looks like a higher-quality PRNG is needed, such as the one mentioned by #radoh.
Probabilistically speaking, you would expect to find runs of N even throws of a fair coin with probability 1/(2^N); and you would expect to collect stats where each entry would be 1/2 the previous one. Encountering 0, 763 indicates a strong bias.
The issue is almost certainly with r.nextInt(nextIntValue);. Here you are requesting a random integer between 0 and 5. I cannot understand specifically why 18 is the break point but the chances a sequence of random positive integers less than a small number to be all even must reduce as the limit reduces.
I note that increasing that value from 6 to 100 still does not find length-18 even sequences. Perhaps the algorithm behind the scenes somehow influences the statistics.
Seems like the random generator doesn't allow 18 consecutive even numbers, when your maxRandom is even, starting at 6.
I changed the code a bit to demonstrate how the 18th random is always odd:
class NextIntWeirdness {
public static void main(String[] args) {
int maxRandom = 6;
Random r = new Random();
for (int i = 0; i < 100; i++) {
int evenNumbers = 17;
int evenResults;
do {
evenResults = 0;
for (int j = 0; j < evenNumbers; j++) {
int num = r.nextInt(maxRandom);
if (num % 2 != 0) {
break;
} else {
evenResults++;
}
}
} while (evenResults < evenNumbers);
System.out.println(r.nextInt(maxRandom));
}
}
}

Happy numbers checker not working correctly

int Cnt(){
return Count (10);
}
int Count (int init){
int u = init % 10;
int t = (init % 100) - u;
int u2 = u * u;
int t2 = t * t;
int m = u2 + t2;
if(m <= 1)
System.out.println("Happy!");
else {
return Count (m);
}
This code should (in theory) check if number is Happy, and if it's not sets initial value to be same as the result and whole process repeats.
Infinite loop should occur if number is not happy.
However none of this happens, does anyone know how to make this work?
According to the Wiki article that you linked, you have to repeat the process of summing the digits of the digits in each number. For the example of 7:
7^2 = 49
49 = 4^2 + 9^2 = 16 + 81 = 97
97 = 9^2 + 7^2 = 81 + 49 = 130
130 = 1^2 + 3^2 = 10
10 = 1^2 = 1
I see a few problems with your code. First, you haven't divided your tens digit by 10, which means for the number 52, you will get u = 2, and t = 50, rather than 5. This part, I'm sure you can easily fix.
Second, it looks like you will never reach a conclusion if your number is unhappy. For example with the number 4, you will reach 16, 37, 72, 53, 34, 25, 29, 85, 89, 145, 42, 20, 4. But your program, since you have no way of checking that you've entered a loop, will run until you run out of memory.
Try using the approach as outlined in the article you referenced:
private static boolean isHappy(int number)
{
List<Integer> set = new ArrayList<Integer>();
while (number > 1 && !set.contains(number))
{
set.add(number);
number = sumSquaresOfDigits(number);
}
return number == 1;
}
private static int sumSquaresOfDigits(int number)
{
String numberString = Integer.toString(number);
int result = 0;
for (char character : numberString.toCharArray())
{
int digit = Character.digit(character, 10);
result += digit * digit;
}
return result;
}
This can be done more efficiently by computing the squares of all 10 digits (0-9) and storing the results in an integer array.
Since this is homework I am not putting in the answer... but here is the clue..
You are not handling 3 digit numbers well.
t=init%100-u computes to 10%100-0 = 10
and once m=u2+t2 i.e. m=0+100 reaches to 100 and your program doesn't handle 3 digit numbers. Hope this helps.
add following...
int h = init/100;
int h2 = h * h;
int m = u2+t2+h2;
and it should keep you going... :)
import java.io.*;
class happy_no
{
void happy(double n)
{
int c=0;
double s=0;
double d,p,i,_sa;
for(i=1;i<=n;i++)
{
while(n!=0)
{
d=n%10;
p=d*d;
s=s+p;
n=n/10;
}
if(s==1)
{
System.out.println("HAPPY NO.");
break;
}
else
{
n=s;
}
}
}
public static void main()throws IOException
{
InputStreamReader read=new InputStreamReader(System.in);
BufferedReader in=new BufferedReader(read);
double a;
System.out.println("ENTER A NO.");
a=Double.parseDouble(in.readLine());
happy_no obj=new happy_no();
obj.happy(a);
}

How to find out all palindromic numbers

A palindromic number or numeral palindrome is a "symmetrical" number like 16461, that remains the same when its digits are reversed.
The term palindromic is derived from palindrome, which refers to a word like rotor that remains unchanged under reversal of its letters.
The first palindromic numbers (in decimal) are:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22,
33, 44, 55, 66, 77, 88, 99, 101, 111,
121, 131, 141, 151, 161, 171, 181,
191, ...
How to find out all palindromic numbers below, say, 10000?
Revert your reasoning. Not try to find these numbers but instead create them.
You can simply take any number and mirror it (which is always even in length) and for that same number simply add 0..9 in between (for the numbers with odd length).
Generating all palindromes up to a specific limit.
public static Set<Integer> allPalindromic(int limit) {
Set<Integer> result = new HashSet<Integer>();
for (int i = 0; i <= 9 && i <= limit; i++)
result.add(i);
boolean cont = true;
for (int i = 1; cont; i++) {
StringBuffer rev = new StringBuffer("" + i).reverse();
cont = false;
for (String d : ",0,1,2,3,4,5,6,7,8,9".split(",")) {
int n = Integer.parseInt("" + i + d + rev);
if (n <= limit) {
cont = true;
result.add(n);
}
}
}
return result;
}
Testing for palindromicity
Using Strings
public static boolean isPalindromic(String s, int i, int j) {
return j - i < 1 || s.charAt(i) == s.charAt(j) && isPalindromic(s,i+1,j-1);
}
public static boolean isPalindromic(int i) {
String s = "" + i;
return isPalindromic(s, 0, s.length() - 1);
}
Using integers
public static boolean isPalindromic(int i) {
int len = (int) Math.ceil(Math.log10(i+1));
for (int n = 0; n < len / 2; n++)
if ((i / (int) Math.pow(10, n)) % 10 !=
(i / (int) Math.pow(10, len - n - 1)) % 10)
return false;
return true;
}
There is a brute force approach, that you loop through all the numbers and check whether they are palindrome or not. To check, reverse the number and compare. Complexity should be O(n log10(n)). [ Not that log10() matters, but for sake of completeness. ]
Other one is to, generate palindromes according to number of digits. Lets say you have to generate 5 digit palindromes, they are of the form ABCBA, so just loop through 0-9 and fill all the positions. Now, if you have generate palindromes below 10^4, then generate palindromes of 1,2,3 and 4 digits.
I wrote quick(and dirty) C++ codes to test the speed of both the algorithms (8 digit palindrome).
Brute force : Ideone. (3.4s)
Better algorithm : Ideone. (0s)
I have removed print statements, because Ideone doesn't allow this large data in output.
On my computer the times are :
Brute force:
real 0m7.150s
user 0m7.052s
Better algorithm:
real 0m0.024s
user 0m0.012s
I know that you have mentioned language as Java, but i don't know Java and these codes simply show you the difference between the algorithms, and you can write your own Java code.
PS: I have tested my code for 8 digit palindromes with brute force, can't be sure if it produces wrong for above 8 digits, though the approach used is general. Also, i would have liked to give the links to code in comments, as correct approach is already mentioned, but i don't have required privileges.
one approach is simply iterating over all numebrs, and checking each number: is it is a palyndrome or not, something like that:
public static boolean isPalindrome(Integer x) {
String s = x.toString();
int len = s.length();
for (int i = 0;i<len;i+=2) {
if (s.charAt(i) != s.charAt(len-i-1)) return false;
}
return true;
}
public static void main(String[] args) {
int N = 10000;
for (Integer x = 0;x<N;x++) {
if (isPalindrome(x)) System.out.println(x);
}
}
Brute force approach: Make a foreach loop from 1…10000 and test against the constraints. Even easier, convert the number to string, reverse it and compare it to the original value. This is inefficient and lame.
Better approach: Think about the patterns of a palindrome. Think about the different possibilities there are for palindromes, depending on the length of the number. Now provide a method that generates palindromes of the given length. (I will not do this, because it's obviously homework.)
Loops similar to the one below can be used to print palindrome numbers:
for(int i = 1; i <= 9; i++) {
for(int j = 0; j <= 9; j++) {
for(int k = 0; k <= 9; k++) {
System.out.println("" + i + j + k + j + i);
}
}
}
import Queue
import copy
def printPalindromesTillK(K):
q = Queue.Queue(K);
for i in range(0, 10):
q.put(str(i));
q.put(str(i) + str(i));
while(not q.empty()):
elem = q.get();
print elem;
for i in range(1, 10):
item = str(i) + elem + str(i);
if int(item) <= K:
q.put(item);
print printPalindromesTillK(10000);
I wrote these methods in C# which may be of some help. The main method builds a definitive list of all palindromic numbers up to the given number of digits. Its fast and commented throughout to help explain the processes I have used.
I've also included some support methods including a fast palindromic test and its worth pointing out that pow10[x] is an array of the powers of 10 to further improve speed.
lhs *= 10;
rhs /= 10;
}
palindrome = MathExt.Concat( lhs * 10, MathExt.ReverseDigits( rhs ) ); // Multiplying the lhs by 10 is equivalent to adding b == 0
result.Add( palindrome ); // Add numbers of the form aaa + 0 + aaa
lhs = a;
for ( ulong b = 1; b != 10; b++ )
{
rhs = a * 10 + b; // Adding b before we reverse guarantees that there is no trailing 0s
palindrome = MathExt.Concat( lhs, MathExt.ReverseDigits( rhs ) ); // Works except when b == 0
result.Add( palindrome ); // Add numbers of the form aaa + b + aaa
}
a++;
}
pow *= 10; // Each pass of the outer loop add an extra digit to aaa
}
return (result);
}
/// <summary>
/// Reverses the digits in a number returning it as a new number. Trailing '0's will be lost.
/// </summary>
/// <param name="n">The number to reverse.</param>
/// <param name="radix">The radix or base of the number to reverse.</param>
/// <returns>The reversed number.</returns>
static public ulong ReverseDigits( ulong n, uint radix = 10 )
{
// Reverse the number
ulong result = 0;
do
{
// Extract the least significant digit using standard modular arithmetric
result *= radix;
result += n % radix;
n /= radix;
} while ( n != 0 );
return (result);
}
/// <summary>
/// Concaternates the specified numbers 'a' and 'b' forming a new number 'ab'.
/// </summary>
/// <example>If a = 1234 and b = 5678 then Concat(a,b) = 12345678.</example>
/// <param name="a">The first number.</param>
/// <param name="b">The second number.</param>
/// <returns>The concaternated number 'ab'.</returns>
public static ulong Concat( this ulong a, ulong b )
{
// Concaternate the two numbers by shifting 'a' to the left by the number of digits in 'b' and then adding 'b'
return (a * pow10[NumberOfDigits( b )] + b);
}
/// <summary>
/// Evaluate whether the passed integer is a palindrome in base 10 or not.
/// </summary>
/// <param name="n">Integer to test.</param>
/// <returns>True - Palindrome, False - Non palindrome.</returns>
static public bool IsPalindrome( this ulong n )
{
uint divisor = NumberOfDigits( n ) - 1;
do
{
// Extract the most and least significant digits of (n)
ulong msd = n / pow10[divisor];
ulong lsd = n % 10;
// Check they match!
if ( msd != lsd )
return (false);
// Remove the msd and lsd from (n) and test the next most and least significant digits.
n -= msd * pow10[divisor]; // Remove msd
n /= 10; // Remove lsd
divisor -= 2; // Number has reduced in size by 2 digits
} while ( n != 0 );
return (true);
}

Categories

Resources