I am making a C++ program that allows you to input a number and checks if it is prime. But it says that numbers like 9, 15, and 21 are prime. Can I have some help?
It is quite confusing. Here is my function that checks if it is prime:
bool isPrime(int num) {
int w = 2;
while (w <= num) {
if (w % num == 0) {
return false;
}
else if (w < num){
w = w + 1;
}
if (w == num) {
w = 0;
return true;
}
}
}
An extra speed up to solution of Aconcagua can be obtained when you realize that all primes bigger than 3 can be written as 6n+1 or 6n+5 for natural n. Or even further, all primes bigger than 5 can be written as 30n+m, with m in {1,7,11,13,17,19,23,29}. This is what is called Wheel factorization.
This is simply understood as:
Wheel factorization of 2 (cfr. Aconcagua): If n is not divisible by 2, then n is not divisible by any multiple of 2
Wheel factorization of 6=2x3: If n is not divisible by 2, then n is not divisible by any multiple of 2 and if n is not divisible by 3, then n is not divisible by any multiple of 3.
Wheel factorization of 30=2x3x5: See above
So implementing the Wheel factorization of 6, quickly gives:
if (num == 1) return false;
if (num < 4) return true;
if (num % 2 == 0) return false;
if (num % 3 == 0) return false;
int w = 5;
while (w*w <= num)
{
if(num % (w-2) == 0) return false;
if(num % w == 0) return false;
w += 6;
}
return true;
This algorithm should run at 2/3rd the speed to the solution of Aconcagua.
remark: the wheel factorization of 30 would only give a minor speedup as it only eliminates the sequence 30n+25 which is also covered by the wheel factorization of 6 as 6*(5*n + 4)+1.
remark: this still tests numbers which should not be tested, example (w=25 while we already know that w-2=5 is tested, ditto for 35,49,...)
If you want to go a bit more robust and use a bit of memory, you might be interested in the Sieve of Eratosthenes.
Other useful information can be found here : primes
With the actual bug already spotted (w % num instead of num % w), just some additional hints:
Your code is far too complex!
while (w <= num) // why <=? w == num is irrelevant, in worst
// case, it will lead to false negatives (num % num == 0)!
{
if (num % w == 0) // (already fixed!)
{
return false;
}
else if (w < num)
{
w = w + 1;
}
if (w == num) // as you increment by 1, this will always be false unless
// previous test failed - so simply use else instead
{
w = 0;
return true;
}
}
First step:
while (w < num)
{
if (w % num == 0)
{
return false;
}
/*else*/ if (w < num) // however, this check is repeated in the while
// loop anyway; no need to do the work twice
{
++w; // shorter...
}
else
{
// w = 0; // obsolete, we will be destroyed afterwards anyway...
return true;
}
}
Second step:
while (w < num)
{
if (w % num == 0)
{
return false;
}
++w; // at some point, will reach w == num and the loop won't be re-entered
}
// we did not leave the loop prematurely (-> non-prime), so we are prime:
return true;
Optimisations:
If num == n * m and n is greater than sqrt(num), then m is smaller! So n will already be caught when m is checked, so you don't have to check values greater than the square root. This will exclude a huge range of numbers already.
If n does not devide num, then k * m won't either. For multiples of 2 it is just too simple not to profit from (whereas while still rather easy, it gets more complex considering multiples of 3, 5, ...).
Applying these:
if(num % 2 == 0)
return false;
int w = 3;
while (w*w <= num) // be aware that I had an error here in my comment
// to the question - cannot fix it any more, though...
{
if(num % w == 0)
return false;
w += 2;
}
return true;
I believe you want
if(num % w == 0)
not
if(w % num == 0)
here this code might help`bool isPrime(int num)
int w = 2;
while (w <= num) {
if (num % w == 0) {
return false;
}
else if (w < num){
w = w + 1;
}
if (w == num) {
w = 0;
return true;
}
}
`
Related
My original function to determine if a number was prime was:
bool is_prime(int x) {
for (int y = 2; y < x; ++y) {
if (x % y == 0) {
return false;
}
}
return true;
}
This ran with a complexity of O(x) as you may have had to go to x.
I've learned of some optimizations and need a check on my big-o. Here is the improved program:
bool is_prime(int x)
{
if (x % 2 == 0 && x > 2) {
return false;
}
for (int y = 3; y*y <= x; y += 2) {
if (x % y == 0) {
return false;
}
}
return true;
}
Does the fact that I am now going up to the sqrt() change this to O(sqrt(x))?
Yes, but here are no ns. The complexity of your new function is O(sqrt(x)). When you say O(N) and don't specify what N is, it's generally taken to be the size of the input. This is confusing for functions that take a single number argument, so in those cases you should be explicit.
Absolutely,
The complexity of your new function is
O(sqrt(x))
But still, there is some room for optimization. Have a look at the code mentioned below:
bool isPrime(int n)
{
// Boundary cases
if (n <= 1) return false;
if (n <= 3) return true;
// This is checked so that we can skip
// middle five numbers in below loop
if (n%2 == 0 || n%3 == 0) return false;
for (int i=5; i*i<=n; i=i+6)
if (n%i == 0 || n%(i+2) == 0)
return false;
return true;
}
Write a recursive C ++ function that returns the smallest even digit of a natural number transmitted as a parameter.
If the number does not contain any even digit, it will return -1.
Easy to do without recursion:
int cifminpar(int x)
{
int mi = 9;
while(x)
{
if(x % 10 % 2 == 0)
mi = min(mi , x%10 );
x /= 10;
}
if(mi == 9)
return -1;
else return mi;
}
How do I do that with recursion ?
What about something like the following?
int cifminpar(const int x)
{
if(!x)
return 11;
//recursive call
int minrest=cifminpar(x/10); //min even in the rest of the digits
if(x % 10 % 2 == 0)
return min(minrest , x%10 );
return minrest;
}
It returns 11 if no even digits are found and work as follows and assumes that the initial number is not 0.
You can easily fix modify it to return -1 on failure and for 0 as input.
Remember: The smallest even digit is either "the first one" or "the smallest one in the number without the first one".
You can recursively compare "current digit" and "the smallest digit after it":
int cifminpar(int x)
{
int ret = cifminpar_recur(x, 10);
if (ret == 10)
return -1;
return ret;
}
int cifminpar_recur(int x, int mi)
{
if (x == 0)
return mi;
if (x % 2 == 1)
mi = min(mi, x % 10);
return cifminpar_recur(x / 10, mi);
}
And we can even drop the extra variable.
int cifminpar(int x)
{
int ret = cifminpar_recur_optimised(x);
if (ret == 10)
return -1;
return ret;
}
int cifminpar_recur_optimised(int x)
{
if (x == 0)
return 10;
if (x % 2 == 1)
return min(x % 10, cifminpar_recur_optimised(x / 10));
return cifminpar_recur_optimised(x / 10);
}
I am using a simple backtracking algorithm to find all the paths but it does not give the right answer. I am not able to figure out the mistake. We can move up, down, left and right from a given position.
Int path(int a[][200],int n,int m,int r,int c)
{
if(n == r - 1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = path(a,n+1,m,r,c);
int y = path(a,n,m+1,r,c);
int u = path(a,n-1,m,r,c);
int v = path(a,n,m-1,r,c);
vis[n][m] = 0;
return (x+y+u+v);
}
}
To find the paths or count the paths are not exactly the same thing. I will assume you want to just count the paths (because the title of your question), and that you can only move right or move down.
For this you don't really need a matrix (representing the grid) as a parameter. The following is a simple (although not efficient) recursive solution that also will work for a n*m grid:
int countPaths(int m, int n) {
if (m == 0 || n == 0)
return 1;
return countPaths(m-1, n) + countPaths(m, n-1);
}
The mathematical solution for the general n*n grid is:
(2n choose n) = (2*n)!/(n!*n!)
Then, comparing results with the formula:
countPaths(1, 1) == 2 // (2*1)!/(1!*1!)=2
countPaths(2, 2) == 6 // (2*2)!/(2!*2!)=6
countPaths(3, 3) == 20 // (2*3)!/(3!*3!)=20
Your backtracking approach will give the same results, but with some considerations. For example, consider when n=2, you will need a 3x3 matrix (and in general a (n+1)x(n+1) matrix) to represent/explore (and mark with 1) all the paths for the 2x2 grid:
int countPaths(int a[][3],int n, int m, int r, int c) {
if(n == r-1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = countPaths(a,n+1,m,r,c);
int y = countPaths(a,n,m+1,r,c);
vis[n][m] = 0;
return (x+y);
}
}
Then:
countPaths(vis, 0, 0, 3, 3) == 6 // (2*2)!/(2!*2!)=6
I am looking forward to improve my algorithm to find the next primenumber to the right to a given number.
What I have so far is this:
int NextPrime(int a)
{
int i, j, count, num;
for (i = a + 1; 1; i++)
{
for (j = 2, count = 0; j <= i; j++)
{
if (i%j == 0)
{
count++;
}
}
if (count == 1)
{
return i;
break;
}
}
}
Tho this algorithm is not that efficent when running often.
Can someone give advices on how the algorithm could be speed up or improved.
Sieve of Eratosthenes is not the best solution when only one prime number should be found. Here is the solution which is useful for that purpose. It is based on the idea that all prime numbers are in form of 6k+-1, so I'm only testing 2, 3 and numbers in form 6+-1. Of course, the loop quits when divisor breaches sqrt(a) because all such numbers have already been tested.
bool IsPrime(int number)
{
if (number == 2 || number == 3)
return true;
if (number % 2 == 0 || number % 3 == 0)
return false;
int divisor = 6;
while (divisor * divisor - 2 * divisor + 1 <= number)
{
if (number % (divisor - 1) == 0)
return false;
if (number % (divisor + 1) == 0)
return false;
divisor += 6;
}
return true;
}
int NextPrime(int a)
{
while (!IsPrime(++a))
{ }
return a;
}
Net result is that this loop works very fast on a couple of large numbers I've tried.
You can improve upon the sieve of Eratosthenes by a lot if you only check each number against each prime before it up until the square root of the prime number. For this you need to keep a list of all primes up to then. This increases memory cost but increases execution speed by a long shot.
Pseudocode:
List foundPrimes;
foundPrimes.add(1)
foundPrimes.add(2)
bool isPrime(int x) {
for (int divisor in foundPrimes) {
if (divisor*divisor > x) {
foundPrimes.add(x);
return true;
} else if (x % divisor==0) {
return false;
}
}
// Invalid, need to run the algo from 3 on to fill the list
}
int nextPrime(int x) {
while (!isPrime(++x)) {}
return x;
}
I've been trying to implement the algorithm from wikipedia and while it's never outputting composite numbers as primes, it's outputting like 75% of primes as composites.
Up to 1000 it gives me this output for primes:
3, 5, 7, 11, 13, 17, 41, 97, 193, 257, 641, 769
As far as I know, my implementation is EXACTLY the same as the pseudo-code algorithm. I've debugged it line by line and it produced all of the expected variable values (I was following along with my calculator). Here's my function:
bool primeTest(int n)
{
int s = 0;
int d = n - 1;
while (d % 2 == 0)
{
d /= 2;
s++;
}
// this is the LOOP from the pseudo-algorithm
for (int i = 0; i < 10; i++)
{
int range = n - 4;
int a = rand() % range + 2;
//int a = rand() % (n/2 - 2) + 2;
bool skip = false;
long x = long(pow(a, d)) % n;
if (x == 1 || x == n - 1)
continue;
for (int r = 1; r < s; r++)
{
x = long(pow(x, 2)) % n;
if (x == 1)
{
// is not prime
return false;
}
else if (x == n - 1)
{
skip = true;
break;
}
}
if (!skip)
{
// is not prime
return false;
}
}
// is prime
return true;
}
Any help would be appreciated D:
EDIT: Here's the entire program, edited as you guys suggested - and now the output is even more broken:
bool primeTest(int n);
int main()
{
int count = 1; // number of found primes, 2 being the first of course
int maxCount = 10001;
long n = 3;
long maxN = 1000;
long prime = 0;
while (count < maxCount && n <= maxN)
{
if (primeTest(n))
{
prime = n;
cout << prime << endl;
count++;
}
n += 2;
}
//cout << prime;
return 0;
}
bool primeTest(int n)
{
int s = 0;
int d = n - 1;
while (d % 2 == 0)
{
d /= 2;
s++;
}
for (int i = 0; i < 10; i++)
{
int range = n - 4;
int a = rand() % range + 2;
//int a = rand() % (n/2 - 2) + 2;
bool skip = false;
//long x = long(pow(a, d)) % n;
long x = a;
for (int z = 1; z < d; z++)
{
x *= x;
}
x = x % n;
if (x == 1 || x == n - 1)
continue;
for (int r = 1; r < s; r++)
{
//x = long(pow(x, 2)) % n;
x = (x * x) % n;
if (x == 1)
{
return false;
}
else if (x == n - 1)
{
skip = true;
break;
}
}
if (!skip)
{
return false;
}
}
return true;
}
Now the output of primes, from 3 to 1000 (as before), is:
3, 5, 17, 257
I see now that x gets too big and it just turns into a garbage value, but I wasn't seeing that until I removed the "% n" part.
The likely source of error is the two calls to the pow function. The intermediate results will be huge (especially for the first call) and will probably overflow, causing the error. You should look at the modular exponentiation topic at Wikipedia.
Source of problem is probably here:
x = long(pow(x, 2)) % n;
pow from C standard library works on floating point numbers, so using it is a very bad idea if you just want to compute powers modulo n. Solution is really simple, just square the number by hand:
x = (x * x) % n