Implementing a prime number counter - c++

For some reason, my last prime(int prime) isn't showing up at the end. Any clue ?
fyi: primeEval stands for a flag, if the loop ends && primeEval==2, the number is actually a prime number. qty stands for quantity of primes counted.
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}

New Answer:
With the change in your code you will now loop through all number. The problem with it now is that once you find a non prime number you will never reset primeEval and because of that you will never capture another prime number If you change your code to the following it will work
int main()
{
long primeEval = 0, prime = 0, qtyprime = 0;
time_t timerr = (time(NULL) + 10);
for (int i = 2; time(NULL) != timerr; i++) {
for (int j = 1; j <= i; j++) {
if ((i%j) == 0){
primeEval++; // incmrent factor
}
// if we are at the end and have 2 factors then we are prime
if (i == j && primeEval == 2) {
qtyprime++;
prime = i;
primeEval = 0; // Resets for the next number 'i'
}
// if we reach the end with more than 2 factors reset and go to the next number
if (i == j && primeEval > 2) {
primeEval = 0; // Resets for the next number 'i'
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
cin.get();
return 0;
}
I would also suggest you look at Which is the fastest algorithm to find prime numbers? to find some more efficient ways to get prime numbers.
Old Answer:
In your code you have:
for (int i = 2; time(NULL)!=timerr; i=+2)
So when you start checking from primes you start with 2 which is prime. Then you increment i by 2 so the next number you check is 4 which is an even number. All even numbers are not prime except for 2. Since you are always adding 2 you will always have an even number so the only prime number you will find is 2.

You have different issues:
for (int i = 2; time(NULL)!=timerr; i=+2) {
Here the syntax is just wrong: it must be i+=2, not i=+2, otherwise you will keep setting i to +2 and testing whether 2 is prime.
Then, as others have pointed out, why are you increasing i by 2? If you want to optimize the search, you should increase j by 2, not i! And j should in any case start from 2 (or, given your approach, from 1), and then you should try j = 3 and then you can increase j by 2 without the risk of skipping some important divisors.
Then, you reset primeEval to 0 only if you find a prime. If you test a number i that is not prime, primeEval stays at 2 and you'll never get into the block again.
So the final code could be:
#include <iostream>
using namespace std;
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
primeEval=0;
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}

Related

comparing a string at index i to a value in C++

So im working on a class assignment where I need to take a base 2 binary number and convert it to its base 10 equivalent. I wanted to store the binary as a string, then scan the string and skip the 0s, and at 1s add 2^i. Im not able to compare the string at index i to '0, and im not sure why if(binaryNumber.at(i) == '0') isnt working. It results in an "out of range memory error". Can someone help me understand why this doesnt work?
#include <iostream>
using namespace std;
void main() {
string binaryNumber;
int adder;
int total = 0;
cout << "Enter a binary number to convert to decimal \n";
cin >> binaryNumber;
reverse(binaryNumber.begin(),binaryNumber.end());
for (int i = 1; i <= binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') { //THIS IS THE PROBLEM
//do nothing and skip to next number
}
else {
adder = pow(2, i);
total = adder + total;
}
}
cout << "The binary number " << binaryNumber << " is " << total << " in decimal form.\n";
system("pause");
}
Array indices for C++ and many other languages use zero based index. That means for array of size 5, index ranges from 0 to 4. In your code your are iterating from 1 to array_length. Use:
for (int i = 0; i < binaryNumber.length(); i++)
The problem is not with the if statement but with your loop condition and index.
You have your index begin at one, while the first character of a string will be at index zero. Your out memory range error is caused by the fact that the loop stops when less than or equal, causing the index to increase one too many and leave the memory range of the string.
Simply changing the loop from
for (int i = 1; i <= binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') {
}
else {
adder = pow(2, i);
total = adder + total;
}
}
To
for (int i = 0; i < binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') {
}
else {
adder = pow(2, i);
total = adder + total;
}
}
Will solve the issue.
Because your started from 1 and not 0
for (int i = 1; i <= binaryNumber.length(); i++)
Try with that
for (int i = 0; i < binaryNumber.length(); i++)

