Smith Number program never ends (infinite loop) - c

I need to make a program to identify whether the input number is a Smith number or not.
Here is my code:
#include <stdio.h>
void smith(int n) {
int num, sd = 0, sf = 0, i, t, c, j;
num = n;
while (num > 0) {
sd = sd + (num % 10); // Sum of digits of input number
num = num / 10;
}
num = n;
while (num > 1) // To calculate factors of the number
{
for (i = 1; i <= num; i++) {
if (num % i == 0) break;
}
c = 0;
t = i;
for (j = 1; j <= i; j++) // To check if the numbers are prime
{
if (i % j == 0) c++;
}
if (c == 2) {
while (i > 0) {
sf = sf + (i % 10);
i = i / 10;
}
}
num = num / t;
}
if (sd == sf) {
printf("Smith Number");
} else
printf("Not a Smith Number");
}
int main() {
int n;
printf("Enter a number");
scanf("%d", &n);
smith(n);
}
Every time I try to run the code, it just doesn't give an output.
It just takes an input and then probably goes into an infinite loop.

Because the value of t is always 1, num is always stay the same, while loop endlessly. You can fix it like this:
for (i = 2; i <= num; i++) {
if (num % i == 0) break;
}

In
for (i = 1; i <= num; i++) {
if (num % i == 0) break;
}
You always get 1 as factor(every number is divisible by 1) and the only factor you consider is one. As you divide by one, you never get your number smaller. You should start that loop at 2.

The problem is that you are introducing an infinite loop (a very elusive one). Look at these lines of code:
for (i = 1; i <= num; i++) {
if (num % i == 0) break;
}
You are testing if the num is divisible by 1 (which is true for every number), so it will always break, and i will be 1.
Later on, you divide num by this number until num is less than or equal to one, but dividing by one yields the same number, so the loop will never end. If the loop never ends, then your program will stall, hence the program never printing a result.
The solution is simple: start your factoring loop at 2, not 1. Like this:
for (i = 2; i <= num; i++) {
if (num % i == 0) break;
}
1 is a factor of every number, so it is not a useful factor.

Related

C Program to Print Prime Numbers From 1 to 100 (problem at inner and outer loop variable)

