Prime testing algorithm not working properly - c++

I have a prime testing algorithm, which I got from Project Euler, but it returns false when 43 is passed as input. The pseudo code was given in the overview, which I converted into c++ code. I may have made a mistake in converting the pseudo code. What is the actual problem with the algorithm?
#include <iostream>
#include <cmath>
using namespace std;
bool is_prime(int n)
{
if(n <= 1)
{
return false;
}
else if(n < 4)
{
return true;
}
else if(n % 2 == 0)
{
return false;
}
else if(n < 9)
{
return true;
}
else if(n % 3 == 0)
{
return false;
}
else
{
int r = sqrt(n);
int f = 5;
while(f <= r)
{
if(n % f == 0)
{
return false;
}
if((n + 2) % f == 0)
{
return false;
}
f = f + 6;
}
return true;
}
}
int main()
{
cout << is_prime(43);
system("PAUSE");
return 0;
}

Your algorithm is right but here is following mistake
if((n + 2) % f == 0) //wrong
{
return false;
}
should be
if(n%(f+2) == 0) //Right
{
return false;
}

You have an algorithm error. Instead of
(n+2)%f
it should read
n%(f+2)

Others have pointed out your error. You can simplify your code somewhat, reducing all those if statements:
bool is_prime(int n)
{
if(n <= 1)
{
return false;
}
if(n % 2 == 0)
{
return n == 2;
}
if(n % 3 == 0)
{
return n == 3;
}
// Check for factors of 5, 7, ...

Related

How to print the middle asterisk shown from the prime factorization output by setting an end condition?

The following code inputs an integer (n) from the user and outputs the prime decomposition of n. I'm trying to set an "end" condition for the output of this part of the code but I can't:
if(countA == 1)
cout<<2;
else if(countA != 0)
cout<<2<<"^"<<countA;
An example for the correct output is:
Input: 100
Output: 2^2*5^2
But what it's printing now is without the middle asterisk (between 2 and 5):
2^25^2
The entire code:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n, countA = 0, countB = 0;
cin>>n;
while(n % 2 == 0)
{
n /= 2;
countA++;
}
if(countA == 1)
cout<<2;
else if(countA != 0)
cout<<2<<"^"<<countA;
for(int i = 3, end = sqrt(n); i <= end; i = i + 2)
{
while(n % i == 0)
{
n /= i;
countB++;
}
if(countB == 1)
cout<<i<<"*";
else if(countB != 0)
{
cout<<i<<"^"<< countB;
if(!(i + 1 >= end))
cout<<"*";
}
}
if(n > 2)
cout<<n;
return 0;
}
#include <iostream>
#include <cmath>
using namespace std;
const char *pad = "";
int main()
{
int n, countA = 0, countB = 0;
cin>>n;
while(n % 2 == 0)
{
n /= 2;
countA++;
}
if(countA > 0)
{
cout<<pad;
cout<<2;
if(countA > 1)
{
cout<<"^"<<countA;
}
pad = "*";
}
for(int i = 3; i <= sqrt(n); i = i + 2)
{
countB = 0;
while(n % i == 0)
{
n /= i;
countB++;
}
if(countB > 0)
{
cout<<pad;
cout<<i;
if(countB > 1)
{
cout<<"^"<<countB;
}
pad = "*";
}
}
if(n > 2)
{
cout<<pad;
cout<<n;
pad = "*";
}
return 0;
}

Looking Bitwise solution for this

