Sieve of Eratosthenes not working beyond 200,000 - c++

My C++ program to calculate all the prime numbers using sieve of Eratosthenes method stops after 200,000. But I need to calculate the primes up to 2 million. Help would be appreciated if someone could tell me where I went wrong with my code.
#include <iostream>
#include<math.h>
using namespace std;
void isprime(long long int prime[],long int n)
{
for(long long int i=0;i<=n;i++)
{
prime[i]=1;
}
prime[0]=prime[1]=0;
for(long long int i=2;i<=sqrt(n);i++)
{
if(prime[i]==1)
{
for(long long int j=2;i*j<=n;j++)
prime[i*j]=0;
}
}
for(long long int i=0;i<=n;i++)
{
if(prime[i]==1)
cout<<i<<endl;
}
}
int main()
{
long long int n;
cout<<"enter number";
cin>>n;
long long int prime[n+1];
isprime(prime,n);
return 0;
}

Since each sieve element contains only a 0 or 1, there is no need to use a long long int to store each one. std::vector<bool> potentially uses 1 bit per element and thus is optimal for memory efficiency.
Here is your code with a very few modifications to use a std::vector<bool>. Since some bit manipulation is required to get and set individual elements, this version may be slower than code which uses one byte or int per sieve element. You can benchmark various versions and decide the right trade-off for your needs.
#include <cmath>
#include <cstddef>
#include <exception>
#include <iostream>
#include <string>
#include <vector>
// returns the number of primes <= n
long isprime(long n) {
std::vector<bool> prime(n + 1);
for (long i = 0; i <= n; i++) {
prime[i] = 1;
}
prime[0] = prime[1] = 0;
long upper_bound = std::sqrt(n);
for (long i = 2; i <= upper_bound; i++) {
if (prime[i] == 1) {
for (long j = 2; i * j <= n; j++)
prime[i * j] = 0;
}
}
long num_primes = 0;
for (long i = 0; i <= n; i++) {
if (prime[i] == 1) {
++num_primes;
// std::cout << i << std::endl;
}
}
return num_primes;
}
int main() {
std::cout << "Enter the sieve size: ";
std::string line;
std::getline(std::cin, line);
std::cout << std::endl;
long len = std::stol(line);
long num_primes = isprime(len);
std::cout << "There are " << num_primes << " primes <= " << len << std::endl;
return 0;
}

Related

Trying to implement Willans' formula for the n-th prime, what's the problem with my code?

The formula is listed in the following article: https://en.wikipedia.org/wiki/Formula_for_primes. I am trying to implement it but to no success, for whatever reason the code is producing number which seem to be nth power of two + 1, which is obviously not what I want to achieve.
#include <iostream>
#include <cmath>
using namespace std;
int nth_prime(int n) {
double s = 1;
for (int i = 1; i <= pow(2, n); i++) {
double c = 0;
for (int j = 1; j <= i; j++) {
double f = (tgamma(j)+1)/j;
c+=floor(pow(cos(M_PI*f), 2));
}
s+=floor(pow(n/c, 1/n));
}
return s;
}
int main() {
int n;
while (cin >> n) {
cout << nth_prime(n) << endl;
}
return 0;
}

CPP Prime Generator SPOJ Sieve

I did implement Sieve prime generator. The code is pretty fast and consumes less memory. https://www.spoj.com/problems/PRIME1/
But I get "Wrong Answer" when I submit the solution. People online seem to just make the set the max to 32000 and run the solution. I don't exactly get where am I actually wrong? Or Is it just an extra newline (if possible) that makes the solution to be incorrect?
#include <iostream>
#include <unordered_map>
using namespace std;
int main(void) {
unordered_map<long long int, bool> notPrime;
notPrime[0] = true;
notPrime[1] = true;
for (long long int x = 2; x < 100000; x++) {
if (notPrime[x]) continue;
for (long long int u = 2 * x; u < 100000; u += x)
notPrime[u] = true;
}
int n;
cin >> n;
while (n--) {
long long int s, e;
cin >> s >> e;
if (s < 0)
s = 0;
for (long long int i = s; i <= e; i++) {
if (!notPrime[i]) {
cout << i << '\n';
}
}
if (n)
puts("");
}
return 0;
}

C++ Program loops forever

