The Sieve of Eratosthenes and Goldbach's Conjecture - c++

The Sieve of Eratosthenes and Goldbach's Conjecture
Implement the Sieve of Eratosthenes and use it to find all prime
numbers less than or equal to one million. Use the result to
prove Goldbach's Conjecture for all even integers between four and
one million, inclusive.
Implement a function with the following declaration:
void sieve(int array[], int num);
This function takes an integer array as its argument. The array
should be initialized to the values 1 through 1000000. The
function modifies the array so that only the prime numbers remain;
all other values are zeroed out.
This function must be written to accept an integer array of any
size. You must should output for all primes numbers between 1 and
1000000, but when I test your function it may be on an array of a
different size.
Implement a function with the following declaration:
void goldbach(int array[], int num);
This function takes the same argument as the previous function
and displays each even integer between 4 and 1000000 with two
prime numbers that add to it.
The goal here is to provide an efficient implementation. This
means no multiplication, division, or modulus when determining if
a number is prime. It also means that the second function must find
two primes efficiently.
Output for your program: All prime numbers between 1 and 1000000
and all even numbers between 4 and 1000000 and the two prime
numbers that sum up to it.
DO NOT provide output or a session record for this project!
This is the code that I have so far, my problem is that it displays numbers higher than 1,000 as 1s, how can I go about this, thank you!
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
void sieve(int array[], int num);
void goldbach(int array[], int num);
const int arraySize = 1000000;
int nums[arraySize];
int main(){
for (int i = 0; i <= arraySize; ++i)
nums[i] = 1;
nums[0] = nums[1] = 0;
sieve(nums, arraySize);
for(int i = 0; i < 10000; ++i){
if (nums[i] > 0){
cout << nums[i] << " ";
}
}
goldbach(nums, arraySize);
return 0;
}
void sieve(int array[], int num) {
int squareR = (int)sqrt(num);
for(int i = 2; i <= squareR; ++i){
int k;
if(array[i]){
for(k = i*i; k <= num; k += i)
array[k] = 0;
}
if (array[i] == 1){
array[i] = i;
}
}
}
void goldbach(int array[], int num){
int i, r = 0;
for (i = 4; i <= num; i += 2){
for (int j = 2; j <= i/2; j++)
if (array[j] && array[i-j]) r ++;
}
}