You’re given a read only array of n integers. Find out if any integer occurs more than n/3 times in the array in linear time and constant additional space.
If so, return the integer. If not, return -1.
If there are multiple solutions, return any one.
Example :
Input : [1 2 3 1 1]
Output : 1
1 occurs 3 times which is more than 5/3 times.
I've solved this problem and found some solutions for this on google. But I want a bitwise approach. If you could help me, I'd appreciate it.
Solution without bitwise:
int Solution::repeatedNumber(const vector<int> &A)
{
int len = A.size();
if (A.size() == 0)
{
return -1;
}
if (A.size() == 1)
{
return A[0];
}
int c1 = A[0];
int c2 = A[1];
int c1count = 0;
int c2count = 0;
for(int num: A)
{
if(c1 == num)
{
c1count++;
}
else if(c2 == num)
{
c2count++;
}
else if(c1count == 0)
{
c1 = num;
c1count = 1;
}
else if(c2count == 0)
{
c2 = num;
c2count = 1;
}
else
{
c1count--;
c2count--;
}
}
c1count = 0;
c2count = 0;
for(int num : A)
{
if(c1 == num)
{
c1count++;
}
else if(num == c2)
{
c2count++;
}
}
if(c1count > len/3)
{
return c1;
}
else if(c2count > len/3)
{
return c2;
}
else
{
return -1;
}
}

How to check if number has a repeating digit using recursion?

I need to know if a number has a repeating digit using recursion and return 'yes' or 'no'. I am not allowed to use loops or arrays. This is what I've done untill now with 10 global variables and it works, but I think there is a better way.
#include <iostream>
using namespace std;
int counter0 = 0;
int counter1 = 0;
int counter2 = 0;
int counter3 = 0;
int counter4 = 0;
int counter5 = 0;
int counter6 = 0;
int counter7 = 0;
int counter8 = 0;
int counter9 = 0;
bool check(int k) {
int p = k % 10;;
if (k < 10) {
return false;
} else {
if (p == 0) {
counter0++;
} else if (p == 1) {
counter1++;
} else if (p == 2) {
counter2++;
} else if (p == 3) {
counter3++;
} else if (p == 4) {
counter4++;
} else if (p == 5) {
counter5++;
} else if (p == 6) {
counter6++;
} else if (p == 7) {
counter7++;
} else if (p == 8) {
counter8++;
} else if (p == 9) {
counter9++;
}
if(counter1>1 || counter2>1 || counter3>1 || counter4>1 || counter5>1 || counter6>1 || counter7>1 || counter8>1 || counter9>1)
{
return true;
}
k=k/10;
check(k);
}
}
int main() {
//cout << "Hello, World!" << std::endl;
int n;
cin >> n;
cout << (check(n) ? "yes" : "no") << endl;
//cout << n/10;
return 0;
}
#include <iostream>
using namespace std;
bool hasRepeatingDigit(int n, int mask)
{
// base case: if we have checked all the digits and didn't find any duplicates, return false
if (n == 0)
return false;
/*
p is the place of the last digit in n (n%10).
A digit can range from 0 to 9.
The place of 0 will be 1 << 0 which is 1.
The place of 1 will be 1 << 1 which is 2.
The place of 2 will be 1 << 2 which is 4.
...
...
The place of 9 will be 1 << 9 which is 512.
*/
int p = 1 << (n % 10);
// if place of p has already been marked then it's a duplicate
if (mask&p)
return true;
// otherwise scrap the last digit (n/10), mark place p and recurse on the remaining digits
return hasRepeatingDigit(n / 10, mask|p);
}
int main()
{
int n;
cin >> n;
cout << hasRepeatingDigit(n, 0) << endl;
}
Recursion problems always have a base case and an recursive case.
The base case is simple: k<11 has no repeated digits.
For the recursive case, k has repeated digits if either:
the lower two digits of k are equal, or
k/10 has repeated digits.
So:
bool check(int k) {
if (k < 11)
return false;
int digit = k % 10;
int next = k / 10;
int digit2 = next % 10;
if (digit == digit2)
return true;
else
return check(next);
// Or in one expression:
// return (digit == digit2) || check(next);
}
first, the code is incorrect...
if you enter n=11 it says 'no' but 1 repeated twice. you can fix it by changing the if statement from if(k < 10) to if(k == 0)
you can get down to the bits level but I can't see how much is useful...
in conclusion, this is the best you can do without arrays...
BUT: if you need to find if a digit repeated twice or more in a row the other answer is perfect

Check if number is perfect prime recursively c++

