counting prime numbers infinite loop - c

I tried counting how many prime there are (except 1 and 0) until there are N number of primes. But somehow my program always ends up looping INFINITELY
int main (){
int n;
printf("Enter size N: ");
scanf("%d", &n);
int i, j, ctr = 0, flag = 0;
for (i = 2; ctr != n; i++){
for (j = 2; j < i; j++){
if (i%j==0){
flag = 1;
break;
}
}
if(flag!=1){
ctr++;
}
}
}

I notice you never reset your flag.
So once a divider is found, you raise your flag to indicate it isn't a prime.
But never set it back to 0, so all number afterward are considered not prime
int i, j;
int ctr = 0; // Prime number counter
int flag;
// For i, from 2 to whatever needed to have N prime numbers
for (i = 2; ctr != n; i++){
flag = 0 // THIS IS THE LINE YOU'RE MISSING
// Look for potential divider
for (j = 2; j < i; j++){
// If i is divided by j, it isn't prime
if (i%j==0){
flag = 1;
break;
}
}
// If no divider found, i is prime
if(flag!=1){
ctr++;
}
}

To add something to your program different than what Portevent mentioned, you dont have to check if i % j != 0 for all j < i to check if i is prime. You just have to check for the range j < sqrt(i).
This is because you stop looping when you get a j value such that i % j == 0. If you were to get to j == sqrt(i) it means for i to not be prime it would have at least a prime factorization of p * q with p and q being greater than sqrt(i), which is nonsense, hence i is prime.
PS: in case you add this optimization to your program, do not hardcode sqrt(i) in the for loop, assign it to some variable then write the variable in the loop to avoid repeated computations.

Who told you that your program loops infinitely? It doesnt.
You just missed resetting the flag like others specified. And also:
you can loop for j < i/2;
Think about it: what is the biggest integer divisor of a prime/non-prime number other than self?
To find it out divide it by the possible minimum integer number:
if we divide it by 1 we get the number itself *
if we divide it by 2 we get the half of the number which is the possible maximum divisor.

Related

Prime Number between given interval