// C Program to Print Prime Numbers From 1 to 100
#include
int main() {
int i, num, count;
// Checking for prime numbers
for (num = 1; num <= 100; num++) {
count = 0;
for (i = 2; i <= num/2; i++) {
if (num % i == 0) {
count++;
break;
}
}
// Checking and Printing Prime Numbers
if (count == 0 && num != 1) {
printf("%d \n", num);
}
}
return 0;
}
I don't understand, if I put 0 at the start of the count variable (i.e., int i, num, count=0; like this) the code is not working. But if you put count=0 inside the for loop it is working. Why is this happening?
I wonder if you wrote that code yourself.
Why did you add count variable to start with if you do not seem to know how it works?
I don't understand, if I put 0 at the start of the count variable (i.e., int i, num, count=0; like this) the code is not working. But if you put count=0 inside the for loop it is working. Why is this happening?
That variable is used to detect if any value of i is found where num is a multiple of i. If that is the case (count != 0 it is not a prime.
Of course you need to do this for each number num which means you must reset count for each iteration of the outer loop.
If you only do it once where you define the variable, it will never find any prime number any more after you saw the first none-prime number.
Working code:
// C Program to Print Prime Numbers From 1 to 100
#include
int main(void) {
int i, num, count;
// Checking for prime numbers
for (num = 2; num <= 100; num++) {
count = 0; // This is the indicator whether a number is prime
// We must reset it here for each number we check.
for (i = 2; i <= num/2; i++) {
if (num % i == 0) {
count++;
break;
}
}
// Checking and Printing Prime Numbers
if (count == 0) {
printf("%d \n", num);
}
}
return 0;
}
Broken code:
// C Program to Print Prime Numbers From 1 to 100
#include
int main(void) {
int i, num, count = 0; // This is only set to 0 once for all numbers we check.
// Checking for prime numbers
for (num = 2; num <= 100; num++) {
for (i = 2; i <= num/2; i++) {
if (num % i == 0) {
count++; // count will never become 0 again.
// We will not be able to detect any prime number after this.
break;
}
}
// Checking and Printing Prime Numbers
if (count == 0) {
printf("%d \n", num);
}
}
return 0;
}
Not related to your problem but some detail to improve the code:
Why do you start with num=1 if you later check num != 1?
Instead start at num=2.
Or print 2 before you start the loop. Then run the loop from num=3 and increment num+=2 to only check the odd numbers.

Generating prime numbers

I have started learning C language recently, but since I've first stumbled upon prime number generators I've been having trouble understanding the code. to be clear i do know what prime numbers are, i just would like someone to explain to me what happens in the code. here is an example from a book that im studying.
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int p, i, primes[50], primeIndex = 2;
bool isPrime;
primes[0] = 2;
primes[1] = 3;
for (p = 5; p <= 50; p = p + 2) {
isPrime = true;
// this is the part that I'm having trouble with
for (i = 1; isPrime && p / primes[i] >= primes[i]; ++i)
if (p % primes[i] == 0)
isPrime = false;
if (isPrime == true) {
primes[primeIndex] = p;
++primeIndex;
}
//--------------------
}
for (i = 0; i < primeIndex; ++i)
printf("%i ", primes[i]);
printf("\n");
return 0;
}
I've been scratching my head for quite some time by now and i can't get through this one on my own, I would be glad if someone could help.
To determine if p is prime, the loop iterates on the array of primes found so far, checking if p modulo primes[i] is 0, which indicates that p is a multiple of primes[i]. If so isPrime is set to false and the loop stops at the next iteration because the test isPrime && p / primes[i] >= primes[i] will be false.
The reason for the second part of the test, p / primes[i] >= primes[i], is to stop the loop once all prime numbers less or equal to the square root of p have been tested.
Here is an alternate version with a simpler test and a break statement:
isPrime = true;
for (i = 1; p / primes[i] >= primes[i]; ++i) {
if (p % primes[i] == 0) {
isPrime = false;
break;
}
}
// here isPrime is true if and only if p is a prime number.
Note that the primes[] array has been initialized with 2 and 3, so 5 will be proven a prime immediately because 5 / primes[1] = 5 / 3 = 1, which is smaller than 3.
Note also that only even numbers are tested from 5 up and i starts at 1, skipping the modulo operation by 2, which will obviously evaluate to 1.
Finally, p is only tested up to 50, which makes the array of 50 primes amply sufficient: only 23 values are tested in the loop (odd numbers from 5 to 49) so at most 25 values could potentially be set in primes[].
#include <stdio.h>
int main() {
int n, i, flag = 0;
printf("Enter a positive integer: ");
scanf("%d", &n);
for (i = 2; i <= n / 2; ++i) {
if (n % i == 0)
{
flag = 1;
break;
}
}
if (n == 1) {
printf("1 is neither prime nor composite.");
}
else
{
if (flag == 0)
printf("%d is a prime number.", n);
else
printf("%d is not a prime number.", n);
}
return 0;
}

How to find the nearest prime for a given number using for loop in C?

I really tried but still don't know what's wrong with my code.
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int minus, i, judge;
for (minus = 0, judge = 1; judge == 1; minus++, n -= minus) {
for (i = 2; i * i < n; i++) {
if (n % i == 0)
judge = 1;
else judge = 0;
}
if (judge == 1)
continue;
else break;
}
printf("%d\n", n);
return 0;
}
When I input 143, the output is 143 not 139.
However, when I input 11, the output is the correct answer 11.
The loop test is incorrect: for (i = 2; i * i < n; i++)
If n is the square of a prime number, the loop will stop just before finding the factor.
You should either use i * i <= n or i <= n / i.
Furthermore, you do not enumerate all numbers as you decrement n by an increasing value at each iteration.
Note also that the loop would not find the closest prime to n, but the greatest prime smaller than n, which is not exactly the same thing.
Here is a modified version:
#include <limits.h>
#include <stdio.h>
int isPrime(int n) {
if (n <= 2 || n % 2 == 0)
return n == 2;
for (int i = 3; i <= n / i; i += 2) {
if (n % i == 0)
return 0;
}
return 1;
}
int main() {
int n;
if (scanf("%d", &n) != 1)
return 1;
if (n <= 2) {
printf("2\n");
} else {
for (i = 0;; i++) {
if (isPrime(n - i))
printf("%d\n", n - i);
break;
}
if (n <= INT_MAX - i && isPrime(n + i))
printf("%d\n", n + i);
break;
}
}
}
return 0;
}

Performance issue in c while dealing with 12 digit number