I seem to be having an issue that I've been stuck on for hours. I run the program, and it just hangs after asking for the user input. My computer also begins to slow down unless I terminate the program. I have no idea what the problem is. I have tried commenting out code to see where the issue may be coming from. I put a cout statement after asking for the input, and even that does not display.
#include <iostream>
#include <vector>
#include <stdexcept>
#include <iomanip>
#include <cstdlib>
#include <array>
#include "problem2.h"
using namespace std;
int binarySearch(int array[], int input);
void selectSort(int arr[], int n);
int problem2() {
srand(time(0)); // generate seed based on current system time
int rand[20];
int result;
int input = 1;
cout << "Enter a number to search for: ";
cin >> input;
cout << "testset ";
for (int z = 0; z < 19; z++) {
rand[z] = random() % 70;
cout << rand[15];
}
selectSort(rand, 20);
for (int t = 0; t < 20; t++) {
//cout << random1D[z];
}
result = binarySearch(rand, input);
//cout << result;
return 0;
}
int binarySearch(int arr[], int a) {
int high = 19;
int middle = 19/2;
int low = 0;
while (arr[middle] != a && low<= high) {
if (arr[middle] > a) {
high = middle - 1;
} else {
low = middle - 1;
}
if (low > high) {
}
}
return middle;
}
void selectSort(int arr[], int n) {
int min, temp;
for (int i = 0; i < n-1; i++) {
min = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min])
min = j;
}
if (min != i) {
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
You have several loops, but all of them except for one have explicit termination. The for loops all end after a specific number of iterations, but your while loop is less certain. Your low is likely never going to be greater than your high, so the loop just keeps going.
Consider changing to low = middle + 1 or altering your logic to more likely ensure that low will eventually overtake high. Or, change the condition the while loop checks.

Neumann's Random Generator

Please read the task first: http://codeabbey.com/index/task_view/neumanns-random-generator
I have to keep track of the number of iterations, but I get very strange results. In the example after the task we have the numbers 0001 and 4100 and they should come to loop after 2 and 4 iterations. But my results are 1, 4 or if I change the place of the counter 2 or 5 but never 2 and 4. Here is my code:
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
int value;
int counter;
int result;
int setvalue = 1; // use to exit the loop if setvalue == 0;
cin >> n;
vector<int> new_results(0); // use to store all the results from iterations
vector<int> results_vec(0); // use to store the number of iterations for each number
for (int i = 0; i < n ; i++)
{
cin >> value;
while(setvalue == 1)
{
value = value*value;
value = (value % 1000000) / 100;
if(find(results_vec.begin(), results_vec.end(), value) == results_vec.end())
{
results_vec.push_back(value);
}
else
{
counter = results_vec.size();
new_results.push_back(counter);
setvalue = 0;
}
}
results_vec.clear();
}
for (int i = 0; i < new_results.size() ; i++)
{
cout << new_results[i] << " ";
}
}
Going in and out of a string the way you have is really very ugly and extremely expensive computationally.
Use
(value % 1000000) / 100;
instead to extract the middle four digits. This works by (1) taking the modulus to remove the leading two digits then (2) removing the last two with integer division.
As it's so much simpler, I suspect that will fix your bugs too.
Here is the correct code, thank you for all your help.
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
int value;
int counter;
int result;
cin >> n;
vector<int> new_results(0); // use to store all the results from iterations
vector<int> results_vec(0); // use to store the number of iterations for each number
for (int i = 0; i < n ; i++)
{
cin >> value;
results_vec.push_back(value);
while(true)
{
value = value*value;
value = (value % 1000000) / 100;
if(find(results_vec.begin(), results_vec.end(), value) == results_vec.end())
{
results_vec.push_back(value);
}
else
{
counter = results_vec.size();
new_results.push_back(counter);
break;
}
}
results_vec.clear();
}
for (int i = 0; i < new_results.size() ; i++)
{
cout << new_results[i] << " ";
}
}

C++ factorial function not working

Can someone please help me understand why this code isn't working properly? I know it's very close and I think that I'm just overlooking something. Any help is appreciated. Here is what I have so far:
#include <iostream>
#define TEST_ARRAY_SIZE 4
long int factorial(int num);
long int factorial(int num){
for(unsigned int i = 1; i <= num; i++) {
num *= i;
}
return num;
}
int main() {
int test[TEST_ARRAY_SIZE] = {1, 2, 5, 7};
for (unsigned int i = 0; i < TEST_ARRAY_SIZE; i++) {
std::cout << "Factorial of " << test[i] << " is " << factorial(test[i]) << std::endl;
}
return 0;
}
You should move return num; outside the loop. As it is now, control always return after the first number is multiplied.
-- the correct code --
long int factorial(int num){
long int res = 1;
for(unsigned int i = 1; i <= num; i++) {
res *= i;
}
return res;
}
The body of the factorial function is not correct. You can use a recursive method to compute the factorial of a specific number. The corrected program of your version is below:
#include <iostream>
#define TEST_ARRAY_SIZE 4
long int factorial(int num);
int main() {
int test[TEST_ARRAY_SIZE] = {1, 2, 5, 7};
for (unsigned int i = 0; i < TEST_ARRAY_SIZE; i++) {
std::cout << "Factorial of " << test[i] << " is " << factorial(test[i]) << std::endl;
}
return 0;
}
long int factorial(int num){
if (num == 1)
return num;
else
return num * factorial(num-1);
}
That's only part of the problem; it's a case in which proper indentation would make the bug apparent in an instant.
In addition to that, why are you using num inside the loop? You should leave it as-is and declare a new variable to compound and return the result.
long int factorial(unsigned int num) {
int x = 1;
for(unsigned int i = 1; i <= num; i++) {
x *= i;
}
return x;
}
Other things to note:
You shouldn't be using a #define; you should declare a const instead.
You're comparing an unsigned against a signed in the factorial() for loop.