Given below is the code for finding prime numbers between the interval entered by the user.
#include <stdio.h>
int main() {
int n1, n2, i, flag;
scanf("%d%d", &n1, &n2);
for (i = n1; i <= n2; i++) {
flag = prime(i);
if (flag == 1)
printf("\n%d", i);
}
return 0;
}
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
Can anyone explain me how this code deals with odd number, which are not prime (for ex: 15, 21, 25, etc)
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
See in this prime function, when we observe the iteration of for loop if value of n is 15 then it will look like this:
for (j = 2; j <= 15 / 2; j++)
I agree this is true. Because 2<7.
Since the condition is true we will enter inside the for loop:
if(n%j==0){
flag=0;
break;
}
Now, since n=15 and j=2, value of n%j=1, which is obviously not equals to 0; so if loop will not be executed and the prime function will return flag =1; and the main function will print 15 as a prime.
But, after Executing the program the code is showing the correct results: it's not showing 15 as a prime.
So can anyone please help me understand the logic behind this code? (Actually I want to understand how this code is eliminating non-prime odd numbers.)
You checked the execution for j==2, but since there is a for loop for(j=2;j<=n/2;j++). The code will run from j=2 to j=n/2. So, if you consider all the iterations, you will realize that the function is working fine.
The first if statement is false, so for j==2, the program won't go inside the if statement.
The loop will iterate for the next value of j, which is 3. Since 15%3 == 0, the program will execute the statements within the if statement and return that 15 is not a prime number.
for(j=2;j<=n/2;j++){
if(n%j==0){
flag=0;
break;
}
}
In the case of n=15, the loop starts at i=2, the test i<=n/2 is true because 2<=7, then 15%2 is 1, hence the loop proceeds and i is incremented to 3, the loop test is true again because 3<=7 but 15%3 is 0 so flag is set to 0 and returned.
Note these remarks:
the code does not have a recursive function. You merely call a function prime() to check each number in the interval for primality.
prime() should be defined or at least declared before the main() function that calls it.
you can test the return value of prime(i) directly. No need for a flag variable.
for prime numbers, the loop will iterate way too far: you can change the test to j <= n / j to stop at the square root of n.
you can return directly from the loop body.
you should output the newline after the number.
Here is a modified version:
#include <stdio.h>
int isprime(int n) {
int j;
for (j = 2; j <= n / j; j++) {
if (n % j == 0)
return 0;
}
return 1;
}
int main() {
int n1, n2, i;
if (scanf("%d%d", &n1, &n2) != 2)
return 1;
for (i = n1; i <= n2; i++) {
if (isprime(i))
printf("%d\n", i);
}
return 0;
}
Can anyone explain me how this code deals with odd number, which are not prime (for ex: 15, 21, 25, etc)
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
Well this function doesn't need to handle specially nonprime numbers, based on the fact that if we can divide the number n by something (be prime or not), the number will be compose. What it does it to get out of the loop (with flag changed into 0) as soon as it finds a number j that divides n.
There's an extra optimization, that can save you a lot of time, that consists on calculating numbers until the integer rounded down square root of n as, if you can divide the number by a number that is greater than the square root, for sure there will be a number that is less than the square root that also divides n (the result of dividing the original number by the first will give you a number that is lower than the square root) so you only need to go up until the square root. While calculating the square root can be tedious (there's a library function, but let's go on), it is only done once, so it is a good point to use it. Also, you can initialy try dividing the number by two, and then skip all the even numbers, by adding 2 to j, instead of incrementing.
#include <math.h>
/* ... */
int prime(unsigned n) {
/* check for special cases */
if (n >= 1 && n <= 3) return TRUE; /* all these numbers are prime */
if (n % 2 == 0) return FALSE; /* all these numbers are not */
/* calculate (only once) the rounded down integer square root */
int j, square_root = isqrt(n); /* see below */
for (j = 3; j <= square_root; j += 2) { /* go two by two */
if (n % j == 0)
return FALSE;
}
/* if we reach here, all tests failed, so the number must be prime */
return TRUE;
}
While there's a sqrt() function in <math.h>, I recommend you to write an integer version of the square root routine (you can devise it easily) so you don't need to calculate it in full precision (just to integer precision).
/* the idea of this algorithm is that we have two numbers between 1 and n,
* the greater being the arithmetic mean between the previous two, while
* the lower is the result of dividing the original n by the arithmetic mean.
* it is sure than if we select the arithmetic mean, the number will be
* between the previous ones, and if I divide n by a number that is lower,
* the quotient will be higher than the original number. By the way, the
* arithmetic mean is always bigger than the square root, so the quotient
* will be smaller. At each step, both numbers are closer to each other, and
* so, the smaller is closer to the result of dividing n by itself (and this
* is the square root!)
*/
unsigned isqrt(unsigned n)
{
unsigned geom = 1, arith = n;
while (geom < arith) {
arith = (geom + arith) / 2;
geom = n / arith;
}
/* return the smaller of the two */
return arith;
}
so, your program would be:
#include <stdio.h>
#define FALSE (0)
#define TRUE (!FALSE)
unsigned isqrt(unsigned n)
{
unsigned geom = 1, arith = n;
while (geom < arith) {
arith = (geom + arith) / 2;
geom = n / arith;
}
return arith;
}
int prime(unsigned n) {
/* check for special cases */
if (n >= 1 && n <= 3) return TRUE;
if (n % 2 == 0) return FALSE;
/* calculate (only once) the rounded down integer square root */
int j, square_root = isqrt(n);
for (j = 3; j <= square_root; j += 2) {
if (n % j == 0) {
return FALSE;
}
}
return TRUE;
}
int main() {
unsigned n1, n2, i;
scanf("%u%u", &n1, &n2);
for (i = n1; i <= n2; i++) {
if (prime(i))
printf("%u\n", i);
}
return 0;
}
If you try your version against this one, with values like 2000000000 and 2000000100 you will see how this is saving a lot of calculations (indeed, for the cases below, the case of considering only the odd numbers when going throug the loop will take out of it half the numbers ---this is 1000000000 tests---, but the square root will reduce the number of tests to its square root ---only around 40000 tests--- for each number!!!).
$ primes
2000000000 2000000100
2000000011
2000000033
2000000063
2000000087
2000000089
2000000099
$ _
Your version takes (on my system) this execution time:
$ echo 2000000000 2000100000 | time primes0 >/dev/null
3.09user 0.00system 0:03.09elapsed 99%CPU (0avgtext+0avgdata 1468maxresident)k
0inputs+0outputs (0major+69minor)pagefaults 0swaps
$ _
while the version proposed takes:
$ echo 2000000000 2000100000 | time primes >/dev/null
0.78user 0.00system 0:00.78elapsed 99%CPU (0avgtext+0avgdata 1572maxresident)k
0inputs+0outputs (0major+72minor)pagefaults 0swaps
$ _

