I wrote this program per my professor's instruction. Turns out he wanted us to use a SINGLE do-while loop. While I did technically do that... this won't fly. I can't figure out how to do it without using a for-loop or at least another loop of some other type. He said it could use continue or break statements--but that it might not be necessary.
I would appreciate not just re-writing my code--while this is handy, I don't learn from it well.
I appreciate any and all help.
int main() {
int max, x, n = 2; //init variables
//start n at 2 because 1 isn't prime ever
//asks user for max value
printf("Enter max number: ");
scanf("%i", &max);
/*prints prime numbers while the max value
is greater than the number being checked*/
do {
x = 0; //using x as a flag
for (int i = 2; i <= (n / 2); i++) {
if ((n % i) == 0) {
x = 1;
break;
}
}
if (x == 0) //if n is prime, print it!
printf("%i\n", n);
n++; //increase number to check for prime-ness
} while (n < max);
return 0;
}
This is definitely doable. The trick is to have a test variable, and each iteration through your while loop, check the test variable against your current number. Always start the test variable at 2 (every natural number > 0 is divisible by 1)
Cases to consider:
Our current number is divisible by the test variable -- number is NOT prime, increase the current number and reset the test variable.
Our test variable is greater than the square root of the current number. By definition, it CANNOT divide the current number, so the current number has to be prime (we have tried all numbers lower than the square root of the current number and none of them divide it). Increase the current number and reset the test variable.
Lastly, if either above case isn't true, we have to try the next number higher. Increment the test variable.
I have not provided the code as you asked to not have it re-written, but can provide if you would like.
EDIT
#include <stdio.h>
#include <math.h>
int main(void)
{
int max = 20;
int current = 4;
int checker = 2;
do{
if(checker > sqrt((double)current))
{
checker = 2;
printf("%d is prime\n",current);
current++;
}
else if(current % checker == 0)
{
checker = 2;
printf("%d is NOT prime\n",current);
current++;
}
else
checker++;
}while(current < max);
}
Output:
4 is NOT prime
5 is prime
6 is NOT prime
7 is prime
8 is NOT prime
9 is NOT prime
10 is NOT prime
11 is prime
12 is NOT prime
13 is prime
14 is NOT prime
15 is NOT prime
16 is NOT prime
17 is prime
18 is NOT prime
19 is prime
I won't give you the exact code, but two pointers that should help you:
First, a for loop can be written as a while loop (and, vice versa)
for (int i=0; i< 100; ++i)
...
would become:
int i=0;
while (i < 100)
{
...
++i;
}
Second, two nested loops can become a single one, in any number of ways:
for (int i=0; i< 100; ++i)
for (int j=0; j< 100; ++j)
...
Becomes
for (int z=0; z< 100*100; ++z)
{
i = z / 100;
j = z % 100;
}
The above shows two for loops, but you can perform similar transforms on other loops.
Think Eratosthenes sieve. In this method we strike composite numbers out of a table, so that in the end only primes remain. For simplicity, the table contains only odd numbers. You start pointing at 3, which is a prime. Strike out 3*3, 3*5... Finish your run over the table (it's finite), point at 5. It's not striked out, thus a prime. Strike out 15, 25... check 7, prime, strike 21, 35... check 9, already striked out, move on to 11...
Questions:
You have just checked a number, what is the next number to check?
How do you know you've ran out of numbers to check?
Write down answers to these questions, and you have a one-loop prime-finding algorithm.
Related
I'm a newbie and i'm currently making a program that asks the user a number and if the number is a prime it gets stored in a vector, if the vector isn't completed the code doesn't stop. The only problem is that it stores multiples of 5, like 15, 25, 35, etc in it. How can i make it stop storing these multiples of 5? Here is the code:
#include <stdio.h>
int main()
{
int primes[5], num, i, count = 0, x = 0;
do
{
printf ("Type a number: ");
scanf("%d", &num);
for (i = 1; i <= num; i++)
{
if (num % i == 0)
{
count++;
}
}
if (count = 2)
{
primes[x] = num;
x++;
}
}
while (x < 5);
for (x = 0; x < 5; x++)
{
printf("%d ", primes[x]);
}
}
= is the assignment operator, not the equality check operator. You should use == to check if the count is 2:
if (count = 2)
You write
for (i = 1; i<= num; i++)
a prime number is a number that is divisible only by one and itself, your primality test divides your number by all numbers (includind 1 and num itself) so every number (prime or not) will probe to be compound.
Your primality test must start at 2 and end at most at num - 1 to avoid dividing the number by one and by itself (all numbers are divisible by themselves and by one) as in
for (i = 2; i < num; i++)
this should solve your problem... but it will be very inefficient, as you are dividing by all the even numbers, and it is not necessary to divide it by all the even numbers (except for 2 itself) Also, you can stop at a number that is below or equal to sqrt(num), rounded down to the previous integer, because if the number has a factor above that number, for sure you have already found a factor below it (and both multiply pairwise to give you the number).
Also, there's a problem here:
if (count = 2)
This is a valid C statement, but it most probably don't do what you intend, as the = operator is the Assignment Operator, and not the logical equal operator (which is spelled ==) You need to change, because as shown, you are assigning count the value 2, and this is always true, by definition of the assignment operator, if you assign something different than zero, it will result in a true result, so your if will execute allways the body of its true part.
Anyway, many variables it's not clear what you are using them for, (count is one of these) as you assign, increment it, but you don't use its value anywhere (except the if statement above, and in a wrong way)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int anz;
scanf("%d", &anz);
time_t start = time(0);
int *primZ = malloc(anz * sizeof(int));
primZ[0] = 2;
int Num = 0;
for (int i = 1, num = 3; i < anz; num += 2) {
for (int j = 1; j < i; j++) {
if (num % primZ[j] == 0) {
num += 2;
j = 0;
}
//this part
if (primZ[j] > i / 2)
break;
}
primZ[i] = num;
i++;
printf("%d ,",num);
}
time_t delta = time(0) - start;
printf("%d", delta);
getchar();
getchar();
return 0;
}
The code works perfectly fine, the question is why. The part if(primZ[j] > i/2) makes the program 2 - 3 times faster. It was actually meant to be if(primZ[j] > num/3) which makes perfect sense because num can only be an odd number. But it is the number of found prime numbers. It makes no sense to me. Please explain.
You check if the prime is composite by checking if it divisible by already found prime numbers. But in doing so you only have to check up to and including the square root of the number because any number larger than that that divides the number will leave a smaller number than the square root of the number.
For example 33 is composite, but you only have to check numbers up to 5 to realize that, you don't need to check it being divisible by 11 because it leaves 3 (33/11=3) which we already checked.
This means that you could improve your algorithm by
for (int j = 1; j < i; j++) {
if( primZ[j]*primZ[j] > num )
break;
if (num % primZ[j] == 0) {
num += 2;
j = 0;
}
}
The reason you can get away with comparing with cutting of at i/2 is due to the distribution of the prime numbers. The prime counting function is approximately i = num/log(num) and then you get that i/2 > sqrt(num).
The reason is that the actual bound is much tighter than num/3 - you could use:
if (primZ[j] > sqrt(num))
The reason for that being that if a prime higher than the square root of num divides num, there must also be a lower prime that does (since the result of such a division must be lower than the square root).
This means that as long as i/2 is higher than sqrt(num), the code will work. What happens is that the number of primes lower than a number grows faster than the square root of that number, meaning that (completely accidentally) i/2 is a safe bound to use.
You can check out how your i value behaves here - they call it pi(x), the number of primes less than x.
It makes sense, since if n has two factors one of them is surely less than or equal to n/2, sense the program found no factors of i in primZ that are less than or equal to i/2 it means there's no factors of i -except 1 of course-.
Sense primZ is sorted in ascending order and j only increases, when primeZ[j] > i/2 it indicates that there's no factors of i in primZ that are less than i/2.
P.S.The point of starting the search is stated in the first part of the for statement num=3 , and the recurring statement num += 2 ensures you only test odd numbers
I'm trying to answer this question:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Here is my code:
#include <stdio.h>
int isPrime(long long num)
{
for (long long k = 1; k < num; k++)
{
if (num%k == 0)
return 0;
}
return 1;
}
long long num = 600851475143;
int main(void)
{
long long prime_factor = 0;
for (long long j = 2; j < num; j++)
{
if (num % j == 0 && isPrime(j) == 1)
prime_factor = j;
}
printf("%lli\n", prime_factor);
}
But for some reason it doesn't print anything, or even end. What is causing this?
That's a terribly inefficient way of finding the prime factors of a number.
To find the prime factors, you should:
Create a static list of primes less than or equal to (number / 2).
Iterate over each element in the list of primes and see if each
one can evenly divide the number.
Divide the original number by the prime, and check the last number
again.
Why? Well the smallest prime is 2. If the number isn't even then the first prime that can divide any number > 2 is 3.
Every number can be uniquely identified by its prime factors. This is called the Fundamental Theorem of Arithmetic. That means that there is only one way to represent e.g. 15 as a product of primes, in this case { 3, 5 }.
However any prime can divide a number more than once. For example, 49 is the product of two primes { 7, 7 }. Dividing the original number by one of its factors makes subsequent divisions quicker. And you can logically stop checking when the number == 1.
It doesn't print anything because it never leaves the loop, after which is found the only line which prints anything in the code. Try a smaller number and see if it ends.
Hi I'm currently in school for Computer science and I'm having problems with two of my codes, the first one pertains to the title. I have to create a program that takes only the odd digits of an input and sums them. I honestly have no idea how to approach this, this is all I have
Scanner in = new Scanner(System.in);
int a;
int b;
System.out.println("Enter a number: ");
a = in.nextInt();
while (a > 0) {
if (a.charAt(0) % 2 != 0) {
}
}
the second problem I have trouble with is write program with loops that computes the sum of all square between 1 and 100 (inclusive) This is the code i have
int i=1;
int j=0;
while (i<101){
i = (i * i);
j= (j+i);
i++;
}
System.out.println(j);
Thanks, I've been searching through this book back and forth and found no ideas.
I will not solve your home-work problem directly.
But it will give you an idea what to do
Sum of all Odd numbers in given numbers
int sum = 0;
while(numbers are still there){
if(presentNumber % 2 == 1){
sum += presentNumber;
}
}
and for second problem, if I understood correctly, Sum of Square Numbers which lies in 1 to 100
Logically, square root of 100 is 10. so all the square numbers which lies in 1 to 100 are 1 to 10 inclusive.
That's sum of squares of 1 to 10 numbers (1^2+2^2+3^2+...+10^2)
int sum = 0;
for(int I=0;i<=10;i++){
sum += (i*i);
}
There are multiple way to approach the first option(odd / even numbers):
if ( x & 1 == 0 ) { even... } else { odd... } //This is because the low bit will always be set on an odd number.
or you can do something like:
boolean isEven(double num) { return (num % 2 == 0) }
Check Check whether number is even or odd for more option.
Now about the squares check out Fastest way to determine if an integer's square root is an integer for your answer
like 17, is a prime, when reversed, 71 is also a prime.
We manage to arrive at this code but we cant finish it.
#include <stdio.h>
main()
{
int i = 10, j, c, sum, b, x, d, e, z, f, g;
printf("\nPrime numbers from 10 to 99 are the follwing:\n");
while (i <= 99)
{
c=0;
for (j = 1; j <= i; j++)
{
if (i % j == 0) c++;
}
if (c == 2)
{
b = i;
d = b / 10;
e = b - (10 * d);
x = (e * 10) + d;
{
z = 0;
f = x;
for (j = 1; j <= f; j++)
{
if (f % j == 0) z++;
}
if (z == 2)
{
printf("%d %d\n", i, f);
}
}
}
i++;
}
getch();
}
my problem is how to add all the fs..
the answer should be 429.
how can i add all the f?
Why don't you break up the code into some functions:
bool isPrime(int number) that checks if a number is prime.
int reverse(int number) that reverses the number.
Then the algorithm would be:
sum = 0;
for (i = 2; i <= 99; ++i)
if (isPrime(i) && isPrime(reverse(i)))
sum += i;
At the beginning initialize sum = 0;. Then, next to your printf count the prime: sum += i;. you can then print it at the end.
If this is a basic programming class and you are just interested in the result then this will get you there, however if it is an algorithms class then you may want to look at the Sieve of Eratosthenes.
You may also want to think about what makes a 2 digit number the reverse of another 2 digit number and how you would express that.
There are many problems in your code. None of them will prevent compilation and none of them will cause problems in getting the output. I'll first tell you how to get the result you want and then highlight the problems.
Here is your code, modified to sum fs. You just need to add f to sum every time you print a prime satisfying the condition. Finally, you should print the sum of all fs.
#include <stdio.h>
//Use int as the return type explicitly!
int main()
{
int i=10,j,c,sum,b,x,d,e,z,f,g;
printf("\nPrime numbers from 10 to 99 are the follwing:\n");
//Set the sum of all primes whose reverse are also primes to zero
sum = 0;
while(i<=99)
{
//c is tyhe number of factors.
c=0;
for(j=1;j<=i;j++)
{
if(i%j==0)
c++;
}
//If there are only two factors.
//Two factors (1 and itself) => Prime
if(c==2)
{
//Reverse i and store it in x
b=i;
d=b/10;
e=b-(10*d);
x=(e*10)+d;
//Curly braces unnecessary
{
//Check if the reverse i.e. x is prime
//z is the number of factors
z=0;
//f is the number being tested for primality.
f=x;
for(j=1;j<=f;j++)
{
if(f%j==0)
z++;
}
//If f i.e. x i.e. the reverse has only two factors
//Two factors (1 and itself) => Prime
if(z==2)
{
//print the prime number.
printf("%d %d \n",i,f);
//Add f to the sum
sum += f;
}//if(z==2)
}//Unnecessary braces
}//if(c==2)
i++;
}//end while
//print the number of reversed primes!!
//That is sum of the reversed values of numbers satisfying the
//condition!
printf("\nThe sum is:%d\n", sum);
//getch() is non standard and needs conio.h
//Use getchar() instead.
//Better solution needed!!
getchar();
//Return 0 - Success
return 0;
}
Output
...#...-desktop:~$ gcc -o temp temp.c
...#...-desktop:~$ ./temp
Prime numbers from 10 to 99 are the follwing:
11 11
13 31
17 71
31 13
37 73
71 17
73 37
79 97
97 79
The sum is:429
...#...desktop:~$
Do take note of all the comments made in the code (above). In addition, consider doing the following:
Removing the unnecessary braces.
Using one variable for one thing. (x could have been used instead of f).
Using better variable names like number and numberOfFactors.
Breaking up your code into functions as Mehrdad Afshari has suggested.
Consider testing primality by checking if there is a divisor of the number (num) being tested up to sqrt(num) (Square root of the number).
Consider this:
For numbers upto 99, the reversed numbers are also 2 digit numbers.
If the number is in the set of primes already found, you can verify easily.
This will reduce the number of checks for primality. (which are expensive)
To do the above, maintain a list of primes that have been identified (primeList)
as well as a list of reversed primes (revList). Any item in revList that is also
in primeList satisfies your condition. You can then easily obtain the sum (429)
that you need.
Look at sweet61's answer, the use of the Sieve of Eratosthenes with my method will definitely be much more efficient. You can reverse primes at the end of the sieve and populate the revList (at the end).
On a personal level, I try to find the best solution. I hope you will also attempt to do the same. I have tried to help you out without giving it all away.
I hope this helps.
Note
I had suggested checking for divisors up to num/2. I fixed it to sqrt(num) on vartec's suggestion.