currently i am working on a program. program is working perfectly but it has performance issue. the code is below.
#include<stdio.h>
int calculate(int temp)
{
int flag = 0,i = 2,tmp = 0;
for(i = 2;i < temp;i++)
{
if(temp % i == 0)
{
return 1;
}
}
}
int main()
{
long int i = 2,j,count = 0,n = 600851475143,flag = 0,prime = 0;
long int check;
while(i < n)
{
if(n % i == 0)
{
check = calculate(i);
if(check != 1)
{
prime = i;
printf(" Prime number is : %ld \n", prime);
}
}
i++;
}
printf(" Max prime number of %ld is : %ld \n",n,prime);
return 0;
}
I can't able to get the maximum prime number here.
can anyone tell me what should i do it takes too much time what should i do to get output fast?
If you are looking for a maximum prime, why are you starting at 2? Begin checking at n and work backwards
calculate can run faster since you only need to check for a divisor up to sqrt(temp), if it has a divisor larger than that, it also has a divisor smaller than that.
Your loop increments and decrements can be done in hops of 2. So you'd also halve the range of numbers to check.
Calling printf in the middle of a search loop for when the check fails is just a waste of execution speed. Instead, check for success and break out of the loop.
With these modifications in mind (and your code cleaned from a lot of UB):
#include<stdio.h>
int calculate(long int temp)
{
long int flag = 0,i = 2,tmp = 0;
if (temp % 2 == 0)
return 1;
for(i = 3; i*i <= temp; i+=2)
{
if(temp % i == 0)
{
return 1;
}
}
return 0;
}
int main(void)
{
long int j, count = 0, n = 600851475143, i = n, flag = 0, prime = 0;
long int check;
while(i > 0)
{
if(n % i == 0)
{
check = calculate(i);
if(check)
{
prime = i;
break;
}
}
i-=2;
}
printf(" Max prime number of %ld is : %ld \n",n,prime);
return 0;
}

Generating Random UNIQUE and converting to binary in C

I have implemented a basic program which generates 10 random and unique numbers from 1 to 10 as shown below. I have added an extra part in which I want the binary representation for each unique and random number. My program looks like this.
int value=1, loop, loop1, get=0, x, arr[10], array[20], count, i =0, y;
srand(time(NULL));
for (x = 0; x < 10; x++)
{
for (count = 0; count < 10; count++) {
array[count] = rand() % 10 + 1; //generate random number between 1 to 10 and put in array
}
while (i < 10) {
int r = rand() % 10 + 1; // declaring int r
for (x = 0; x < i; x++)
{
if (array[x] == r) { //if integer in array x is equal to the random number generated
break; //break
}
}
if (x == i) { //if x is equal to i then
array[i++] = r; //random number is placed in array[10]
}
}
for (y = 0; y < 10; y++) {
printf("unique random number is %d\n", array[y]);
array[y] = value;
for (loop = 0; loop < 1000; loop++)
{
if (value <= 1) { arr[loop] = 1; break; } //if value is 1 after dividing put 1 in array
if (value % 2 == 0) arr[loop] = 0;
else arr[loop] = 1;
value = value / 2;
}
for (loop1 = loop; loop1 > -1; loop1--)
printf("%d", arr[loop1]);
printf("\n");
}
}
My problem is that The binary value for each random unique number is being given as 1. In this program it is seen that I initialised value=1 and this can be the source for my error, however when I remove this I get an error stating that the local variable is uninitialised.
The first part of my program which generates the unique numbers is working fine, however the second part where I am converting to binary is not.
EDIT: I tested The second part of my program and it works well on it's own. The problem must be the way I am combining the two programs together.
Statement array[y] = value overrides the previously generated random values with constant 1.write
value = array[y];
Here is the commented code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//function to check unique random number
int check(int array[],int count,int val)
{
int i=0;
for( ;i<count ;++i )
{
if (array[i]==val)
return 1;
}
return 0;
}
int main(void)
{
int value,loop, loop1, get, x, arr[10];
int oldRandoms[10]; // array to preserve old random values
srand(time(NULL));
for (x = 0; x < 10; x++)
{
do // do while to get only unique random number
{
get = rand() % 10 + 1;
}while(check(oldRandoms,x,get));
oldRandoms[x]=get; // backup the number
printf("random number is %d \n", get);
value = get;
for (loop = 0; loop < 1000; loop++)
{
if (value <= 1) { arr[loop] = 1; break; } //if value is 1 after dividing put 1 in array
if (value % 2 == 0) arr[loop] = 0;
else arr[loop] = 1;
value = value / 2;
}
for (loop1 = loop; loop1 > -1; loop1--)
printf("%d", arr[loop1]);
printf("\n");
}
}

Resources