Write a function gets number of squares and will return how many integer numbers are used as square

Write a function getNumberOfSquares(int n) (C) / get_number_of_squares that will return how many integer (starting from 1, 2...) numbers raised to power of 2 and then summed up are less than some number given as a parameter.
e.g 1: For n = 6 result should be 2 because 1^2 + 2^2 = 1 + 4 = 5 and 5 < 6 E.g 2: For n = 15 result should be 3 because 1^2 + 2^2 + 3^2 = 1 + 4 + 9 = 14 and 14 < 15
For the function above I wrote a program but the test program gave an error that is when input is getNumberOfSquares(100000) function should return 66 but mine returns 403.
Here is my solution:
int getNumberOfSquares(int n){
int sum=0;
int limit=0;
for (int i = 1; i < n && n>sum; ++i)
{
sum += i*i;
++limit;
if(sum>=n){
sum -= i*i;
--limit;
}
}
return limit;
}
Assuming that an integer is 32 bits on your system, i*i will overflow once it reaches a value of 65536. That causes the inaccuracies.
However it shouldn't actually reach that point, since you continue to check values of i even after the value of sum exceeds n. You should break out of the loop when you reach that point.
int getNumberOfSquares(int n){
int sum=0;
int limit=0;
for (int i = 1; i < n; ++i)
{
if (sum + i*i >= n) {
return limit;
}
sum += i*i;
++limit;
}
return limit;
}
You want to find the biggest i such that sum < n. So this should be the only condition breaking the loop. You don't need to check even that i < n.
Now the problem of your code is that you modify sum when it gets big enough to break the loop, making it again less than n. So if sum < n was your only condition you would have had an infinite loop. But since you have the i < n condition, the program keep adding and subtracting i*i to sum until i < n.
If n is small enough, adding and subtracting i*i doesn't change sum and when the loop breaks you get your result.
But if i can grow big enough to make sum greater than the greatest int you can have, sum overflows and becomes a meaningless value.
The solution is to eliminate the condition if(sum>=n){}.
Removing the condition will reveal that limit is like i, so you can even use i as returned value.
And keeping in mind that you don't need the condition i < n, your function becomes
int getNumberOfSquares(int n) {
int i, sum = 0;
for(i = 1; sum < n; ++i) {
sum += i*i;
}
return i-2;
}
Returning i-2 because the i making sum > n was already 1 more than the value you wanted to return and then before sum > n is checked, thefor increments i.

Find largest prime number below input value

Let me start by saying that I am a beginner. I'm trying to define a function that calculates/identifies the largest prime number below an input value. However, my current approach is flawed.
I've tried implementing a nested for loop. Generating numbers from one below the input down to 1, subsequently running each number through the second loop so as to identify whether or not it is prime. If it is prime (if count == 2) the function is supposed to return the number that was generated by the first loop (n)
I've been permitted to assume that the input will be a positive integer greater than 2.
int prime(int maximum)
{
int i, j, count = 0, n;
for (i = 1; i < maximum; i++) {
n = maximum - i; /* generating number below input value*/
for (j = 1; j <= maximum; j++) {
if (n % j == 0) { /* testing whether or not it is prime */
count++;
}
} if(count == 2) {
break;
}
}
return n;
}
I'd expect an input of 10 to produce an output of 7, an input of 30 to produce an output of 29 and an input of 100 to produce an output of 97.
However, the function is currently generating an output of 1 - consistently.
The code is not generating any error messages
note: This is my first time utilising this platform, my most sincere apologies if the formatting of my question is incorrect
The problem is you are not resetting the count to 0 in the outer loop.
This will solve the problem.
Adding further,
There are some other optimizations that can be done in the code too.
You need not run the inner loop maximum times, only n times will be sufficient as you are checking whether n is prime or not.
You can put the break condition inside the inner for loop for those whose count has crossed 2 to avoid further iterations.
int prime(int maximum)
{
int i, j, count = 0, n;
for (i = 1; i < maximum; i++) {
count = 0; # <----- Reset it to 0.
n = maximum - i; /* generating number below input value*/
for (j = 1; j <= n; j++) {
if (n % j == 0) { /* testing whether or not it is prime */
count++;
if(count > 2) # to avoid further iterations as we know, this number is not prime.
break;
}
} if(count == 2) {
break;
}
}
return n;
}

