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.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
You are given a number, at a time either you can increase a number by 1 or decrease by 1 it is considered as one move find the minimum number of moves required to convert a given into a lucky number. A number is called lucky if all the digits in it are even.
I have writtern the code but I am not sure if it is correct. Can anybody please confirm me?
#include<bits/stdc++.h>
using namespace std;
int count(int n)
{
int count = 0;
while (n != 0)
{
n = n / 10;
++count;
}
return count;
}
int firstDigit(int n)
{
// Remove last digit from number
// till only one digit is left
while (n >= 10)
n /= 10;
// return the first digit
return n;
}
int main()
{
int n;
cin >> n;
int i,j,ans=0;
int x = count(n);
while(x--)
{
if(firstDigit(n)%2 != 0)
{
if(firstDigit(n) == 9)
{
ans = ans + pow(10,x);
n = n-pow(10,x);
}
else
{
ans = ans + pow(10,x);
n = n + pow(10,x);
}
}
else
n = n - pow(10,x);
}
cout << ans << endl;
}
Edit:
I found it is giving wrong answer at 100. Can you please help me in finding out the mistake
Not all code can easily be tested, thats why you should strive to write testable code right from the start (instead of first writing it all and then try to confirm correctness). In your case testability could benefit a lot from moving most logic from main into a dedicated function:
int minimal_steps(int input) {
....
}
Once you have that, you can either call it in main with user supplied input just as you do it now, but you can also write tests more easily:
void test() {
assert( minimal_steps(2222) == 0);
assert( minimal_steps(2221) == 1);
...etc...
}
Once you got into the habit of testing your code (you should also write tests for count and firstDigit) you may consider to use a testing framework to automate tests.
PS: It isnt wrong, but it is such a waste of CPU cycles that it is worth mentioning (actually it was already mentioned in a comment). You do not need to compute pow(10,x) in a loop where x is the loop counter. Consider that you are computing 10^2 almost as many times as the loop has iterations. Also 10^3 is the same in every iteration. Instead you should only update with *10 (in case x is incremented) or /10 when x decrements between iterations. Moreover, pow is for floating-points, not for integers.
I am fairly new to c++ and I want to learn how to optimize the speed of my programs. I am currently working on a program that computes the perfect numbers from 1 to 1.000.000. A perfect number is where the sum of its proper divisors is equal to the number itself. Eg. 28 is a perfect number because 1+2+4+7+14=28. Below is my code
#include <iostream>
using namespace std;
int main() {
int a = 1000000;
for(int i = 1; i <= a; ++i)
{
int sum = 0;
int q;
// The biggest proper divisor is half the number itself
if(i % 2 == 0) q = i/2;
else q = (i+1)/2;
for(int j = 1; j <= q; ++j)
{
if(i % j == 0) sum += j;
}
//Condition for perfect number
if(sum == i) cout << i << " is a perfect number!" << endl;
}
system("pause");
return 0;
}
What operations in this code are time consuming? How can I improve the speed of the program? In general, how do I learn about what operations that are time consuming and how to avoid them?
The only way to really know what operations are time consuming and are limiting the execution speed of your program is to run the program through a profiler. This tool will tell you where each second of the execution time was spent (on a function call basis, usually).
To answer your question specifically: the most time in this program will be spent at this line:
system("pause");
because, aside from the fact that this is a horrible line of code you should get rid of, is actually user input, and as we all know, the thing between the chair and the screen is what slows things down.
You may trade of computation by memory consumption with the following:
const int max = 1000000;
std::vector<std::size_t> a(max);
for(std::size_t i = 1; i != a.size(); ++i) {
for (std::size_t j = 2 * i; j < a.size(); j += i) {
a[j] += i;
}
}
for (std::size_t i = 1; i != a.size(); ++i) {
if(a[i] == i) {
std::cout << i << " is a perfect number!" << std::endl;
}
}
Live example
Branches: ifs, loops, function calls and goto are costly. They tend to distract the processor from perform data transfers and math operations.
For example, you can eliminate the if statement:
q = (i + (i % 2)) / 2; // This expression not simplified.
Research loop unrolling, although the compiler may perform this on higher optimization settings.
I/O operations are costly, especially using formatted I/O.
Try this:
if(sum == i)
{
static const char text[] = " is a perfect number!\n";
cout << i;
cout.write(text, sizeof(text) - 1); // Output as raw data.
}
Division and modulo operations are costly.
If you can divide by a power of 2, you can convert the division into a shift right.
You may be able to avoid modulo operations by using binary AND.
My rules of thumb:
conditional branches (i.e. comparisons) are costly
divisions are costly (as well as modulo %)
prefer integer operations over floating-point
How to avoid them ?
Well, there is no simple answer. In many cases you just can't.
You avoid conditional branches by using branchless expressions, or improving the program logics.
You avoid divisions by using shifts or lookup-tables or rewriting expressions (when possible).
You avoid floating-point by simulating fixed-point.
In the given example, you have to focus on the body of the innermost loop. That's the line that is the most frequently executed (about 125000000000 times vs 1000000 for others). Unfortunately, there is a comparison and a division, which are hard to remove.
Optimizations of other parts of the code will have no measurable effect. In particular, don't worry about the cout statement: it will be called 4 times in total.
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.
lets say you want to make a program that will print the numbers 1-9 over and over again
123456789123456789123456789
i guess the most obvious way to do it would be to use a loop
int number = 1;
while(true)
{
print(number);
number = number + 1;
if(number > 9)
number = 1;
}
before i go any further, is this the best way to do this or is there a more common way of doing this?
Will this do?
while(true)
{
print("123456789");
}
Everyone using the % operator so far seems to be under the impression that ten values are involved. They also overlook the fact that their logic will sometimes generate 0. One way to do what you want is:
int i = 1;
while (true) {
print(i);
i = (i % 9) + 1;
}
The most obvious way would be this:
for (;;)
{
for (int i = 1; i < 10; ++i)
{
print(i);
}
}
Why you'd want to optifuscate it is beyond me. Output is going to so overwhelm the computation that any kind of optimization is irrelevant.
First off, why are you trying to "optimize" this? Are you optimizing for speed? Space? Readability or maintainability?
A "shorter" way to do this would be like so:
for (int i = 1; true; i++)
{
print(i);
i = (i + 1) % 10;
}
All I did was:
Convert the while loop to a for
loop
Convert increment +
conditional to increment + mod
operation.
This really is a case of micro-optimization.
My answer is based off Mike's answer but with further optimization:
for (int i = 1; true; i++)
{
std::cout << ('0' + i);
i = (i + 1) % 10;
}
Printing a number is way more expansive then printing a char and addition.
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.