Summing Prime Numbers below two million - c++

You may have heard of a website called Project Euler (projecteuler.net). I'm working through the first problems, which were quite trivial, and I'm on the problem described in the title.
This isn't about optimising or anything - it takes about 90 thousandths of a second to complete. It's giving me the wrong total.
Can someone help me? I have no clue why the answer I'm getting - from both the array total (atotal) and the total that was added up normally (total) - is incorrect. The answer they are both showing is 947402457, which the website it telling me is the wrong answer.
In case it's just the wording, the question is here: http://projecteuler.net/index.php?section=problems&id=10
What's also very strange is, as far as I can tell, when, at the end when you can type in which prime number you would like to view (it takes it out of the array), it gives you the correct answer.
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <ctime>
typedef unsigned long int bignum;
//there are 666671 primes below two million
int main(){
using namespace std;
bignum top = 2000000;
bignum total = 0;
bignum atotal = 0;
//hardcode 2 and 3
total += 5;
int inc = 2;
bignum n = 5;
double sq = n;
bignum np = 1;
bignum *pa = new bignum[top];
pa[0] = 2;
pa[1] = 3;
while (n < top){
int div = 5;
int divinc = 2;
int p = 1;
//check if number is prime
//check divisiblity from any possible prime up to the square root of n
//first hardcode 2 and 3
if(n%2==0||n%3==0)
p = 0;
else{
while(div<=sqrt(sq)){
if(n%div==0){
p = 0;
break;
}else{
div = div + divinc;
if(divinc==2) divinc = 4; else divinc = 2;
}
}if(p!=0){ //if it's a prime - 0 is not, 1 is prime
total = total + n;
np++;
pa[np] = n;
//cout << np << " prime number: " << n << endl; //takes too long if it prints everything
}
}
n += inc;
if(inc==2) inc = 4; else inc = 2;
}
for (int c=0;c<=np;c++){
atotal += pa[c];
}
cout << "Total " << top << ": " << total << endl;
cout << "Array total: " << atotal << endl;
cout << "Elapsed time: " << clock() << " " << CLOCKS_PER_SEC << "s of a second" << endl << endl;
while(true){
int ptoview = 0;
cout << "Enter the number of the prime you would like to see (you can view every prime number below "<<top<<") ";
cin >> ptoview;
if (pa[ptoview-1]){
if (pa[ptoview-1] < top)
cout << ptoview << " prime: " << pa[ptoview-1] << endl;
else
cout << "Too high/low" << endl;
cout << endl;
}
}
system("PAUSE");
return 0;
}

Here's a clue to at least one problem. Have a look at what happens when you replace:
for (int c=0;c<=np;c++){
atotal += pa[c];
}
with:
for (int c=0;c<=np;c++){
bignum oldatotal = atotal;
atotal += pa[c];
if (atotal < oldatotal)
cout << "Hmmm: " << oldatotal << " " << atotal << endl;
}
I get something like:
Hmmm: 4294819625 12858
Hmmm: 4294864122 123849
Hmmm: 4294717053 27802
Hmmm: 4294697657 51420
: : :
Hmmm: 4293781002 792849
Hmmm: 4294658253 1676602
Hmmm: 4293686116 710941
Hmmm: 4294706293 1737578
Total 2000000: 947402457
Array total: 947402457
I won't go into the detail since this is a puzzle and I'm assuming you want to keep it at least a little challenging :-)
And yes, you're right (based on your comment below) so I'll make the answer a little less obtuse so it's more useful for others.
The unsigned long type is not big enough to hold the sum of all those primes so it's wrapping around.
Whether it can hold the actual primes themselves I haven't checked, but the answer in the next paragraph will solve that as well.
You might want to try redefining bignum as a "larger" type like unsigned long long if available.