Non divisible subset-Hackerrank solution in C

I am new to programming and C is the only language I know. Read a few answers for the same question written in other programming languages. I have written some code for the same but I only get a few test cases correct (4 to be precise). How do I edit my code to get accepted?
I have tried comparing one element of the array with the rest and then I remove the element (which is being compared with the initial) if their sum is divisible by k and then this continues until there are two elements in the array where their sum is divisible by k. Here is the link to the question:
https://www.hackerrank.com/challenges/non-divisible-subset/problem
#include<stdio.h>
#include<stdlib.h>
void remove_element(int array[],int position,long int *n){
int i;
for(i=position;i<=(*n)-1;i++){
array[i]=array[i+1];
}
*n=*n-1;
}
int main(){
int k;
long int n;
scanf("%ld",&n);
scanf("%d",&k);
int *array=malloc(n*sizeof(int));
int i,j;
for(i=0;i<n;i++)
scanf("%d",&array[i]);
for(i=n-1;i>=0;i--){
int counter=0;
for(j=n-1;j>=0;j--){
if((i!=j)&&(array[i]+array[j])%k==0)
{
remove_element(array,j,&n);
j--;
continue;
}
else if((i!=j)&&(array[i]+array[j])%k!=0){
counter++;
}
}
if(counter==n-1){
printf("%ld",n);
break;
}
}
return 0;
}
I only get about 4 test cases right from 20 test cases.
What Gerhardh in his comment hinted at is that
for(i=position;i<=(*n)-1;i++){
array[i]=array[i+1];
}
reads from array[*n] when i = *n-1, overrunning the array. Change that to
for (i=position; i<*n-1; i++)
array[i]=array[i+1];
Additionally, you have
remove_element(array,j,&n);
j--;
- but j will be decremented when continuing the for loop, so decrementing it here is one time too many, while adjustment of i is necessary, since remove_element() shifted array[i] one position to the left, so change j-- to i--.
Furthermore, the condition
if(counter==n-1){
printf("%ld",n);
break;
}
makes just no sense; remove that block and place printf("%ld\n", n); before the return 0;.
To solve this efficiently, you have to realize several things:
Two positive integer numbers a and b are divisible by k (also positive integer number) if ((a%k) + (b%k))%k = 0. That means, that either ((a%k) + (b%k)) = 0 (1) or ((a%k) + (b%k)) = k (2).
Case (1) ((a%k) + (b%k)) = 0 is possible only if both a and b are multiples of k or a%k=0 and b%k=0. For case (2) , there are at most k/2 possible pairs. So, our task is to pick elements that don't fall in case 1 or 2.
To do this, map each number in your array to its corresponding remainder by modulo k. For this, create a new array remainders in which an index stands for a remainder, and a value stands for numbers having such remainder.
Go over the new array remainders and handle 3 cases.
4.1 If remainders[0] > 0, then we can still pick only one element from the original (if we pick more, then sum of their remainders 0, so they are divisible by k!!!).
4.2 if k is even and remainders[k/2] > 0, then we can also pick only one element (otherwise their sum is k!!!).
4.3 What about the other numbers? Well, for any remainder rem > 0 make sure to pick max(remainders[rem], remainders[k - rem]). You can't pick both since rem + k - rem = k, so numbers from such groups can be divisible by k.
Now, the code:
int nonDivisibleSubset(int k, int s_count, int* s) {
static int remainders[101];
for (int i = 0; i < s_count; i++) {
int rem = s[i] % k;
remainders[rem]++;
}
int maxSize = 0;
bool isKOdd = k & 1;
int halfK = k / 2;
for (int rem = 0; rem <= halfK; rem++) {
if (rem == 0) {
maxSize += remainders[rem] > 0;
continue;
}
if (!isKOdd && (rem == halfK)) {
maxSize++;
continue;
}
int otherRem = k - rem;
if (remainders[rem] > remainders[otherRem]) {
maxSize += remainders[rem];
} else {
maxSize += remainders[otherRem];
}
}
return maxSize;
}