my problem is that it displays numbers higher than 1,000 as 1s, how can I go about this
That's because you're not updating the values in the array above 1000, here:
for(int i = 2; i <= squareR; ++i){
...
if (array[i] == 1){
array[i] = i;
clearly the array's entries above squareR are not updated and remain at the value you initialized them, which is 1.
However I you don't need this update at all. You can drop it and simplify your code, keeping the array's entries as either 1 (for primes) or 0 (for non-primes). with this, and display your result like this (in main):
for(int i = 0; i < arraySize; ++i){
if (nums[i] != 0){
// cout << nums[i] << " "; // <-- drop this
cout << i << " "; // <-- use this
}
}

Related

Maximum and Minimum difference (greedy algorithm)

Problem:
You are given an array A ,of n elements.You have to remove exactly n/2 elements from an array and add it to another array B
(intially empty).Find the maximum and minimum values of difference
between these two arrays.The difference between those two arrays is
sum(abs(A[i]-B[i]).
The code only works if the size of the array(N) is even.
Can someone provide a solution which works when the size of array is odd as well.
#include <bits/stdc++.h>
using namespace std;
//This code only works for even number of elements
int main(){
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a.begin(), a.end());
long long mn = 0,mx = 0;
for(int i=0;i<n/2;i++){
mx+=a[i+n/2]-a[i];
mn+=a[2*i+1]-a[2*i];
}
cout<<abs(mn)<<" "<<abs(mx)<<" ";
return 0;
}
For me, I like to split up the work to easily visualize where efficiencies can be made in the algorithm. The following is very similar to your solution, but works fine for both even and odd length vectors. The average runtime is O(nlogn) for sort with space complexity as O(n) for the vectors.
// Given two arrays of equal length, returns their "Difference", O(n) runtime
int ArrayDiff(vector<int> A, vector<int> B)
{
if (A.size() != B.size() || A.size() == 0) return -1;
int sum = 0;
for (int i = 0; i < A.size(); i++)
{
sum += abs(A[i] - B[i]);
}
return sum;
}
// Given a vector arr, find the max and min "Difference"
void PrintMaxAndMin(vector<int> arr)
{
int n = arr.size();
if (n <= 0) return;
vector<int> Amax, Amin, Bmax, Bmin {};
// for each iteration of removing n/2 elements, we find the max and min of the arrays
sort(arr.begin(), arr.end());
for (int i = 0; i < n/2; i++)
{
Amax.push_back(arr[i]);
Bmax.push_back(arr[n-i-1]);
Amin.push_back(arr[n-i-1]);
Bmin.push_back(arr[n-i-2]);
}
cout << ArrayDiff(Amax, Bmax) << " " << ArrayDiff(Amin, Bmin) << endl;
}
// Run the above functions on a vector of odd and even sizes
int main(){
vector<int> arr_even = { 4,3,2,1 };
cout << "Even Length Vector: ";
PrintMaxAndMin(arr_even);
vector<int> arr_odd = { 5,4,3,2,1 };
cout << "Odd Length Vector: ";
PrintMaxAndMin(arr_odd);
return 0;
}
Here's the working example: live example. Hope this helped.
Program output:
Program stdout
Even Length Vector: 4 2
Odd Length Vector: 6 2

(C++) Generate first p*n perfect square numbers in an array (p and n inputted from the keyboard)

I input p and n (int type) numbers from my keyboard, I want to generate the first p*n square numbers into the array pp[99]. Here's my code:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int i, j, n, p, pp[19];
cout<<"n="; cin>>n;
cout<<"p="; cin>>p;
i=n*p;
j=-1;
while(i!=0)
{
if(sqrt(i)==(float)sqrt(i))
{
j++;
pp[j]=i;
}
i--;
}
for(i=0; i<n*p; i++)
cout<<pp[i]<<" ";
return 0;
}
But I am encountering the following problem: If I for example I enter p=3 and n=3, it will only show me the first 3 square numbers instead of 9, the rest 6 being zeros. Now I know why this happens, just not sure how to fix it (it's checking the first n * p natural numbers and seeing which are squares, not the first n*p squares).
If I take the i-- and add it in the if{ } statement then the algorithm will never end, once it reaches a non-square number (which will be instant unless the first one it checks is a perfect square) the algorithm will stop succeeding in iteration and will be blocked checking the same number an infinite amount of times.
Any way to fix this?
Instead of searching for them, generate them.
int square(int x)
{
return x * x;
}
int main()
{
int n = 0;
int p = 0;
std::cin >> n >> p;
int limit = n * p;
int squares[99] = {};
for (int i = 0; i < limit; i++)
{
squares[i] = square(i+1);
}
for (int i = 0; i < limit; i++)
{
std::cout << squares[i] << ' ';
}
}

Print the maximum non perfect square

I'm trying to make a c++ program that finds the maximum non perfect square in an array and print it, perfect square i.e. x = y^2 => 4 = 2^2.
Here is what I've tried and doesn't work for me, don't know why:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
sqrt(arr[i]);
if ((arr[i] * 10) % 10 == 0)
arr[i] = arr[1];
else
arr[i] = arr[0];
}
for (int i = 0; i < n; i++)
{
if (arr[0] < arr[i])
arr[0] = arr[i];
}
cout << arr[0] << endl;
return 0;
}
My logic is to take the square root of each array element and check if it's non-perfect or perfect. If we multiply the element by 10, then take modulus of 10, then we know whether it is an integer or decimal. For example: 2*10 = 20, 20%10 = 0 (perfect square), otherwise it is not perfect. Then, I stored each non-perfect square in arr[0], in the next loop I'm supposed to find the largest non perfect square and print it. What am I doing wrong?
PS:
Consider arr[variable] is valid, because it works in CodeBlocks. Thank you!
You lost the result of sqrt. sqrt(arr[i]) does not change arr[i]).
You improperly check if a square root is an integral. You should cast a result of sqrt to int, multiply it by itself and compare with arr[i].
I left you free to update your code properly yourself.
You can use this logic to find if a number is perfect-square or not, this is one way to find largest non perfect square of an array of positive numbers, initialize answer=-1 before you enter the loop, n is the size of the array
double answer = -1,temp;
for(int i=0;i<n;i++){
if((temp = array[i]) != (sqrt(array[i])*sqrt(array[i]))){
if(temp > answer){
answer = temp;
}
}
}
#include <iostream>
#include <cmath>
using namespace std;
int main () {
int n;
cin>>n;
int k[n];
double arr[n];
for (int i = 0 ; i < n ; i++){
cin>>k[i];
arr[i]=sqrt(k[i]);
int j = arr[i];
if (arr[i]==j){
arr[i]=0;
}
}
double m=0;
int index = 0;
for (int i = 0; i < n; i++){
if (arr[i]>m){
m=arr[i];
index = i;
}
}
cout << k[index];
}
Here is a code. We introduce a double, such that it can store the decimals. Then we introduce an integer. If the square root of the number is a decimal, it is not a perfect square. However, when I introduce this integer j, it will convert arr[i] to an integer. If the number is a perfect square, then arr[i] is an integer, and j==arr[i]. We do not want that, so we put that equal 0. We find the largest array, and mark the index. Then we print out the original number in the original array with that index. i have added this as float does not store every single decimal point.
To clarify: lets say arr[i]=4.55556. Then j=4. arr[i]!=j. If arr[i]=5, j=5, arr[i]=j, and then arr[i] is set to 0.

