OK so I got this challenge where I have to print all the primes from 1 to 100... However there is an error in my code that I am unable to find. Here is how I thought the problem should be done:
For any number from 3 to 100 check if there is any other number in the primes array that divides it. If there is the number is not prime. If there is not the number is prime and should be added to the array. Pretty simple, right ?
However it is not working.
Here is my code :
#include <stdio.h>
int main() {
int Primes[50] = {0};
int i, j, k;
Primes[0] = 2;
Primes[1] = 3;
for (i = 3; i < 101; i++) {
for (j = 2; j < 100; j++) {
if (i % Primes[j] != 0 && Primes[j] != 0) {
Primes[j] = i;
}
}
}
printf("Primes array : \n");
for (k = 0; k < 51; k++) {
printf("%d ", Primes[k]);
}
return 0;
}
instead of assuming the magic number as 25... that is k!=25, we can
replace it with i<=100.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int Primes[50] = {0};
int i,j,k = 0;
Primes[0]=2;
Primes[1]=3;
for(i=0; i<=100; i++) {
for(j = 2; j<=i; j++) {
if(i % j == 0 ){
if(i == j)
Primes[k++]=i;
break;
}
}
}
printf("Primes array : \n");
for(int index = 0;index < k; index++) {
printf("%d\n", Primes[index]);
}
return 0;
}
When you do this:
if(i % Primes[j] != 0 && Primes[j] !=0)
{
Primes[j]=i;
}
You're saying "if the current number is not divisible by the given prime number, replace the given prime number with the current number". This is not what you want.
You need to check if the current number is not divisible by any prime number. So you need to loop though the list of primes to make sure your number isn't divisible by any of them, and if so add the number to the end of the list. You can do that as follows:
int num_primes = 0;
for (i=2;i<101;i++)
{
int is_prime = 1;
for(j=0; j<num_primes && is_prime; j++)
{
if(i % Primes[j] == 0)
{
is_prime = 0;
}
}
if (is_prime) {
Primes[num_primes++] = i;
}
}
In the above code, we use num_primes to count the number of primes we have so far, and is_prime to see if we found a prime that divides the current number. As you divide each number by a prime, if the remainder is 0 you know the number is not prime and set is_prime to 0. This also causes the inner loop to exit right away. Then if is_prime is still set at the end of the inner loop, you have a prime and you add it to the end of the list.
You also have an off-by-one error in the printing loop:
for(k=0;k<51;k++)
Since Primes has size 50, the largest valid index is 49. So change it to:
for(k=0;k<50;k++)
There are lot of issues in the algorithm you used. Use this simple version with issues addressed in the code.
int main(void){
int Primes[50] = {0};
int i,j,k = 0 /* use for prime count purpose */;
Primes[0]=2;
Primes[1]=3;
for(i=4 /* 3 is already stored */; k != 48; i++) { /* rotate loop until prime count doesn't reaches 48 */
for(j = 2; j<=i; j++) { /* i is the number you want to check whether its prime or not. SO rotate loop from 2 to "i" */
if(i % j == 0){ /* use i%j not i % Primes[j] as you want to check whether i is prime or not */
if(i == j) /* if its a prime numbur j reaches upto i */
Primes[k++]=i; /* store it */
break; /* comes out of inner loop */
}
}
}
printf("Primes array : \n");
for(int index = 0;index < k; index++) { /* rotate k times not some random 51 times */
printf("%d ", Primes[index]);
}
return 0;
}
The code above doesn't actually give what we want, but beautiful code nonetheless. Here is the edited code that gives the prime numbers from 1 to 100
int main(void){
int Primes[50] = {0};
int i,j,k = 0 /* use for prime count purpose */;
Primes[0]=2;
Primes[1]=3;
for(i=0 /* 3 is already stored */; k != 25; i++) { /* rotate loop until prime count doesn't reaches 48 */
for(j = 2; j<=i; j++) { /* i is the number you want to check whether its prime or not. SO rotate loop from 2 to "i" */
if(i % j == 0){ /* use i%j not i % Primes[j] as you want to check whether i is prime or not */
if(i == j) /* if its a prime numbur j reaches upto i */
Primes[k++]=i; /* store it */
break; /* comes out of inner loop */
}
}
}
printf("Primes array : \n");
for(int index = 0;index < k; index++) { /* rotate k times not some random 51 times */
printf("%d\n", Primes[index]);
}
return 0;
}
Related
I have this code in which I need to find all prime numbers from 2 to 1000 and need to print them out in groups of 5 in each line. How can I do that?
#include <stdio.h>
int main() {
int i, a, count;
printf("Prime numbers between 2 and 1000 are : \n");
for (i = 2; i < 1000; i++) {
count = 0;
for (a = 1; a <= i; a++) {
if (i % a == 0)
count++;
}
if (count == 2)
printf("%d\t", i);
}
return 0;
}
You can add a new counter to count the number of prime numbers printed until the current loop. If this counter value is divisable by 5, print a new line.
int main()
{
int i,a,count;
printf("Prime numbers between 2 and 1000 are : \n");
int cnt_prime = 0; // count the number of prime numbers until this loop
for (i=2;i<1000;i++)
{
count=0;
for (a=1;a<=i;a++)
{
if (i%a==0)
count++;
}
if (count==2) {
printf("%d\t", i);
cnt_prime++;
if (cnt_prime % 5 == 0) // print new line after each five numbers
printf("\n");
}
}
return 0;
}
There is another faster approach to find the prime numbers in a range. You can read about sieve of eratosthenes from here: https://www.geeksforgeeks.org/sieve-of-eratosthenes/
Maybe not the best answer, but you could add another counter-variable called prime_count and initialize it with value 0. Then each time you print a prime, you increment that variable. After printing a prime you then check wether prime_count is equal to 4. If that's the case you print a newline-character and reset prime_counter to 0.
The code could look something like this:
int main()
{
int i,a,count,prime_count=0;
printf("Prime numbers between 2 and 1000 are : \n");
for (i=2;i<1000;i++)
{
count=0;
for (a=1;a<=i;a++)
{
if (i%a==0)
count++;
}
if (count==2)
{
printf("%d\t",i);
prime_count++;
if (prime_count == 4)
{
printf("\n");
prime_count = 0;
}
}
}
return 0;
}
You can check till square root of N to verify prime no need to check till N it makes your code O(sqrt(n)) refer this for more info about the algorithm.You can have a variable called printCounter to check total elements printed on console when it become a multiple of 5 we can print a new line.
int main() {
int i, a, printCount = 0 ;
printf("Prime numbers between 2 and 1000 are : \n");
for (i = 2; i < 1000; i++) {
int isPrime = 1;
for (a = 2; a * a <= i; a++) {
if (i % a == 0){
isPrime = 0;
break;
}
}
if (isPrime == 1) {
printf("%d\t", i);
printCount++;
}
if(printCount%5 == 0){
printf("\n");
}
}
return 0;
}
How can i write a program that lists all sexy prime pairs that exist in n numbers.
For example if n = 10 the output should be (5, 11) and (7, 13)
My idea was to generate all primes within n and then add 6 to each and check if the i + 6 is a prime. But it doesnt work, there's no output and the program ends.
#include <stdio.h>
int main() {
int i, j, n, k, isprime = 1, prime2, flag = 0;
scanf("%d", &n);
for (i = 3; i <= n; i++){
for (j = 2; j <= i; j++){
if (i % j == 0)
break;
}
if (i == j){
prime2 = i + 6;
for (k = 3; k <= prime2; k++){
if (prime2 % k == 0){
flag++;
break;
}
}
if (flag == 0){
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Any ideas of what im doing wrong or any tips on how to solve it? (with loops only)
As there're a lot of resources about finding a prime number, I'm not going to discuss that. Rather I'll try to point out the bug in your code.
First problem:
for (k = 3; k <= prime2; k++)
Here you need to run the loop till prime2 - 1. Also you should start checking from 2 rather than 3, just like you did previously. That means,
for (k = 2; k < prime2; k++)
or
for (k = 2; k <= prime2 - 1; k++)
Reason: when k = prime2, prime2 % k will be 0. For finding out whether a number is prime we don't need to check if that number is divisible by 1 and that number itself.
Note: Now you might think why the first prime number loop for (j = 2; j <= i; j++) is working .
It's working because you've given an additional condition if (i == j) after it.
Second problem:
You need to declare the flag variable within the first loop.
for (i = 2; i <= n; i++)
{
int flag = 0;
.... (rest of the code)
....
}
Reason: Basically with the flag value, you're trying to find out whether prime2 is a prime number.
Every time you'll get a prime number from the first loop, you'll have a new value of prime2. In your code, once you're incrementing the value of flag, you're never resetting the flag value.
That's why once your code detects a prime2 which is not a prime, it'll never detect the second prime number again (prime2 which is actually prime).
Overall code:
#include <stdio.h>
int main()
{
int i, j, n, k, isprime = 1, prime2;
scanf("%d", &n);
for (i = 3; i <= n; i++)
{
int flag = 0; // changing point
for (j = 2; j <= i; j++)
{
if (i % j == 0)
break;
}
if (i == j)
{
prime2 = i + 6;
for (k = 2; k < prime2; k++) // changing point
{
if (prime2 % k == 0)
{
flag++;
break;
}
}
if (flag == 0)
{
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Few resources to know more about finding out prime numbers:
Prime Numbers
C Program to Check Whether a Number is Prime or not
Sieve of Eratosthenes
You can use Sieve to speed up the program. It can generate all pairs in O(N log N) time. Here's the Algorithm.
Now, you have a boolean array, is_prime where is_prime[i] is true if i is a prime, false otherwise.
Now, iterate from i = 1 to i = N and check if is_prime[i] && is_prime[i + 6], if the condition is true, output the pair.
I have the code below and it's annotated. It is essentially based on 'Sieve of Eratosthenes.' I am modifying it to have the remaining prime numbers printed and counted in the last for loop of the code. However, the output is '1There are 1 primes.'
#include <stdio.h>
#define SIZE 50000
int main(void) {
int i, mult, count, count2;
int flag[SIZE + 1];
count = 0;
count2 = 0;
//sets up all numbers
for (i = 1; i <= SIZE; i++) {
flag[i] = 1;
//printf("%d",flag[i]);
}
//step 1: selects the prime number
for (i = 2; i <= SIZE; ++i) {
if (flag[i] == 1)
++count;
mult = i;
//step 2: filters out numbers multiple of that prime number in step 1
while (mult <= SIZE) {
flag[mult] = 0;
mult = mult + i;
}
}
//Now that the non-prime numbers have been filtered, this then prints the number and counts the prime numbers
for (i = 1; i <= SIZE; i++) {
if (flag[i] == 1) {
++count2;
printf("%d", i);
}
}
printf("There are %d primes. \n", count2);
return 0;
}
In your second for loop, you start with:
mult = i;
and then in the while that is just after you set:
flag[mult] = 0;
In essence you say this number is not a prime.
If you replace the line mult = i with:
mult = i + i ;
Then your program is working.
I just started learning C and i would like to make a program that finds how many prime numbers are within 200 and 300, but i dont seem to get it right as my program seems not to even loop. Could you suggest a fix? For those who dont know, prime numbers are those greater than 1 that cannot be formed by multiplying two smaller natural numbers. (ex. 3, 5, 7)
#include <stdio.h>
#define START 200
#define END 300
int main()
{
int primenum = 0, i = 0, j = 0, c = 0;
for (i = START; i <= END; i++)
{
for (j = 1; j <= i; j++)
{
if (i%j == 0)
{
c++;
}
if (c == 2)
{
primenum = primenum + 1;
}
}
}
printf("tHE PRIME NUMBERS ARE %d", primenum);
}
This is my solution:
#include <stdio.h>
#define START 200
#define END 300
int main()
{
int primenum = 0, i = 0, j = 0, c = 0;
for (i = START; i <= END; i++)
{
c = 2;
for (j = 2; j <= i-1; j++)
{
if (i%j == 0)
{
c++;
}
}
if (c == 2) primenum = primenum + 1;
}
printf("THE PRIME NUMBERS ARE %d", primenum);
return 0;
}
I put c = 2 in the for with i because a prime number has 2 divisor (1 and itself). The for with j starts from 2 because 1 is a divisor and ends at i-1 because i is the number and each number is a divisor for itself. I tested the c value at the end of the for with j because if this value is tested inside the result is wrong. I obtained 16 prime numbers between 200 and 300.
Let's fix some issues.
for (j = 1; j <= i; j++) Every number is divisible by 1 and
itself so you need to fix this issue. You should start j=2 to
j=i-1 You need to change for (j = 1; j <= i; j++) to for (j = 2;
j <i; j++)
You need to reset the counter variable c for every number before you
enter the nested for loop.
You're checking the value of c in the loop and that's why you're
getting the wrong result. You should check the value of c after
breaking out from the loop.
#include <stdio.h>
#define START 100
#define END 200
int main()
{
int primenum = 0, i = 0, j = 0, c = 0;
for (i = START; i <= END; i++)
{
c=2;
for (j = 2; j <i; j++)
{
if (i%j == 0)
{
c++;
break;
}
}
if (c == 2)
{
primenum = primenum + 1;
}
}
printf("tHE PRIME NUMBERS ARE %d", primenum);
}
I'm trying to print the Prime numbers between a given range but I get blank output. Where have I gone wrong? Is it a logic mistake or implementation mistake?
#include <stdio.h>
int isPrime(int i)
{
int j;
for(j=2; j<=i; j++)
{
if(i%j==0)
{
return 0;
}
}
return 1;
}
int main()
{
int cases, n1, n2, i;
scanf("%d", &cases);
while(cases>0)
{
scanf("%d%d", &n1, &n2);
for(i=n1; i<=n2; i++)
{
if(isPrime(i))
{
printf("%d\t", i);
}
}
cases--;
}
return 0;
}
You must stop the loop in isPrime before i because all non zero numbers are divisible by themselves:
int isPrime(int i) {
int j;
for (j = 2; j < i; j++) {
if (i % j == 0) {
return 0;
}
}
return 1;
}
Note that you should also return 0 for numbers below 2. Furthermore, you can improve performance dramatically by stopping at the square root of i and by testing only odd numbers above 2.
int isPrime(int i) {
if (i <= 2) {
return i == 2;
}
for (int j = 3; j * j <= i; j += 2) {
if (i % j == 0) {
return 0;
}
}
return 1;
}
i%i==0 will be always true unless i is zero, so isPrime will return 0 for whatever i which is 2 or greater.
You can use j<i instead of j<=i, for example.
Another point is that your isPrime will mistakenly judge all integers that is 1 or less as primes, so you should check for them before the loop.
Apart from being sub-optimal, your code goes all the way to i when trying to find the divisor. This means that all checks will eventually succeed when i == j, so i%j is zero.
A better stopping condition for the loop is
for( j=2 ; j*j <= i ; j++)
In other words, stop upon passing the square root of i. This is valid, because if you have not found proper divisors smaller than the square root, then it is guaranteed that there are also no divisors larger than the square root.
If you know the upper limit for n2, you could make your solution even faster by pre-computing all primes up to sqrt(n2), and using them to test whether other numbers are prime or not.
For starters 2 is a prime number. And every number is divisible by itself. So this condition
if(i%j==0)
will be always equal to true when j is equal to i.
The function can be written the following way
int isPrime( unsigned int x )
{
int prime = ( x == 2 ) || ( x % 2 != 0 && x > 2 );
for ( unsigned int i = 3; prime && i * i <= x; i += 2 )
{
prime = x % i != 0;
}
return prime;
}