This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Hi guys I am working on a program to give the sum of all prime numbers under two million. Here's what I have... and I know this method works for finding prime numbers because I have used it before... however when I run this program I keep getting an infinite loop and no output.... any help would be greatly appreciated!
#include <iostream>
using namespace std;
int main (int argc, char * const argv[]) {
bool isPrime=true;
int i = 2;
int sum = 0;
do{
for ( int j = 2; j < i; j++)
{
if ( i % j == 0 )
{
isPrime=false;
break;
}
}
if (isPrime)
{
cout << "Prime: " << i << endl;
sum += i; // add prime number to sum
}
i++;
}while(i < 2000000);
cout << "the sum of all the primes below two million is: " << sum << endl;
getchar();
return 0;
}
The only logical error I can find is that you never re-set isPrime to true inside the loop, but that shouldn't cause an infinite loop, just wrong results.
I doubt it goes in an infinite loop though, I just think it takes a long time because it's sub-optimal. You don't need to check every number until i, sqrt(i) or even i/2 would do it.
Even better, you can generate a sieve of primes (google this) and then just add them up - this will be wildly more efficient.
I don't think you have an infinite loop. You forget to set isPrime to true, as Luchian Grigore noted, but your code will also take an awfully long time to run. Notice that you can stop doing trial division once j*j > i.
If you are also concerned about making things more efficient with minimum effort -- to get the primes you only need to check numbers of the form (6n + 1) and (6n + 5)
So including something like in your main loop :
int p6 = p % 6;
if (p6 == 1) {
result = isPrime(p);
p += 4;
} else if (p6 == 5) {
result = isPrime(p):
p += 2;
}
Will speed you up by a multiple. Don't forget the corner cases 2 and 3 though.
Related
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm working on a C++ program that determines and prints the prime numbers between 3 and an integer 'x' the user inputs. I'm assuming that I need a double nested loop for this, one to iterate from 3 to x and the other to check if the number is prime. I think it needs to do something like go from 2 to x-1? I'm just really not sure how to do this syntax-wise. Thanks for any help! :)
EDIT:
This is what I have:
#include <iostream>
#include <cmath>
using std::cout;
using std::endl;
using std::cin;
int main(){
int x;
int i;
int j;
cout << "Please enter an integer 'x' greater than 3: " << endl;
cin >> x;
if (x <= 3){
cout << "Please enter new value 'x' greater than 3: " << endl;
cin >> x;
}
for(int i=3; i<=x; i++){
for(j=2; j<i; j++){
if(i%j == 0)
break;
else if(i == j+1);
cout << i << endl;
}
}
return 0;
}
And I when I enter 10 as 'x' I get the output:
3
5
5
5
7
7
7
7
7
9
Can anyone tell me how to fix this?
Provided your X is small enough, you can use the Sieve of Eratosthenes to do it more efficiently. This is ideal for the "primes up to X" case since it maintains a memory of previously discarded primes. It does so by keeping a set of flags for each candidate number, all initially set to true (except for 1, of course).
Then you take the first true value (2), output that as a prime, and then set the flags for all multiples of that to false.
Then carry on with:
3;
5 (since 4 was a multiple of 2);
7 (since 6 was a multiple of 2 and 3);
11 (since 8 and 10 were multiples of 2 and 9 was a multiple of 3);
13 (since 12 was a multiple of 2);
17 (since 14 and 16 were multiples of 2 and 15 was a multiple of 3 and 5);
and so on.
Pseudo-code would be similar to:
def showPrimesUpTo (num):
// create array of all true values
array isPrime[2..num] = true
// start with 2 and go until finished
currNum = 2
while currNum <= num:
// if prime, output it
if isPrime[currNum]:
output currNum
// also flag all multiples as nonprime
clearNum = currNum * 2
while clearNum <= num:
isprime[clearNum] = false
clearNum = clearNum + currNum
// advance to next candidate
currNum = currNum + 1
Otherwise, you can do trial division as per your suggestion. The basic idea is to check each number from 2 up to the square root of your target number to see if it's a multiple. In pseudo-code, that would be something like:
def isPrime (num):
// val is the value to check for factor
val = 2
// only need to check so far
while val * val <= num:
// check if an exact multiple
if int (num / val) * val == num:
return false
// no, carry on
val = val + 1
// if no factors found, it is a prime
return true
The reason you only need to check up to the square root is because, if you find a factor above there, you would have already found the corresponding factor below the square root.
For example, 3 x 17 is 51. If you're checking the numbers from 2 through 50 to see if 51 is prime, you'll find 3 first, meaning you never need to check 17.
int main (char argv)
{
int tempNum = atoi(argv);
for (int i=3; i<=tempNum; i++)
for (int j=2; j*j<=i; j++)
{
if (i % j == 0)
break;
else if (j+1 > sqrt(i)) {
cout << i << " ";
}
}
return 0;
}
Printing prime numbers from 1 through 100
Basically this, but modified
I find this one pretty fast and efficient
int main(){
for(int i=3; i<=X; i++)
if(IsPrime(i)){
cout<<i<<endl;
}
}
bool IsPrime(int num){
/* use commented part if want from 2
if(num<=1)
return false;
if(num==2)
return true;
*/
if(num%2==0)
return false;
int sRoot = sqrt(num*1.0);
for(int i=3; i<=sRoot; i+=2)
{
if(num%i==0)
return false;
}
return true;
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am new to programming and found this exercise on a website. I tried completing it and this is how far i have got.
can someone please tell me if i am on the right direction, if not, what is wrong?
Also please explain any code you write.
"Write a program that prints the numbers from 1 to 100. But for multiples of three print Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".
for (int i = 0; i < 100;i++ ){
while (i * 3 ){
cout << "Fizz"<<endl;
while (i * 5){
cout <<"Buzz"<<endl;
while ( 1 * 3 && 1*5){
cout <<"FizzBuzz"<<endl;
}
}
You're approaching things wrong. Why do you need the while (i*3)? Do you know what a while does? Is that supposed to check the remainder?
Hint - use conditionals (if) and the % operator to check the remainder.
No full code for you! Learn to debug! (this is the best thing you can do at this stage)
Replace
while (i * 3 ) {
with
if (i % 3 == 0) {
etc.
To test for divisibility test for remainder of 0 with %
whiles should be ifs
For loop will print 0 to 99
Try something like this:
for (int i=1; i <= 100; i++) {
if ((i%3 != 0) && (i%5 != 0)) {
cout << i;
}
else
{
if (i%3 == 0) {
cout << "Fizz";
}
if (i%5 == 0) {
cout << "Buzz";
}
}
cout << endl;
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
#include <iostream>
using namespace std;
int checkIfPrime(int num) {
for (int i = 1; i < num; i++) {
int result = num / i;
if (num == result * i) {
return 0;
}
}
}
int main() {
int i = 3;
while(1) {
int c = checkIfPrime(i);
if (c != 0) {
cout << c << "\n";
}
i = i + 2;
}
}
Sorry about posting the wrong code!
When I run this, nothing happens.. Can someone tell me what I am doing wrong?
After the question has completely changed its meaning:
Your CheckIfPrime is just wrong. You're checking divisibility in a very strange way. The general way to check whether a is divisible by b is if(a % b == 0)
That said, your error is that your loop starts with 1. Of course every number is divisible by 1, therefore by your logic, no number is prime. Start with for(int i = 2; .... (Depending on whether you want to consider 1 as prime or not, you might want to test specially for num == 1 initially.)
Also, the end condition is very inefficient. It is enough to check before the square root of num, that is i <= sqrt(num), but since sqrt is a rather slow and imprecise operation, MUCH better is to loop this way:
for(int i = 2; i * i < = num; ++i)
Another note - to generate all prime numbers from 1 to some MAX_VAL, your approach is very inefficient. Use the Sieve of Erastothenes.
Some stylistic note: your function should ideally return bool rather than int, and don't forget to return true or 1 after the loop has finished without returning.
Original Answer:
First of all, you need
fprintf(OUTPUT_FILE, "%d", Num); //d instead of s, no & before Num
instead of
fprintf(OUTPUT_FILE, "%s", &Num);
Second, you use the file I/O extremely inefficiently. Why do you open and close the file for every number? You should open it once, write all numbers, and then close it.
And thirdly, your algorithm doesn't seem to have anything to do with prime numbers... :)
By the way, since the first issue results in Undefined Behavior, you can't complain about any behavior of the program, since it's... well, undefined.
You aren't error checking any of your FileIO - wonder if something's going wrong there. A few ifs could help sort that out. Beyond that, all I see is an app that will fill your HDD real fast if it's working correctly.
The main reason why your prime generator isn't working, that i can see:
for (int i = 1; i < num; i++) {
int result = num / i;
if (num == result * i) {
return 0;
}
}
You start checking at 1. Since every number / 1 == itself, and every number * 1 == itself, the condition will always be true on the first run; that is, your prime test will always return false. Start at 2 instead.
Once you fix that, you should also make it so that the test returns true if it manages to get all the way through the loop. (Inserting a return 1; after the loop should be enough.)
(BTW, if you care the least bit about efficiency, if ((num & 1) == 0) return 0; for (int i = 3; i * i <= num; i += 2) would be better. But better still would be a sieve of some sort, as mentioned elsewhere.)
int checkIfPrime(int num) {
for (int i = 1; i < num; i++) {
int result = num / i;
if (num == result * i) {
return 0;
}
}
}
Missing return 1 at the end of the loop
The initial value of i must not be 1. Walk through the first iteration with a pencil and paper and see what happens.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
The following is my simple attempt at generating Armstrong numbers. But it only outputs "1". What might be wrong?
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
int main()
{
clrscr();
int r;
long int num = 0, i, sum = 0, temp;
cout << "Enter the maximum limit to generate Armstrong number ";
cin >> num;
cout << "Following armstrong numbers are found from 1 to " << num << "\t \n";
for(i=1;i<=num;i++)
{
temp = i;
while( temp != 0 )
{
r = temp%10;
sum = sum + r*r*r;
temp = temp / 10;
}
if ( i == sum ) {
cout << i;
sum = 0;
}
}
getch();
return 0;
}
You need to always set sum = 0 inside the for-i-loop.
Armstrong numbers: n-digit numbers equal to sum of n-th powers of their digits.
From your code
sum = sum + r*r*r;
'r*r*r' isn't n'th power of the number.
The first thing is that you're assuming that n (as in the nth power) is always three (in your r*r*r). That's only true if your initial value has three digits (as with the 153 example).
You need to count the digits in your initial number to calculate n, and then replace your r*r*r with raising r to the nth power.
This doesn't explain why 153 isn't found, though. The reason for that is because you aren't reseting sum to zero unless you find a match. You need to reset it to zero whether you found a match or not.
you can calculate n using log:
n = log(i)+1
then calculate r^n correctly and use it in your summation: sum += r^n;. r*r*r is not the correct way of calculating it.
Your code only works with n=3 : sum = sum + r*r*r;
You must use the pow() function (http://www.codecogs.com/reference/c/math.h/pow.php) to compute powers. (Or create a custom one.)
To summarize the right, but partial answers:
// #include <math.h>
for (long int i = 1; i <= num; i++)
{
long int n = 0, sum = 0; // <--- here
long ing temp = i;
while ( temp != 0 )
{
++n;
temp /= 10;
}
temp = i;
while ( temp != 0 )
{
int r = temp%10;
sum += int(pow(double(r), n)); // <-- here
temp /= 10;
}
if ( i == sum )
{
cout << i;
sum = 0;
}
}
#Power-inside, I saw your code, its difficult to change your code and edit it, but I have written a similar code to generate Armstrong numbers in a given limit, and it works fine.
Here it is....
#include<iostream.h>
#include<conio.h>
class arm
{
int a;
public:
void display();
};
void arm::display()
{
cout<<"Enter any number to find armstrong numbers less than it";
cin>>a;
for(int i=a;i>=1;i--)
{
int d=i;
int b=i;
int c=i;
int count=0;
while(b!=0)
{
b=b/10;
count++;
}
int l,m;
m=0;
for(int k=1;k<=count;k++)
{
l=c%10;
c=c/10;
m=m+l*l*l;
}
if(d==m)
cout<<d<<"\t";
}
}
void main()
{
arm k;
k.display();
getch();
}
I'm working on Euler Problem 14:
http://projecteuler.net/index.php?section=problems&id=14
I figured the best way would be to create a vector of numbers that kept track of how big the series was for that number... for example from 5 there are 6 steps to 1, so if ever reach the number 5 in a series, I know I have 6 steps to go and I have no need to calculate those steps. With this idea I coded up the following:
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main()
{
vector<int> sizes(1);
sizes.push_back(1);
sizes.push_back(2);
int series, largest = 0, j;
for (int i = 3; i <= 1000000; i++)
{
series = 0;
j = i;
while (j > (sizes.size()-1))
{
if (j%2)
{
j=(3*j+1)/2;
series+=2;
}
else
{
j=j/2;
series++;
}
}
series+=sizes[j];
sizes.push_back(series);
if (series>largest)
largest=series;
cout << setw(7) << right << i << "::" << setw(5) << right << series << endl;
}
cout << largest << endl;
return 0;
}
It seems to work relatively well for smaller numbers but this specific program stalls at the number 113382. Can anyone explain to me how I would go about figuring out why it freezes at this number?
Is there some way I could modify my algorithim to be better? I realize that I am creating duplicates with the current way I'm doing it:
for example, the series of 3 is 3,10,5,16,8,4,2,1. So I already figured out the sizes for 10,5,16,8,4,2,1 but I will duplicate those solutions later.
Thanks for your help!
Have you ruled out integer overflow? Can you guarantee that the result of (3*j+1)/2 will always fit into an int?
Does the result change if you switch to a larger data type?
EDIT: The last forum post at http://forums.sun.com/thread.jspa?threadID=5427293 seems to confirm this. I found this by googling for 113382 3n+1.
I think you are severely overcomplicating things. Why are you even using vectors for this?
Your problem, I think, is overflow. Use unsigned ints everywhere.
Here's a working code that's much simpler and that works (it doesn't work with signed ints however).
int main()
{
unsigned int maxTerms = 0;
unsigned int longest = 0;
for (unsigned int i = 3; i <= 1000000; ++i)
{
unsigned int tempTerms = 1;
unsigned int j = i;
while (j != 1)
{
++tempTerms;
if (tempTerms > maxTerms)
{
maxTerms = tempTerms;
longest = i;
}
if (j % 2 == 0)
{
j /= 2;
}
else
{
j = 3*j + 1;
}
}
}
printf("%d %d\n", maxTerms, longest);
return 0;
}
Optimize from there if you really want to.
When i = 113383, your j overflows and becomes negative (thus never exiting the "while" loop).
I had to use "unsigned long int" for this problem.
The problem is overflow. Just because the sequence starts below 1 million does not mean that it cannot go above 1 million later. In this particular case, it overflows and goes negative resulting in your code going into an infinite loop. I changed your code to use "long long" and this makes it work.
But how did I find this out? I compiled your code and then ran it in a debugger. I paused the program execution while it was in the loop and inspected the variables. There I found that j was negative. That pretty much told me all I needed to know. To be sure, I added a cout << j; as well as an assert(j > 0) and confirmed that j was overflowing.
I would try using a large array rather than a vector, then you will be able to avoid those duplicates you mention as for every number you calculate you can check if it's in the array, and if not, add it. It's probably actually more memory efficient that way too. Also, you might want to try using unsigned long as it's not clear at first glance how large these numbers will get.
i stored the length of the chain for every number in an array.. and during brute force whenever i got a number less than that being evaluated for, i just added the chain length for that lower number and broke out of the loop.
For example, i already know the Collatz sequence for 10 is 7 lengths long.
now when i'm evaluating for 13, i get 40, then 20, then 10.. which i have already evaluated. so the total count is 3 + 7.
the result on my machine (for upto 1 million) was 0.2 secs. with pure brute force that was 5 seconds.