Function returning sum of even numbers in an array

So the prompt I was given was "Write a function that is given an array of ints and returns the sum of the even numbers in the array. The function is not given the length of array, but the last number in the array is -1. For example, if the array contains {2,3,5,4,-1} the function returns 6. Use the header int sumEven(int myArray[]). "
and the code I've written so far is
#include <iostream>
using namespace std;
int sumEven(int myArray[]){
int sum = 0;
for (int i=0; i++;){
if (myArray[i] >=0) {
sum+=myArray[i];
}
}
return sum;
}
But it keeps returning back zero's? I'm not seeing what I'm doing wrong here
The typical order of parameters to a for() loop are like so:
for(<initialize variable>; <end condition>; <increment variable>)
In your example, you have the i++ as your second parameter to the for loop, which is incorrect. It will return 0 (since i starts as 0, and i++ is post-increment, so it returns 0 and then increments to 1) and your for loop will exit immediately, since 0 evaluates to false.
Instead, replace the end condition with the end condition you've described: myArray[i] != -1. You should also include a check to see if the number is even before adding it to sum, which can be done by checking to see if the remainder when divided by 2 is 0.
#include <iostream>
using namespace std;
int sumEven(int myArray[]){
int sum = 0;
for (int i=0; myArray[i] != -1; i++){
if(myArray[i] % 2 == 0)
sum += myArray[i];
}
return sum;
}
The error is in the for loop. You should change the for loop to for (int i=0; ; i++) and you should also add a break statement to exit the for loop.
using namespace std;
int sumEven(int myArray[]){
int sum = 0;
for (int i=0; ; i++){
if (myArray[i] >=0) {
sum+=myArray[i];
}
else
{
break;
}
}
return sum;
}
int sumEven(int arr[]) {
int sum = 0;
// int len = (sizeof(arr)/sizeof(*arr)); // Since this will not work for all cases.
// auto len = end(arr) - begin(arr);
for (int i = 0; arr[i] >= 0; i++) {
if(arr[i]%2==0)
sum += arr[i];
}
return sum;
}
i guess the
for (int i=0; i++;){
make no iterations, cause condition to continue loop is "i++" - which is initialy zero.
Replace it with following for example
for (int i=0; i < array_length; i++;){

Modifying a dynamic 2D array in a function

I've got a function that accepts a dynamic multidimensional array (which is initialized to 0) as a parameter, and I'm trying to modify certain values within the array in my function.
The function that accepts the array as a parameter is supposed to simulate the roll of two dice and output the frequency distribution to the array I made that's initialized to zero.
The code for it is as follows:
#include <iostream>
#include <cstdlib>
using namespace std;
int** rollDie(int numRolls, unsigned short seed, int** &rollarray)
{
srand(seed);
int side1, side2;
while (numRolls > 0)
{
side1 = 1 + rand() % 6;
side2 = 1 + rand() % 6;
rollarray[side1][side2]++;
numRolls--;
}
return rollarray;
}
int** initializeArray(void)
{
int i, j;
int** m = new int*[6];
for (i = 0; i < 6; i++)
m[i] = new int[6];
for (i = 0; i < 6; i++)
for (j = 0; j < 6; j++)
m[i][j] = 0;
return m;
}
int main()
{
int numRolls;
unsigned short seed;
int ** a = initializeArray();
cout << "rolls?\n";
cin >> numRolls;
cout << "seed?\n";
cin >> seed;
int ** b = rollDie(numRolls, seed, a);
int i,j;
for (i = 0; i < 6; i++) {
for (j = 0; j < 6; j++) {
cout << b[i][j];
}
cout << "\n";
}
}
Code works for me with just a few issues (I had to guess how you defined a. Next time add that too):
In the printing you should print a space after every number (minor)
In the random, you choose index as 1+rand()%6, so from 1 to 6, but when you print you take indexes from 0 to 5! So your first row and first column will be 0.
Other than that it seems to work.
Only when one goes and does something else does the answer come to mind. I suspect you declared a as:
int a[6][6];
which is an array of 36 integers. In your function, though, you're declaring rollarray to be a pointer to an array of pointers to integers. All you need to do is change the function signature to:
int* rollDie(int numRolls, unsigned short seed, int* rollarray)
As cluracan said, you also want to use array indices in the range 0 to 5.
This is a good case for either the judicious use of print statements or stepping through with a debugger to see what's really going on.