Not able to understand the logic behind the code which is an optimisation problem of generating prime numbers between two given numbers

Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!
Input
The input begins with the number t of test cases in a single line (t<=10). In each of the next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.
Output
For every test case print all prime numbers p such that m <= p <= n, one number per line, test cases separated by an empty line.
Example
Input:
2
1 10
3 5
Output:
2
3
5
7
3
5
Warning: large Input/Output data, be careful with certain languages (though most should be OK if the algorithm is well designed)
I looked up on google to find an optimasation solution for the above problem and here's the code.
#include <iostream>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
int main() {
vector<int> primes;
primes.push_back(2);
for (int i = 3; i <= 32000; i+=2) {
bool isprime = true;
int cap = sqrt(i) + 1;
vector<int>::iterator p;
for (p = primes.begin(); p != primes.end(); p++) {
if (*p >= cap) break;
if (i % *p == 0) {
isprime = false;
break;
}
}
if (isprime) primes.push_back(i);
}
int T,N,M;
cin >> T;
for (int t = 0; t < T; t++) {
if (t) cout << endl;
cin >> M >> N;
if (M < 2) M = 2;
int cap = sqrt(N) + 1;
set<int> notprime;
notprime.clear();
vector<int>::iterator p;
for (p = primes.begin(); p != primes.end(); p++) {
if (*p >= cap) break;
int start;
if (*p >= M) start = (*p)*2;
else start = M + ((*p - M % *p) % *p); //not able to understand this logic.
for (int j = start; j <= N; j += *p) {
notprime.insert(j);
}
}
for (int i = M; i <= N; i++) {
if (notprime.count(i) == 0) {
cout << i << endl;
}
}
}
return 0;
}
I am not able to understand the above code. Please, help me in understanding it. I am just not getting the logic behind this program(I know STL, just want to understand the logic).
Its pretty simple really. You precalculate all primes that exists in your range. Then for each multiple of prime, except first, you mark number as "not prime".
Line you marked just calculates first occurence of particular prime's multiple in range M to N.
Edit: More explanations.
This method finds primes by first searching for all non-primes. What is left is primes.
To do so on first step it calculates all "small" primes. Then for each small prime it marks all its multiples that fit in target range. To do so, you need first calculate first occurence of this prime in your range - this is what "start" variable is. Basically it is first multiple of prime that >= M.
When yo have "start" you simply mark all multiples by adding prime to current number until you reach N.
If you still confused about what and how "start" is calculated try to think about how you would find "x" such that it is "x = A * y" and "x >= M" where you know A and M, but don't know "y".
Also I think there probably error in this algorithm. Because it should complete this cycle for each value in "nonprime" set. But may be it doesn't matter if first unaccounted prime multiple always > N.

Not sure where this infinite loop is coming from

