I'm doing Project Euler #7, where you calculate the 10,001st prime. I've written a simple function to check if an integer is a prime number:
bool isPrime(int p)
{
if (p % 2 == 0 || p <= 1)
{
return false;
}
for (int i=3; i<=(int)sqrt((double)p)+1; i+=2)
{
if (p % i == 0)
{
return false;
}
}
return true;
}
Then in the main program I start at 2 and iterate through all subsequent odd numbers, counting each prime:
int count(1);
int i(1);
while (count != 10001)
{
i += 2;
if (isPrime(i))
{
count++;
}
}
std::cout << "Answer: " << i << std::endl;
I then thought that I could improve on this function by keeping track of all the primes found so far, and feeding them into my isPrime function, like so:
bool isPrime(int p, std::vector<int> primes)
{
if (p <= 1)
{
return false;
}
for (std::vector<int>::iterator it=primes.begin(); it!=primes.end(); it++)
{
if (p % *it == 0)
{
return false;
}
else if (*it > (int)sqrt((double)p)+1)
{
return true;
}
}
return true;
}
And the main program is changed to:
int count(1);
int i(1);
std::vector<int> primes(1,2);
while (count != 10001)
{
i += 2;
if (isPrime(i, primes))
{
count++;
primes.push_back(i);
}
}
std::cout << "Answer: " << primes.back() << std::endl;
The first version of my code gets the answer in less than a second, whereas the second takes over a minute. I don't understand why this is, surely the second version should be faster as isPrime is iterating over a smaller range of numbers? If anyone can offer any advice, thanks.
You should change the signature of isPrime() to
bool isPrime(int p, const std::vector<int>& primes)
to avoid copying primes every time you call the function.
Related
The task was: Write a program that receives a number from the input and finds the first two prime numbers after it in c++.
I tried
#include <iostream>
// Check, if a number is prime and return true, if it is
bool isPrime(int value) {
bool isPrime = true;
// Try all potential values
for (int i = 2; i <= value / 2; ++i) {
if (value % i == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
int main() {
// Read start value, check, if in OK range
if (int number{}; (std::cin >> number) and (number > 3))
{
int primeCounter = 0;
// Check for the next 2 prime values
while (primeCounter < 2) {
if (isPrime(number)) {
// Prime found
std::cout << number << '\n';
++primeCounter;
}
// Try next number
++number;
}
}
else
{
std::cout << "The input value is not ok\n";
}
}
But the answer was judged as wrong. What could be the reason?
Thank you for your kindness and help!
There are only some minor issues with the code:
The prime check function was not optimized. It worked, but now it is a little bit faster. But does not matter taht much.
The input range check was wrong and, because you wanted to have the primes after the input value. So one increment is necessary.
The corrected code looks like this:
#include <iostream>
// Check, if a number is prime and return true, if it is
bool isPrime(int value) {
// Special cases
if (value < 2) return false;
if (value == 2) return true;
if (value % 2 == 0) return false;
// Brute force
bool isPrime = true;
// Try all potential values
for (int i = 3; i*i < value / 2; i+=2) {
if (value % i == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
int main() {
// Read start value, check, if in OK range
if (int number{}; (std::cin >> number) and (number > 0))
{
// need the next folowing 2 prime numbers
++number;
int primeCounter = 0;
// Check for the next 2 prime values
while (primeCounter < 2) {
if (isPrime(number)) {
// Prime found
std::cout << number << '\n';
++primeCounter;
}
// Try next number
++number;
}
}
else
{
std::cout << "The input value is not ok\n";
}
}
C++ Program help
Hello, I am writing a c++ program to print out several fibonacci numbers that are prime. The program prints out 8 numbers but not only those that are prime. Can some please help me find out what is going on
#include <iostream>
#include <cmath>
using namespace std;
//fibonacci function
int fibonacci(int x) {
if ((x == 1) || (x == 2)) { return 1; }
return fib(x - 1) + fib(x - 2);
}
//prime test bool function
bool is_prime(double n) {
for (int i = 2; i <= sqrt(n); i++) {
if (n % i != 0) { return true; }
else { return false; }
}
}
// main function
int main (){
int y = 1;
int c = 0;
while (y >= 0) {
fibonacci(y);
if ((is_prime(true)) && (fibonacci(y) != 1)) {
cout << fib(y) << " ";
count++;
if (c >= 8) { return 0; }
}
y++;
}
}
return 0;
}
Your code above uses double names for the function, and also you use c while you may mean count.
The is_prime function logic should take an int and the function logic is better to be rewritten to look for values that show if the number is not prime.
Lastly, using recursion with Fibonacci function is resource exhaustive. it is better to use plain loops.
check this code against yours:
#include <iostream>
#include <cmath>
using namespace std;
int fib(int x)
{
int first = 0, second = 1, sum = 0;
if ((x == 1) || (x == 2)) { return 1; }
for (int i = 2; i <= x; ++i)
{
sum = first + second;
first = second;
second = sum;
}
return sum;
}
bool is_prime(int n) // n should be int not double
{
for (int i = 2; i <= sqrt(n); i++)
if (n % i == 0)
return false; // you should look for what breaks the condition
return true; // if nothing break the condition you return true
}
int main ()
{
for (int i = 1; i <= 8; ++i)
{
int f = fib(i);
if (is_prime(f))
cout << f << " ";
}
}
Your is_prime() function has a logical problem and appears to be returning the opposite evaluation for input numbers. Try the following:
bool is_prime(int n) {
for (int i=2; i <= sqrt(n); i++) {
// if input divisible by something other than 1 and itself
// then it is NOT prime
if (n % i == 0) {
return false;
}
}
// otherwise it is prime
return true;
}
Here is a demo showing that the refactored is_prime() function is working correctly:
Rextester
Then you can use this function along with your Fibonacci number generator to find say the first 8 prime Fibonacci numbers:
int c = 0;
int y = 1;
do {
int fib = fibonacci(y);
++y;
if (is_prime(fib)) {
cout << fib << " ";
++c;
}
} while (c < 8);
As a side note, your fibonacci() function uses recursion and it won't scale well for large number inputs. Consider using dynamic programming there to dramatically improve performance.
Use Tim Biegeleisen answer for the issues in is_prime() function.
But additionally you do not check your Fibonacci number at all, is_prime is always being called with the same value is_prime(true). And apart of that, in current implementation while cycle will never finish. Try to consider following for the while loop:
while (y >= 0) {
double fib = fibonacci(y);
if ( is_prime(fib) && (fib != 1) ) {
cout << fib << " ";
c++;
if (c >= 8) { return 0; }
}
y++;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to solve an exercise written in the Stroustrup's book about calculating and printing if a number between 1 and 100 is a prime number or not.
My code seems to work perfectly but, when it prints values on the screen, it starts from 6 and not from 2.
I have tried to figure out why but I am not able to understand the reason of that.
Can you lend me an hand?
Thank you very much!
// Prime Numbers.cpp : definisce il punto di ingresso dell'applicazione console.
//
#include "stdafx.h"
#include "std_lib_facilities.h"
vector<int> primes = { 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 };
int primecheck(int x) {
for (int i : primes) {
if (x <= primes[i])
break;
if (primes[i] == x)
return 1;
while (x % primes[i] != 0) {
--i;
if (i < 0) {
return 1;
break;
}
else {
if (x % primes[i] == 0)
return 2;
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
for (int i = 1; i <= 100; ++i) {
if (primecheck(i) == 1) {
cout << i << " is a Prime Number." << endl;
}
else {
if (primecheck(i) == 2) {
cout << i << " is not a Prime Number." << endl;
}
}
}
keep_window_open();
return 0;
}
for (int i : primes) is different than for(int i = 0;i < terminating condition; ++i).
You can think of for(int i : primes) as "For every int i in the container primes, do something.", and for(int i = 0; i < terminating condition; ++i) as "for every int i up to terminating condition, do something"
Try this for your loop:
for (int i : primes) {
if (x <= i)
break;
if (i == x)
return 1;
while (x % i != 0) {
--i;
if (i < 0) {
return 1;
break;
}
else {
if (x % i == 0)
return 2;
}
}
}
Your code is very wrong and you should rewrite it.
Not all paths have return statement and you must use i instead of prime[i]
There's simple working code:
int primecheck(int x) {
for (int prime : primes) {
if (x < prime) {
return 2;
}else if (x == prime) {
return 1;
}
return 2;
}
int primecheck(int x) {
int flag=1;
for (int i =2;i<x;i++)
{
if(x%i)
flag=2;
}
return flag;
}
Please change your function and avoid the array
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.
I am currently trying to solve one of project euler's problems, to find the 10001st prime number. Though my code is not returning the right number, and even returned a even number when I changed the starting value of 'count'. Below is my code, if anyone could help me out with this it would be appreciated.
#include <math.h>
#include <iostream>
#include <stdbool.h>
using namespace std;
bool isPrime(int num);
int main()
{
int num = 0, count = 0;
while(count < 10001)
{
num++;
while(isPrime(num) != true)
{
num++;
cout << "\n num: " << num;
}
count++;
isPrime(12);
}
cout << "the 10001's prime number is: " << num << "\n " << count;
system("pause");
return 0;
}
bool isPrime(int num)
{
bool checkPrime = false;
if(num%2 != 0)
{
for(int i = 3; i <= sqrt(num); i++)
{
if(num%i != 0)
{
checkPrime = true;
}
else
{
checkPrime = false;
break;
}
}
}
else
{
return false;
}
if(checkPrime)
{
return true;
}
else
{
return false;
}
}
Your logic in isPrime is wrong. isPrime(3) returns false for instance. The basic problem is that you initialize checkPrime to false instead of true, so that any small number which doesn't enter your for loop returns false even if it's a prime.
Here's a (hopefully) correct version, also with some of the changes Dukeling suggested.
bool isPrime(int num)
{
if (num < 2) // numbers less than 2 are a special case
return false;
bool checkPrime = true; // change here
int limit = sqrt(num);
for (int i = 2; i <= limit; i++)
{
if (num%i == 0)
{
checkPrime = false;
break;
}
}
return checkPrime;
}