c language, multiples of 5 being saved on a prime vector - c

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)

Related

How to print decreasing odd numbers starting from scanf input integer in C?

If you input even numbers, only the odd numbers will be printed until it reaches 0. (0 will not be printed). For example, if you input 10, the output would be 9, 7, 5, 3, 1.
This is what I came up with. I'm wondering what should I decrement x by to get the desired output.
int x;
scanf("%d", &x);
while (x >= 0) {
printf("%d", x);
x = x - 2;
}
I'm wondering what should I decrement x by to get the desired output.
Subtracting 2 is fine, as long as you always start from an odd number. So you could change the loop into something like this:
for ( int i = x % 2 ? x : x - 1; // Is x odd? good.
// Otherwise, start from the previous one.
i > 0;
i -= 2 ) {
printf("%d\n", i);
}
int x, n;
printf("Give N: ");
scanf("%d", &n);
printf("odd numbers from 1 to %d are: \n", n);
x=n;
while(x<=n && x>0)
{
if(x%2!=0)
{
printf("%d\n", x);
}
x--;
}
return 0;
}
Your code was almost correct (indeed, it is a pity that you have selected as the correct question such a bad response) I will show you where is your error:
int x;
scanf("%d", &x);
if (x % 2 == 0) /* if the number is even */
x = x - 1; /* decrement it to convert it in an odd number */
while (x >= 0) {
printf("%d", x);
x = x - 2;
}
The thing is that you start your question with exactly that assert (if you input even numbers...)
Another problem is that you don't say what should happen when you introduce an odd number. Anyway, the code printed it, and all the odd numbers until we reach 0.
Why your code is better than the selected one? because your code only wastes time in the loop with the valid results, and doesn't get into the loop to decide that it has nothing to do. This saves a lot of loop executions (almost half of them) which, if your number is very large, can do your program a lot more efficient.

Why does this prime number algorithm work?

#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

Determine Prime Numbers using SINGLE do-while Loop

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.

How do I fill up the array with the first 10 prime numbers?

This is probably a really simple problem to solve but for for some reason I just can't think of the correct solution!
We have a function int isPrime(int n) which returns a 2 if n is prime, a -1 if n is not positive and a 0 if n isn't prime. (We don't have to write any code for this function, we just assume that the code is already written so all we have to do is call this function). Using this function, we have to write a code fragment that fills up an integer array of size 10 with the first ten prime numbers. NOTE: Treat 1 as a non-prime number.
I've attempted a solution below but I don't think it's right:
NOTE: We just have to write a code fragment!
int a[10];
int n, i, result;
result = isPrime(n);
for (i = 0; i < 10; i++) {
if (result == 1) {
a[i] = n;
}
}
I have a feeling that I will have to use two for loops, one to cycle through the numbers being checked with isPrime and another one to loop through the positions in the array as I have above. But I'm not sure how it would look if I had two for loops. Any help is appreciated! Thanks ahead of time.
Try something like this. It will repeatedly find the next prime until you have found 10 of them.
Note: Since you did not provide an implementation of isPrime, this code is not tested. It is only meant to give you an idea of what it should look like.
int a[10];
int n, i, result;
n = 2;
for (i = 0; i < 10; i++) {
// Keep bumping n until we find a prime.
while (!(isPrime(n) == 2)) {
n++;
}
// Record the prime we just found.
a[i] = n;
// Ensure that we do not just record the same prime n times.
n++;
}
Start by having zero primes. While you don't have 10 of them, see if the next number is prime; if it is, add it to the next spot in the array if it is (and now you have one more prime).
(This straightforwardly translates into code. You need one loop, but two different counters: number of found primes, and number you're testing next)
An implementation of Amaden's algorithm:
int a[10];
for (int n = 1, nprimes = 0;;)
if (isPrime(++n) == 2) {
a[nprimes++] = n;
if (nprimes == 10)
break;
}

Find largest digit in decimal number

I'm trying to make a C function which will ask the user to enter in a number (44634329) and will scanf the number, save it to a variable , and will go through digit by digit, and figure out the largest number.
http://pastebin.com/tF7PVtvg - this is my project so far
void extractLargestDigit() {
int i;
i = 0;
int v;
v = 0;
int x;
x = 0;
printf("Enter an integer : ");
scanf("%d", &x);
i = x % 10;
x = x / 10 % 10;
if(i >= x) { i = i; x = x / 10 % 10;}
if(x >= i) { i = x; x = x / 10 % 10;}
if(x = 0) { i = i;}
Right here is where I'm trying to make the program loop so that it will continue to cycle through until x is equal to 0. I'm hoping that this will make i be the largest value in the number and will display it as such. I also have to display at what point the largest digit occurs , like in the number 542356976 , the right most 6 is in the 1st digit position, and the 9 is in the 3rd digit position, I need to display where the largest digit occurs in the number and have not quite figured that out
printf("\nThe largest digit : %d\n", i);
printf("\nIts position : );
return;
}
Any help or insight would be awesome
Why does the input necessarily have to be treated as an integer? You may consider treating the input as a string instead. Then, each digit is a char in an array of ascii characters, making it very easy to loop through the digits.
By looking at an ascii table, you'll notice the numerical values of the ascii digits 0-9 are in ascending order, which means comparing them for which is the largest is quite easy.
I would do it in a different way:
void extractLargestDigit() {
printf("Enter an integer : ");
scanf("%d", &x);
int max = -1; // so it will always be less than any first digit
while (x >0){
int digit = X %10; //grab last digit
x = x / 10; //throw last digit away
if (max < digit) //if this digit is grater than current max...
max = digit; //... update it!
}
return max;
}
This way, you loop through each digit in turn, and the greatest on will be in max varible.
So you want to use a loop then.
do {
// grab input, process...
} while( x != 0 );
Also...
if(x = 0)
That is an assignment, i.e., x will always equal zero when that executes and the if block will never be entered. If you want to check equality, use ==.
if(x == 0)
You need a loop. Something like this:
while (x != 0)
{
// ...
x /= 10;
}
In the loop, check the current last digit (which is x % 10), and track the maximum.
You want something like:
while(x>0)
{
i=x%10;
x/=10;
// here check to see if 'i' is the biggest so far
}
Also, don't use variables with single-letter names. It's easy to forget what they are. (In fact, I can't tell in your code which variable is supposed to track the largest digit found so far.)
Your code is a little bit hard to read as it is formatted now. Try this (your professor will thank you) as I think it will help you better understand what you have to do. I have given you a hint on what you might need to do next as well.
void extractLargestDigit() {
int i = 0; /* You can declare and initialise at the same time, by the way */
int v = 0;
int x = 0;
printf("Enter an integer : ");
You want to keep doing everything between this and the end of the function until the user enters a zero. You need a loop construct; C provides a few. Read up on do...while, for and while loops and you will find something that meets your needs.
scanf("%d", &x);
i = x % 10;
x = x / 10 % 10;
if(i >= x) {
i = i;
x = x / 10 % 10;
}
if(x >= i) {
i = x;
x = x / 10 % 10;
}
if(x = 0) { /* Something's not right here */
i = i;
}
}

Resources