I've been assigned to write a program that checks if a number is perfect prime or not (the sum of its digits is prime, the sum of the sum of its digits is prime...). I've stumbled upon two extreme cases that break my program:
INPUT: 20328307 OUTPUT: true (expected false)
INPUT: 587899597 OUTPUT: true (expected false)
The code:
#include <iostream>
using namespace std;
bool is_prime(int n) {
if (n == 0 or n == 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i * i == n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
int sum_of_digits(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
bool is_perfect_prime(int n) {
if (sum_of_digits(n) >= 10) is_perfect_prime(sum_of_digits(n)); //cas recursiu
return is_prime(n); //cas base
}
int main() {
int n;
while (cin >> n) cout << (is_perfect_prime(n) ? "true" : "false") << endl;
}
I can't see where this script fails for these two values, and why it doesn't fail for smaller numbers.
First of all your for loop is incorrect, it should be instead:
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
otherwise you return true almost on every non even number. Second you ignore result of recursive call, possible solution is:
bool is_perfect_prime(int n) {
if ( n >= 10 and not is_perfect_prime(sum_of_digits(n)) )
return false;
return is_prime(n); //cas base
}
Finally I've got it to work. The problem was in the is_prime() for loop and in the recursive case of is_perfect_prime(). This is what I've come up with:
bool is_prime(int n) {
if (n == 0 or n == 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
int sum_of_digits(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
bool is_perfect_prime(int n) {
if (n < 10) return is_prime(n);
if (! is_prime(n)) return false;
return is_perfect_prime(sum_of_digits(n));
}
Thanks for your answers.

sieve of Eratosthenes C++ algorithm

I am trying to implement this algorithm and I have having a hard time working out the algorithm to work for finding the prime numbers up to 1000. I don't really understand but my code is not giving me the correct output, if you can suggest a way I should change my code I would greatly appreciate it.
#include <iostream>
using namespace std;
bool isPrime(int n);
int main() {
int i;
for(i = 1; i <= 1000; i++){
if( isPrime(i)) cout << "This number " << i << " is a prime. " << endl;
}
}
bool isPrime(int n){
if(n <= 1){
return false;
}
if(n == 2){
return true;
}
for(int i = 2; i < n; i++){
if(n % i == 0){
return false;
}else{
return true;
}
}
}
Your decision inside the for loop inside isPrime() is wrong. This is a criterion to terminate the loop:
if(n % i == 0){
but the elsepart is no reason to terminate. You have to wait until the for loop finished. Like this:
for(int i = 2; i < n; i++){
if(n % i == 0){
// Here, we are sure that n can be divided by any other numbers than 1 and n.
return false;
}
}
// Here, we are sure that n cannot be divided by any number 2 .. (n-1).
return true;
}
By the way, you only have to check until the square root of n. You can spare the rest.
There is problem in your isPrime function
bool isPrime(int n){
if(n <= 1){
return false;
}
if(n == 2){
return true;
}
for(int i = 2; i < n; i++){
if(n % i == 0){
return false;
}
else{
return true; /* this line is very dangerous. When there is odd number it is not divisible by two so the control goes to else block and you get every odd number as your prime number */
}
}
}
Instead use this
bool isPrime(int n){
if(n <= 1){
return false;
}
if(n == 2){
return true;
}
for(int i = 2; i < n; i++){
if(n % i == 0){
return false;
}
}
return true;
}
For Sieve Of Erastosthenes
try this code it may help
int b;
cout << "Enter upper limit" << endl;
cin >> b;
bool *x;
x = new bool[b];
x[2] = true;
for (int i = 2; i < b; i++)
{
int count = 2;
if (x[i])
{
cout << i << endl;
while (i*count < b)
{
x[i*count] = false;
count++;
}
}
}
The problem is in the isPrime function.
Your isPrime function says if the the first value of i (i.e 2) is not divided by n then return true. So for eg. 21, 27 etc are also counted as a prime number.
You can use a flag variable in the isPrime function and used it to determine whether the n is prime or not. Like this
boolean prime = true;
for(int counter = 2; counter <= number / 2; counter++) {
if(number % counter == 0) {
prime = false;
break;
}
}
return prime;
I don't think this is Sieve of Eratosthenes algorithm. If you want to implement this algorithm then you can read from here.