Creating a program in C to generate primes

I am trying to generate a list of all the prime numbers for the first 1000 numbers.
I am not sure where I am going wrong in my code. From what I can tell, my nested for loop is not reading dividing/reading the array correctly and then assigning that array the proper value. How can I fix it?
The program currently only generates all the odd numbers.
int main() {
int x = 1;
int arr[500];
int i, j, k;
int counter;
int primearray[500];
for (j = 0; j <= 500; j++) {
x += 2;
arr[j] = x;
for (k = 1; k <= 15; k++) {
counter = x % k;
if (counter == 0) {
primearray[j] = x;
} else {
break;
}
}
for (i = 0; i < 500; i++) {
printf("%d ", primearray[i]);
}
}
Please invest time in learning how to indent your code. Choose a style that suits you and use it consistently: this will make your programs easier to read, and in turn easier to understand.
As I'm writing this, your posted code doesn't even compile because a closing curly brace } is missing: such editing mistakes are made possible by misleading indentation. Also note that in a properly written C program you must remember to #include any standard headers that are used:
#include <stdio.h> // for `printf()`
Rather than try to fix your algorithm, which at first glance doesn't make any sense to me anyway, I will try to help you restructure your program.
Keep main() simple
Given that the goal of your program is checking which of the first 1000 natural numbers are prime, the main() function should do no more than loop through those numbers and print the ones which are prime, like this:
for (int n=0; n < 1000; ++n)
if (is_prime(n))
printf("%d\n", n);
Putting them in an array instead of printing is equally easy:
int prime_array[500]; // array of primes
int k=0; // current index in array of primes
for (int n=0; n < 1000; ++n)
if (is_prime(n))
prime_array[k++] = n;
Break up the program in several functions
In accordance to the previous idea, write short and simple functions that do one thing, and do it well. In your case, you should write the is_prime() function to determine if a number is prime or not. You can start from here:
///
/// #brief Checks if a number is prime.
/// #param [in] n Number to be checked
/// #returns Whether `n` is prime or not.
/// #retval 1 If `n` is prime.
/// #retval 0 If `n` is not prime.
///
int is_prime(int n)
{
// TODO: add code here
}
Decide how to check for primality
There is a Primality test article on Wikipedia that you should read.
First, you must correctly handle these special cases:
0 is not prime
1 is not prime
2 is prime
// TODO: also check 1 and 2 in a similar fashion
if (n == 0)
return 0;
After this is done, you can use a naive and inefficient algorithm that checks the other numbers:
// try divisors from 2 to n-1
for (int d=2; d < n; ++d)
if (n % d == 0) // if the division was even,
return 0; // the number is not prime
return 1; // if we get here, the number is prime
If you want to use a faster (but more complicated) algorithm for checking primes, look back at the Wikipedia article linked above. Notice how you'd only have to change the code inside is_prime() and the rest of the program would work the same, unchanged.
As I understood from your code, arr is an array of possible candidates and primearray is an array of approved ones. No every candidate will be approved one so you need different variables for indexing them.
The second issue is the algorithm for approving candidates. From this part of your code (I changed some indents)
for (k = 1; k <= 15; k++) {
counter = x%k;
if (counter == 0) {
primearray[j] = x;
} else {
break;
}
follows that you approve a candidate if it is divisible by all integers from 1 to 15 - I am sorry but prime numbers have not this property.
I think you could refer to this code which will generate all prime numbers up to the number that you specify. I think this will be more optimised.
void main()
{
int n, i, j, temp=0;
printf("Enter a number \n");
scanf("%d", &n);
printf(" Prime numbers -\n");
for(i=2; i<n+1; i++)
{
temp = 0;
for(j=2; j<i; j++)
{
if(i%j == 0)
{
temp = 1;
break;
}
}
if(temp == 0)
{
printf("%d \n", i);
}
}
getch();
}

Resources