Not looked at everything but sq isn't modified in the main while loop. That doesn't seem right. (BTW, I'd have used a sieve filter to get to the primes).

Related

Palindromes And Project Euler C++ Version -Tips

Can Anyone Tell Me What's Wrong In My Code?
Thank you :)
// A palindromic number reads the same both ways.
// The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
// Find the largest palindrome made from the product of two 3-digit numbers.
#include <iostream>
using namespace std;
int main()
{
int x = 2;
int product;
int n, digit, rev = 0;
int greatest = 0;
for(int i = 2;i<100;i++){
product = x * i;
n = product;
cout << x << " * " << i << " = " << product << endl;
do
{
digit = product % 10;
rev = (rev * 10) + digit;
product = product / 10;
} while(product != 0);
cout << " The reverse of the number is: " << rev << endl;
if(n == rev){
cout << "Therefore Palindrome" << endl;
if(rev > greatest){
cout << "REV Greater Than Greatest Palindrome" << endl;
greatest = rev;
}
}
if(i == 99){
if(x < 99){
x++;
i = 1;
cout << "Go For The Next Loop" << endl;
}
}
}
cout << "The Greatest Palindrome Number Is " << greatest << endl;
return 0;
}
Several things:
You should be counting down from 999 thru 100.
You should be using two loops for the two factors of your product
rev should be initially zero before each entrance into your inner do-while loop
The results would look something like this, with all but the detected palindromes and final result being output (the amount of worthless noise in your output is mind-bending)
#include <iostream>
using namespace std;
int main()
{
int product;
int n, digit, rev = 0;
int greatest = 0;
for(int i = 999;i>=100; --i)
{
for (int j =999; j>=100; --j)
{
product = j * i;
n = product;
rev = 0;
do
{
rev = (rev * 10) + (product % 10);
product /= 10;
} while(product != 0);
if(n == rev)
{
cout << "Palindrome : " << i << " * " << j << " = " << n << endl;
if(rev > greatest)
greatest = rev;
}
}
}
cout << "The Greatest Palindrome Number Is : " << greatest << endl;
return 0;
}
This will conclude the correct answer you seek.
Faster
Optionally, you can squeeze better performance out of this by understanding a few additional details:
The task is to find the largest palindrome, not just the longest palindrome. Therefore, once you find one, any product, palindrome or not, that is a smaller magnitude than the current largest palindrome is pointless to even check and the inner loop can be terminated (thus the reason you're counting down).
A little number crunching will allow you to conclude that at least one of the factors must be divisible by 11. I won't cover why, but do the math, it's true. Therefore, you can make one of your loops a count-down from the largest 3-digit multiple of 11 (990) to 100, in steps of (-11).
The result looks like this:
#include <iostream>
using namespace std;
int main()
{
int greatest = 0;
for(int i = 999;i>=100; --i)
{
for (int j =990; j>=100; j-=11)
{
int product = j * i;
if (product < greatest)
break;
int n = product;
int rev = 0;
do
{
rev = (rev * 10) + (product % 10);
product /= 10;
} while(product != 0);
if(n == rev)
{
cout << "Palindrome : " << i << " * " << j << " = " << n << endl;
if(rev > greatest)
greatest = rev;
}
}
}
cout << "The Greatest Palindrome Number Is : " << greatest << endl;
return 0;
}
Output
Palindrome : 995 * 583 = 580085
Palindrome : 993 * 913 = 906609
The Greatest Palindrome Number Is : 906609

c++ sum large numbers, Program stops?

am running these two functions that do the same calculation "summing the first N integers " then compare the run times for each one. The program works fine with small inputs, but the problem is when I input large numbers like 1000000, it calculates the first method "the iterativeSum()" then as soon as it gets to the the recursiveSum() it stops working.
am not sure but do you think that this might be because of the cout?
#include <stdio.h>
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
void iterativeSum(int);
int RecursiveSum(int);
int main()
{
long long posInt;
std::cout << "Enter a positive integer: ";
std::cin >> posInt;
int start_s=clock();
iterativeSum(posInt);
int stop_s=clock();
int start_s1=clock();
cout << "\nThe recursive algorithm to sum the first N integers of "<< posInt << " is: "<< RecursiveSum(posInt) << endl;
int stop_s1=clock();
cout << "time: " << (stop_s-start_s)/double(CLOCKS_PER_SEC)/1000 << endl;
cout << "time: " << (stop_s1-start_s1)/double(CLOCKS_PER_SEC)/1000 << endl;
return 0;
}
void iterativeSum(int posInt)
{
//positive Integer >=0
int sum = 0;
//loop through and get only postive integers and sum them up.
// postcondion met at i = 0
for(int i = 0; i <= posInt;i++)
{
sum +=i;
}
//output the positive integers to the screen
std::cout <<"\nThe iterative algorithm to sum the first N integers of " <<posInt <<" is: " << sum << "\n";
}
int RecursiveSum(int n)
{
if(n == 1) // base case
{
return 1;
}
else
{
return n + RecursiveSum(n - 1); //This is n + (n - 1) + (n - 2) ....
}
}
You may need an arbitrary precision arithmetic library like GMPlib, to avoid arithmetic overflows. And you should be afraid of stack overflow.
The call stack is often limited (to e.g. a megabyte). See this

Find the smallest value in a vector

I am pretty new when it comes to programming with STL and I thought I was getting the hang of it. But I am a little perplexed about this one bit. My goal is to take in 5 values, then print out my values, print the highest value among them, print the average, and print the lowest among them ( my problem ). It seems that my variable "low" is given the value of 0 and I do not know why this is. I have tested to see if my values are being read in and to my knowledge, they are. So if anyone could please enlighten me to why I cannot seem to get the proper lowest value, I would greatly appreciate it. Thank you for your time.
vector<double> vecList;
int x = 0;
double high = 0;
double low = 0;
double sum = 0;
cout << "Enter Integer Values, then press Ctrl(z) to Quit:" << endl;
for (int i=0; i < 5; i++)
{
cin >> x;
sum = sum + x;
vecList.push_back(x);
}
vector<double>::iterator intVecIter;
cout <<"List contains: ";
for (intVecIter = vecList.begin(); intVecIter != vecList.end(); ++intVecIter)
cout << *intVecIter << " ";
for (int i=0; i < 5; i++)
{
if(vecList[i] > high)
{
high = vecList[i];
}
// prints out "0"
if(low > vecList[i])
{
low = vecList[i];
}
}
cout << endl << "Largest: "<< fixed << setprecision(2) << high << endl;
cout << "Smallest: "<< fixed << setprecision(2) << low << endl;
cout << "Average: " << fixed << setprecision(2)<< (sum/5);
return 0;
Since you are trying to learn STL, take a look at the algorithms library and it has some helper functions which will give the min, max and sum (accumulate is the actual function name) for a given range.
you need to initalize low to a big value not 0, otherwise this
if(low > vecList[i])
is never true

Finding maxium factorial n what intiger allows! C++

Sorry for bad English.
So my problem is that i need to find all possible factorials starting from 1.
I need it to stop when Int have maximum memory used and print out maximum factorial value. My code is pretty simple, but i do not know how to get to stop loop when it reach maximum of Intiger values.
#include <iostream>
#include<climits>//
#include <cmath>
using namespace std;
int main() {
int k,n=0;
unsigned int factorial = 1;
unsigned int factorial2=1;
unsigned uval=INT_MAX;
cout << "Ievadi koeficentu k: ";
cin >> k;
for(int i = 1; i<=k; ++i) {
factorial *= i;
}
cout << "Ievadita koeficenta " << k << " faktorials " << " = " <<factorial;
cout << "\nVisi iespejamie faktoriali no 1 - n: ";
for(int s = 1; s<=uval; ++s) {
factorial2 *= s;
if( s < uval / factorial2 ){
cout <<" \nkoeficenta " << s << " faktorials ir ==> " <<factorial2;
}
}
return 0;
}
The problem is that the loop is going to calculate factorial to all UINT_MAX values, and most of the output will be 0 becouse memory is overloaded.
But it should stop before it goes bigger that UINT_MAX memory!
Hope you all understand my problem and will help me with this.
In a 32-bit signed integer, 12! is the largest possible.
You can check this by doing
if (INT_MAX / fact_so_far < n)
{
std::cout << "Max factorial " << n-1 << std::endl;
}
[This code STOPS when it reaches the "unable to calculate", because INT_MAX / fact_so_far will not multiply without overflow].
if (INT_MAX / fact_so_far >= n)
{
fact_so_far *= n;
}
else
{
std::cout << n << " is too large to calculate factorial" << std::endl;
}
would be the other way to do this. [Obviously with suitable loop to increment n]
Not that MAX_UINT is the max value for unsigned int, not for int [it's typically half that].
Edit to explain the logic:
The logic here is that if we divide INT_MAX with what our current factorial value is, it should produce a value larger than n [the current multiplier for the next factorial].
As a simple step through example, we pick a MAX_INT of 127:
Initial state:
factorial = 1, n = 1;
Steps:
n = 2, MAX_INT / factorial = 127 -> factorial *= n => 2
n = 3, MAX_INT / factorial = 63 -> factorial *= n => 6
n = 4, MAX_INT / factorial = 21 -> factorial *= n => 24
n = 5, MAX_INT / factorial = 5 -> factorial *= n = 120
n = 6, MAX_INT / factorial = 1 -> FAIL - will overflow.
Before calculating the next factorial in the list, see if the previous one is greater than UINT_MAX / i. If it is, you know that the next multiplication will go out of bounds.
If factorial2 > UINT_MAX / (s+1), the next factorial can't be calculated.
By the way, you should use unsigned int for factorial2
You are comparing the signed int with an unsigned one i.e. you are doing i < UINT_MAX (This is the maximum value of unsigned int) which is wrong and will result in overflow and wrong condition check.
so i finaly did this with my code. Now it works but its not realy good. Maybe someone someday will need something like this as a start for his own max factorial programm. First program will ask you to insert a random number and then it calculate its factorial (only in max int borders). Then it prints out all possible int factorials. Its show only 11! as max but the max is 12! I add factorial 12! manualy, becouse the if statment cannot print out excatly the number 12 as max it prints one before. And in the end the programm shows you what is maxium possible factorial for intiger.
#include <iostream>
#include<climits>//
#include <cmath>
using namespace std;
int main() {
int k, max,s;
unsigned int factorial = 1;
unsigned int factorial2 = 1;
unsigned uval=INT_MAX;
cout << "Ievadi koeficentu k: ";
cin >> k;
for(int i = 1; i<=k; ++i) {
factorial *= i;
}
cout << "Ievadita koeficenta " << k << " faktorials " << " = " <<factorial;
cout << "\nVisi iespejamie faktoriali no 1 - n: ";
for( s = 1; s<=uval; ++s) {
factorial2 *= s;
max=factorial2;
if( s <= uval / factorial2 ){
cout <<" \nkoeficenta " << s << " faktorials ir ==> " <<factorial2;
}
else {
break;
}
}
cout <<" \nkoeficenta " << s << " faktorials ir ==> " <<factorial2;
cout <<" \nMaksimalais faktorials ir skaitla " << s << " faktorials ==> " <<max;
return 0;
}
This is what the programm looks like!
![Programm][1]

Mysterious Stack Overflow

So I wrote a program that utilizes the euclid algorithm to find GCD's of 2 ints.
The user enters one int (n), then the program takes every possible integer combination between 8 and n, finds their respective GCD's (recursively), and prints which GCD calculations required the most modulus operations.
I got the program working, but I get a stack overflow at around n=50, and it needs to work to at least 3000.
I've reviewed my code for a while and cannot find the problem.
#include<iostream>
#include <math.h>
using namespace std;
int cost, gcd, greatestCost, n, beginningA, beginningB, finalA, finalB, finalGCD, iteration;
void findGCD(int num1, int num2, int startingCost) {
//findGCD
//finds GCD of every combination (a,b) from i to n
//prints those with the greatest number of modulus operations
int a = num1;
int b = num2;
cost = startingCost;
cost++;
if (b%a > 0) {
//cout << "gcd(" << b << "," << a << ") = ";
findGCD(b%a, a, cost);
}
else {
gcd = a;
if (cost > greatestCost) {
greatestCost = cost;
finalA = beginningA;
finalB = beginningB;
finalGCD = gcd;
}
//cout << "gcd(" << b << "," << a << ") = " << gcd << " With a cost of: " << cost << endl;
//do next iteration (2,8), (3,8) etc...
if (++beginningA <= beginningB) { //beginning A goes from 1-i first
findGCD(beginningA, beginningB, 0);
}
else {
if (beginningA <= n) { //begin next cycle with new b value (1,9), (2,9) while b <= n
beginningA = 1; //reset to 1 so it will increment from 1-i again
cout << "At i=" << iteration++ << "; gcd(" << finalA << "," << finalB << ") = " << finalGCD <<
" took " << greatestCost << " modulus operations" << endl;
findGCD(beginningA, ++beginningB, 0);
}
else //When it tries to continue iterating with a number > n
//print the last, most intensive, iteration and stop
cout << "At i=" << iteration++ << "; gcd(" << finalA << "," << finalB << ") = " << finalGCD <<
" took " << greatestCost << " modulus operations" << endl;
}
}
}
int main() {
greatestCost = 0; //cost of the iteration with the most modulus operations
beginningA = 1;
beginningB = 8;
iteration = 8;
cout << "Enter an integer greater than 8 " << endl; //receive n from user
cin >> n;
if (n <= beginningB) //begin GCD search, granted user input > 8
cout << "Error!!! integer must be greater than 8";
else
findGCD(beginningA, beginningB, 0); //algorithm begins at (1,8)
return 0;
}
At this point the only thing I can think of as the problem is something I've done in C++ that I shouldn't (I am new to C++ and transferred over from java)
Sample Output
Things I've tried:
splitting the gcd function into 2
passing only references through the functions
First of all your explanation is unclear, from you code I understood that for every 8<=i<=n you take all possible x, y where y<=i and x<=y and calculate which gcd require most steps.
I've rewritten your code so that findGCD only finds gcd of 2 number, while incrementing some global cost variable.
#include<iostream>
#include <math.h>
using namespace std;
int cost, gcd, greatestCost, n, beginningA, beginningB, finalA, finalB, finalGCD, iteration;
int findGCD(int a, int b) {
cost++;
if (b%a > 0)
return findGCD(b%a, a);
else
return a;
}
int main() {
greatestCost = 0; //cost of the iteration with the most modulus operations
beginningA = 1;
beginningB = 8;
iteration = 8;
cout << "Enter an integer greater than 8 " << endl; //receive n from user
cin >> n;
if (n <= beginningB) //begin GCD search, granted user input > 8
cout << "Error!!! integer must be greater than 8";
else {
for ( int i = beginningB; i <= n; i++ ) {
int greatestCost = 0, gcd0 = 1, i0 = 0, j0 = 0;
for ( int t = beginningB; t <= i; t++ )
for ( int j = 1; j <= t; j++ ) {
cost = 0;
int gcd = findGCD(j, t);
if ( cost > greatestCost ) {
greatestCost = cost;
gcd0 = gcd;
i0 = t;
j0 = j;
}
}
cout << "At i=" << i << "; gcd(" << j0 << "," << i0 << ") = " << gcd0 <<
" took " << greatestCost << " modulus operations" << endl;
}
}
return 0;
}
The stack overflow you're getting is caused by using too deeply recursive calls: Every time you call a function a new stack frame (holding local variables, parameters and possibly other stuff) is created in the (call) stack. This frame is freed only when returning (normally or via exception) from the function. But with recursive calls you don't return from the first function call before returning from the second, which in turn only returns after the third and so on. Thus stack frames are piling up on the stack, which is commonly about the size of around 8 kB, until all available memory for the stack is used: That's the stack overflow (you put too much on it, thus it overflows).
This can be solved by using iteration (using loops) instead:
An outer one incrementing from 8 up to the user supplied maximum, as well as an inner one incrementing from 0 to the value of the outer loop's current iteration variable. This gives you all the pairs of values you want to operate on.
Calculating the greatest common divisor and its cost should be factored out into a function.
The only thing left is calling that function from within the loops and some how keeping track of the maximum.
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
unsigned gcd(unsigned a, unsigned b, unsigned * const cost) {
if (cost) {
*cost = 0;
}
while (b != 0) {
auto const rest = a % b;
if (cost) {
++(*cost);
}
a = b;
b = rest;
}
return a;
}
int main() {
unsigned const n = 3500;
unsigned greatestCost = 0;
vector<pair<unsigned, unsigned>> pairs;
for (unsigned b = 8; b <= n; ++b) {
for (unsigned a = 0; a <= b; ++a) {
unsigned cost;
gcd(a, b, &cost);
if (cost == greatestCost) {
pairs.emplace_back(a, b);
} else if (cost > greatestCost) {
pairs.clear();
pairs.emplace_back(a, b);
greatestCost = cost;
}
}
}
cout << "Greatest cost is " << greatestCost << " when calculating the GCD of " << endl;
for (auto const & p : pairs) {
cout << "(" << p.first << ", " << p.second << ")" << endl;
}
return 0;
}
(Live)
Note in particular that I'm not using any global variable.
The above might make you feel that recursion is an unusable, useless construct. This is not the case. Many algorithms are most cleanly expressed using recursion. When putting the recursive call as the last statement, then an optimisation known as tail call optimisation can be used: Then the called function is reusing the stack frame of the calling function, thus not using any more memory.
Unfortunately this optimisation is quite tricky to implement in a language like C++ due to various reasons.
Other languages, mostly functional ones, use it and thus also recursion instead of loops, though. An example of such a language is Scheme, which even requires implementations to be able to make that aforementioned optimisation.
As a final note: You could implement the GCD calculation using recursive calls here, since as you see the maximum depth will be 17 + 1 which should be small enough to fit on any (outside of embedded systems) call stack. I'd still go with the iterative version though: It has better performance, better fits the idiom of the language and is the "safer" way to go.