I'm coming from C into C++, I might be missing something very basic.
I'm trying to make a program with the collatz conjecture.
Before the first iteration of the loop, i and j both correctly equal 1 and 10.
However, the value of i never seems to change although I have i++ in my loop.
I thought this would be a quick program to code but I'm getting hung up on this. Any help would be appreciated.
int n, j, i, count = 0;
cin >> n >> j;
for (i = n; i < j; i++){
while (i != 1){
if (i % 2 == 0)
i = i/2;
else
i = 3*i + 1;
}
count++;
cout << i << endl;
}
The problem in your code is that after you've run the while loop that tests whether the conjecture is true for i, i is by definition set back to 1 (since that's the condition to get out of the loop), so i++ keeps incrementing from 1 to 2 each time. You'll never get past 2.
If you're trying to test the Collatz Conjecture for all the numbers from n to j, you need to use a different variable in the while loop than you use for iteration.
And if count is supposed to tell you how many cycles are needed, you need to zero it before each while loop, and increment it inside the while loop.
int n, j, i;
cin >> n >> j;
for (i = n; i < j; i++){
int test = i;
int count = 0;
while (test != 1){
if (test % 2 == 0) {
test = test/2;
} else {
test = 3*test + 1;
}
count++;
}
cout << i << ' ' << count << endl;
}
Not sure what it's all about, but here's some quick observation:
your while(i != 1) loop means that it will either run indefinetely, or when this loop ends i will be equal to 1. Which means that your for (i = n; i < j; i++){ loops will always restart with i=1. No wonder it's a dead loop.
Before the first iteration of the loop, i and j both correctly equal 1 and 10.
The let's replay the second iteration of the outer loop.
Before it, at the end of the first iteration, i has been incremented to equal 2. Now,
i % 2 == 0 => i := i / 2, i.e. i := 1.
Now i == 1, inner loop ends.
i is incremented and now equals 2.
Repeat.
You can simply copy the loop variable to a new variable in every loop iteration i = k in this case, so that the for loop variable is not affected
#include <iostream>
int main(){
int min, max, count = 0;
std::cin >> min >> max;
for (int k = min; k <= max; ++k){
i = k;
while (i != 1)
{
if (i % 2 == 0)
i /= 2;
else
i = 3*i + 1;
count++;
std::cout << i << std::endl; //ONLY IF U WANT TO PRINT i EVERY ITERATION
}
std::cout << "Number of iterations needed: " << count << " for i = " << i << std:: endl;
}

Print divisors in order using theta(n) efficiency

I'm struggling to implement this correctly. I want to create a function that determines all of the divisors of the user input userNum and outputs them to the user. When userNum = 16 i'm getting the output 1 16 2 8. I didn't expect the order to be correct, but i'm missing 4 and am struggling to figure out why. Any thoughts? I'm trying to do this in theta(sqrt(num)) efficiency.
void PrintDivisors(int num);
int main()
{
int userNum;
//Request user number
cout << "Please input a positive integer >=2:" << endl;
cin >> userNum;
PrintDivisors(userNum);
return 0;
}
void PrintDivisors(int num)
{
int divisorCounter;
for (divisorCounter = 1; divisorCounter < sqrt(num); divisorCounter++)
{
if (num % divisorCounter == 0 && num / divisorCounter != divisorCounter)
cout << divisorCounter << endl << num / divisorCounter << endl;
else if (num % divisorCounter == 0 && num / divisorCounter == divisorCounter)
cout << divisorCounter << endl;
}
}
Update: I have all the numbers printing, but still trying to determine how to print them in order while remaining within theta sqrt(n) efficiency
Change loop termination condition operation to <=, now you will observe 4.
Get rid of sqrt function call. Better use this loop
for (divisorCounter = 1; divisorCounter * divisorCounter <= num; divisorCounter++)
Make sure to check your edge conditions carefully.
What is sqrt(num)?
What is the largest divisorCounter that will pass the test in the for loop?
Would 4 pass the test?
I think if you look carefully at that line with these three questions in mind you will squash the bug.
For making it run in sqrt(n) time complexity:
For any n = a X b. either a<=sqrt(n) or b<=sqrt(n).
So if you can find all divisors in range [1,sqrt(n)] you can find other divisors greater than sqrt(n)
You can use a for loop to traverse numbers in range 1 to sqrt(n) and find all the divisors less than sqrt(n), which at the same time you can also use to find other numbers greater than(or equal to) sqrt(n).
Suppose a number i < sqrt(n) is divisor or n. In that case the number k = n/i will also be divisor of n. But bigger than sqrt(n).
For printing numbers in sorted order:
During finding divisors in range [1,sqrt(n)] print only divisor in range [1,sqrt(n)] You can use an array/vector to store numbers in range [sqrt(n),n] and print them after the for loop ends. Here is a sample code
vector<int> otherNums;
for(i=1;i*i<n;i++) {
if(num%i==0){
cout<<i<<endl;
otherNums.push_back(n/i);
}
}
if(i*i == n) otherNums.push_back(i);
for(i=(int)v.size() - 1 ;i>=0;i--)
cout<<otherNums[i]<<endl;
This is the solution I ended up using, which saves space complexity too. I was struggling to think of effective ways to loop over the solution in ascending order, but this one runs very fast and is nicer than appending to a vector or array or some weird string concatenation.
void printDivisors(int num)
{
for (int k = 1; k*k < num; k++)
{
if (num % k == 0)
cout << k << " ";
}
for (int d = sqrt(num); d >= 1; d--)
{
if (num % d == 0)
cout << num / d << " ";
}
cout << endl;
}

Can you explain this code to me and why is work c++ prime numbers

This code is to find the prime numbers from 3 to n, n being an input. this code works perfect but I need to understand it much more clearly mostly the part within the nested for loop.
#include <iostream>
using namespace std;
int main ()
{
cout << "Please enter a number: \n";
int inputtedNumber;
cin >> inputtedNumber;
cout <<"the primes between 3 and that number are: \n";
int candidate = inputtedNumber;
for (int i=3; i<candidate; i++)
{
bool prime=true;
for (int j=2; j*j<=i;j++)
{
if (i % j == 0)
{
prime=false;
break;
}
}
if(prime) cout << i << "\n";
}
system("pause");
return 0;
}
thank you!
The inner loop looks at each number from 2 to the square root of i, to see if i is divisible by that number. If i is divisible by j, then i%j will be zero. If it finds a divisor, then we know it's not prime and can stop looking.
There's no need to go beyond the square root since, if there is a divisor larger than that, there must also be a corresponding divisor smaller than that, which will already have been found by this loop.
This line is key.
if (i % j == 0)
The if block is executed if i is divisible by j, which implies that i is not prime.
for (int i=3; i<candidate; i++) // for every i between 3 and candidate
{
bool prime=true;
for (int j=2; j*j<=i;j++) // for every j between 2 and the square root of i
{
if (i % j == 0) // if there is an i that is evenly divisible by j
{
prime=false; // set the flag
break; // break the inner loop
}
}
if(prime) cout << i << "\n"; // if i was a prime (no j's were evenly divisible), print it
}