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;
}
Related
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;
}
}
`
I am trying to create a maze generator using recursive backtracking and have come across a problem that I just can't get my head around. For some reason my move function is returning the value "18446744073709551615". This is (of course) leading to a segmentation fault. Why is my move function returning such a large value when my move function can only increase or decrease the value by 2?
bool maze::generate(size_t x, size_t y) {
//mark the position as visited
labyrinth.s[y][x] = true;
//print to see progress
//this->print();
//if the position is not out of bounds
if (x < 0 || x > labyrinth.MAXWIDTH - 1 || y < 0 || y > labyrinth.MAXHIGHT - 1) {
//if the position is the endpoint return true
if (labyrinth.v[y][x - 1] == 'W' || labyrinth.v[y][x + 1] == 'W' || labyrinth.v[y - 1][x] == 'W' || labyrinth.v[y + 1][x] == 'W') {
return true;
}
}
//pick a random direction
do {
d = size_t(rand() % 4);
} while(!this->pos_test(x, y, d));
std::cout << x << ' ' << y << std::endl;
if (d == UP) {
y = move(x, y, UP);
}
else if (d == DOWN) {
y = move(x, y, DOWN);
}
else if (d == RIGHT) {
x = move(x, y, RIGHT);
}
else if (d == LEFT) {
x = move(x, y, LEFT);
}
else{
}
std::cout << x << ' ' << y << std::endl;
//recursively generate the maze
if (this->generate(x, y)) {
return true;
}
}
void maze::initialize(size_t x, size_t y) {
//set the maxhight and the maxwidth to y and x
labyrinth.MAXHIGHT = y;
labyrinth.MAXWIDTH = x;
//set all elements in the vector to #
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<char> temp;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp.push_back(labyrinth.wall);
}
labyrinth.v.push_back(temp);
}
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
if (j % 2 == 1 && i % 2 == 1 && j != labyrinth.MAXWIDTH - 1 && j != 0 && i != labyrinth.MAXHIGHT - 1 && i != 0) {
labyrinth.v[j][i] = labyrinth.path;
}
}
}
//set all posistions to unvisited
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<bool> temp2;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp2.push_back(false);
}
labyrinth.s.push_back(temp2);
}
//setup the start point
labyrinth.v[0][1] = 'S';
//setup the endpoint
labyrinth.v[labyrinth.MAXHIGHT - 2][labyrinth.MAXWIDTH - 1] = 'W';
}
//if a position has been visited or if not possible to go to return true
bool maze::pos_test(size_t x, size_t y, size_t d) const {
//if the position is out of bounds return false
if (x < 0 || y < 0 || x > labyrinth.MAXWIDTH - 1 || y > labyrinth.MAXHIGHT - 1) {
return true;
}
else if (x == 1 && d == LEFT) {
return true;
}
else if (y == 1 && d == UP) {
return true;
}
else if (x == labyrinth.MAXWIDTH - 1 && d == RIGHT) {
return true;
}
else if (y == labyrinth.MAXHIGHT - 1 && d == DOWN) {
return true;
}
else if (d == UP) {
return labyrinth.s[y - 2][x];
}
else if (d == DOWN) {
return labyrinth.s[y + 2][x];
}
else if (d == RIGHT) {
return labyrinth.s[y][x + 2];
}
else if (d == LEFT) {
return labyrinth.s[y][x - 2];
}
else {
return true;
}
}
size_t maze::move(size_t x, size_t y, size_t d) {
//if the position is out of bounds return without modifying
if (x < 0 || x > labyrinth.MAXWIDTH - 1) {
return x;
}
else if (y < 0 || y > labyrinth.MAXHIGHT - 1) {
return y;
}
else if (d == UP) {
labyrinth.v[y - 1][x] = labyrinth.path;
return y = y - 2;
}
else if (d == DOWN) {
labyrinth.v[y + 1][x] = labyrinth.path;
return y = y + 2;
}
else if (d == RIGHT) {
labyrinth.v[y][x + 1] = labyrinth.path;
return x = x + 2;
}
else if (d == LEFT) {
labyrinth.v[y][x - 1] = labyrinth.path;
return x = x - 2;
}
else {
}
}
You are underflowing your unsigned 64-bit return type size_t.
You are checking whether x and y are below zero, but that's not enough, because 0 and 1 will still be too low because you are subtracting 2!
The number you get is 0xFFFFFFFFFFFFFFFF in hexadecimal. This is the highest possible value for an unsigned 64-bit integer.
It comes from calculating 1 - 2. Yes, this is supposed to be -1, but because your move function doesn't return a signed number but an unsigned one (check the docs on size_t), it can't be negative! Instead, it wraps around to the highest possible number.
You can imagine this in the same way you would get ...99999999999 when you try to calculate 1 - 2 on paper ignoring the "you can't subtract a higher number from a smaller one on paper" rule.
As a side note: I guess the negative result is undesired anyway, because actually your huge number, once added to a pointer, will in turn overflow back into positive, so basically it will work the same is a real -1 in your case and the segmentation fault comes from accessing something right before the beginning of your buffer, not far beyond it, but it comes down to the same thing.
Apart from that, there is no need to do return y = y - 2 and such. Just return y - 2.
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;
}
Is there any predefined function in c++ to check whether the number is square of any number and same for the cube..
No, but it's easy to write one:
bool is_perfect_square(int n) {
if (n < 0)
return false;
int root(round(sqrt(n)));
return n == root * root;
}
bool is_perfect_cube(int n) {
int root(round(cbrt(n)));
return n == root * root * root;
}
sqrt(x), or in general, pow(x, 1./2) or pow(x, 1./3)
For example:
int n = 9;
int a = (int) sqrt((double) n);
if(a * a == n || (a+1) * (a+1) == n) // in case of an off-by-one float error
cout << "It's a square!\n";
Edit: or in general:
bool is_nth_power(int a, int n) {
if(n <= 0)
return false;
if(a < 0 && n % 2 == 0)
return false;
a = abs(a);
int b = pow(a, 1. / n);
return pow((double) b, n) == a || pow((double) (b+1), n) == a;
}
No, there are no standard c or c++ functions to check whether an integer is a perfect square or a perfect cube.
If you want it to be fast and avoid using the float/double routines mentioned in most of the answers, then code a binary search using only integers. If you can find an n with n^2 < m < (n+1)^2, then m is not a perfect square. If m is a perfect square, then you'll find an n with n^2=m. The problem is discussed here
Try this:
#include<math.h>
int isperfect(long n)
{
double xp=sqrt((double)n);
if(n==(xp*xp))
return 1;
else
return 0;
}
The most efficient answer could be this
int x=sqrt(num)
if(sqrt(num)>x){
Then its not a square root}
else{it is a perfect square}
This method works because of the fact that x is an int and it will drop down the decimal part to store only the integer part. If a number is perfect square of an integer, its square root will be an integer and hence x and sqrt(x) will be equal.
For identifying squares i tried this algorithm in java. With little syntax difference you can do it in c++ too.
The logic is, the difference between every two consecutive perfect squares goes on increasing by 2. Diff(1,4)=3 , Diff(4,9)=5 , Diff(9,16)= 7 , Diff(16,25)= 9..... goes on.
We can use this phenomenon to identify the perfect squares.
Java code is,
boolean isSquare(int num){
int initdiff = 3;
int squarenum = 1;
boolean flag = false;
boolean square = false;
while(flag != true){
if(squarenum == num){
flag = true;
square = true;
}else{
square = false;
}
if(squarenum > num){
flag = true;
}
squarenum = squarenum + initdiff;
initdiff = initdiff + 2;
}
return square;
}
To make the identification of squares faster we can use another phenomenon, the recursive sum of digits of perfect squares is always 1,4,7 or 9.
So a much faster code can be...
int recursiveSum(int num){
int sum = 0;
while(num != 0){
sum = sum + num%10;
num = num/10;
}
if(sum/10 != 0){
return recursiveSum(sum);
}
else{
return sum;
}
}
boolean isSquare(int num){
int initdiff = 3;
int squarenum = 1;
boolean flag = false;
boolean square = false;
while(flag != true){
if(squarenum == num){
flag = true;
square = true;
}else{
square = false;
}
if(squarenum > num){
flag = true;
}
squarenum = squarenum + initdiff;
initdiff = initdiff + 2;
}
return square;
}
boolean isCompleteSquare(int a){
// System.out.println(recursiveSum(a));
if(recursiveSum(a)==1 || recursiveSum(a)==4 || recursiveSum(a)==7 || recursiveSum(a)==9){
if(isSquare(a)){
return true;
}else{
return false;
}
}else{
return false;
}
}
For perfect square you can also do:
if(sqrt(n)==floor(sqrt(n)))
return true;
else
return false;
For perfect cube you can:
if(cbrt(n)==floor(cbrt(n)))
return true;
else
return false;
Hope this helps.
We could use the builtin truc function -
#include <math.h>
// For perfect square
bool is_perfect_sq(double n) {
double r = sqrt(n);
return !(r - trunc(r));
}
// For perfect cube
bool is_perfect_cube(double n) {
double r = cbrt(n);
return !(r - trunc(r));
}
bool isSquare(int n) {
return floor(sqrt(n)) == ceil(sqrt(n));
}
bool isQube(int n) {
return floor(cbrt(n)) == ceil(cbrt(n));
}