Using While-Loops to Find the Smallest Divisor of a Number - c

I've been studying C programming again with the usage of my "C How to Program" textbook. As an exercise within the text, I have been prompted to find the smallest divisor of a number supplied by a user. Just to clarify, just in case, a number is a divisor if the division results in a remainder of 0, and we are looking for a divisor greater than 1. To complete this, it instructs that I should use a while-loop. I have just begun using while-loops, so I understand the basic idea and function, but not exactly how to execute everything properly in this situation. Seeing this example will grant me a better understanding. I take it as that I am supposed to create some code that looks for a divisor, counting up until it finds one. Thank you for any help that you provide. It is greatly appreicated.
Best regards!

To find the smallest divisor, you need to check from 2 to n that which number's division results in a remainder of 0. The first number which division results in a remainder of 0 is the smallest one. See the implementation below:
int n, i;
scanf("%d", &n);
i = 2;
while(i <= n){
if(n % i == 0){
printf("The smallest number is %d\n", i);
break;
}
i++;
}
But u can do it more efficiently. you don't actually need to traverse till n. Traversing till square root of n is enough to find this. if you don't find the smallest number after traversing till the square root of n that's mean the smallest number is n itself. see the implementation below.
#include <stdio.h>
#include <math.h>
int main()
{
int n, i, sq;
scanf("%d", &n);
i = 2;
sq = sqrt(n);
while(i <= sq){
if(n % i == 0){
printf("The smallest number is %d\n", i);
break;
}
i++;
}
if(i > sq){
printf("The smallest number is %d\n", n);
}
}

Related

Loops running infinitely for big inputs

I am self learner, I am working on a population growth problem, and I came across the issue of loop running infinitely when I enter a big ending number that I want to reach.
#include <cs50.h>
#include <stdio.h>
int main(void) {
// TODO: Prompt for start size
int n;
do {
n = get_int("Enter the starting size of your llamas: ");
} while (n <= 8);
// TODO: Prompt for end size
int j;
do {
j = get_int("Enter the Ending size of your llamas: ");
} while (j <= n);
// TODO: Calculate number of years until we reach threshold
int k = 0;
do {
n = n + (n/3) - (n/4);
printf("The number is %i\n", n);
k++;
} while (n != j);
// TODO: Print number of years
printf("The number is %i\n", k);
}
The answer is supposed to be the number of years it takes to reach the end size llamas, but I am not able to put in big numbers of end size, can you help me figure out what is wrong, maybe in my math or a sign. Thanks in advance.
For large numbers, n is incremented by more than 1 at each iteration, so it is possible than it becomes larger than j without being equal to it first.
Change the test while(n != j); to while(n < j);

For loop "<" vs "<=" print format issues in program

I am learning C on my own with a book and I cannot for the life of me figure out how to solve this exercise. I'm obviously looking at it in the wrong way or something. Here is an explanation below.
Listed below are some functions and the main function at the bottom. This program is compiled to generate a certain number of random numbers and determine the min and the max of the random numbers. If you copy and paste this code, you will see how it works. Anyways, an exercise asks me to go to the function "prn_random_numbers()" and change the for loop from "for (i = 1; i < k; ++i)" to for (i = 2; i <= k; ++i). This causes the first line format to print incorrectly. The exercise is to further modify the program in the body of the for loop to get the output to be formatted correctly.
To sum it up, the "prn_random_numbers()" function is written to print out 5 random numbers before moving to the next line. Hence the" i % 5" if statement. Now, for some reason, when you make the slight adjustment to the for loop, as the exercise asks above, it causes the first line to only print 4 numbers before moving to the next line. I have tried a number of things, including trying to force it to print the 5th number, but it only duplicated one of the random numbers. I even tried "i % 4" to see if it would print 4 numbers for each row, but it only prints 3 numbers for the first row instead of 4! So it always prints one less number on the first line than it is supposed to. I have n clue why it is doing that and the book does not give an exercise. Do you have any idea?
Bear with me if you think this is a stupid question. I am just learning on my own and I want to make sure I have a good foundation and understand everything as I learn it, before moving forward. I appreciate any help or advice!
prn_random_numbers(k) /* print k random numbers */
int k;
{
int i, r, smallest, biggest;
r = smallest = biggest = rand();
printf("\n%12d", r);
for (i = 1; i < k; ++i)
{
if (i % 5 == 0)
printf("\n");
r = rand();
smallest = min(r, smallest);
biggest = max(r, biggest);
printf("%12d", r);
}
printf("\n\n%d random numbers printed.\n", k);
printf("Minimum:%12d\nMaximum:%12d\n", smallest, biggest);
}
int main()
{
int n;
printf("Some random numbers are to be printed.\n");
printf("How many would you like to see? ");
scanf("%d", &n);
while (n < 1)
{
printf("ERROR! Please enter a positive integer.\n");
printf("How many would you like to see? ");
scanf("%d", &n);
}
prn_random_numbers(n);
return (EXIT_SUCCESS);
}
the following proposed code:
properly initializes the random number generator
cleanly compiles
properly checks for and handles errors
performs the desired functionality
avoids having to list instructions twice
follows the axiom: Only one statement per line and (at most) one variable declaration per statement.
does not use undefined functions like: max() and min()
and now the proposed code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void prn_random_numbers(int k)
{
int count = 1;
int r;
int smallest;
int biggest;
r = smallest = biggest = rand();
printf("\n%12d", r);
for ( int i = 2; i <= k; i++, count++)
{
if (count % 5 == 0)
{
count = 0;
printf("\n");
}
r = rand();
smallest = (r < smallest)? r : smallest;
biggest = (r > biggest)? r : biggest;
printf("%12d", r);
}
printf("\n\n%d random numbers printed.\n", k);
printf("Minimum:%12d\nMaximum:%12d\n", smallest, biggest);
}
int main( void )
{
int n;
srand( (unsigned)time( NULL ) );
do
{
printf("Please enter a positive integer, greater than 0.\n");
printf("How many would you like to see? ");
if( scanf("%d", &n) != 1 )
{
fprintf( stderr, "scanf for number of random numbers failed\n" );
exit( EXIT_FAILURE );
}
} while( n < 1 );
prn_random_numbers(n);
// in modern C, if the returned value from `main()` is 0 then no `return 0;` statement needed
}
a typical run, no input problems is:
Please enter a positive integer, greater than 0.
How many would you like to see? 20
98697066 2110217332 1247184349 421403769 1643589269
1440322693 985220171 1915371488 1920726601 1637143133
2070012356 541419813 1708523311 1237437366 1058236022
926434075 1422865093 2113527574 626328197 1618571881
20 random numbers printed.
Minimum: 98697066
Maximum: 2113527574
Try to use a debugger to solve your problem, it's easy to use and really helpfull :)
SOLUTION:
Your i variable don't count the number of numbers because it is initialize at 1 (in the for statement), so you need to declare a new variable to count properly.
If you have still a problem:
void prn_random_numbers(int k)
{
int count = 1;
int i, r, smallest, biggest;
r = smallest = biggest = rand();
printf("\n%12d", r);
for (i = 2; i <= k; i++, count++) {
if (count % 5 == 0) {
count = 0;
printf("\n");
}
r = rand();
smallest = min(r, smallest);
biggest = max(r, biggest);
printf("%12d", r);
}
printf("\n\n%d random numbers printed.\n", k);
printf("Minimum:%12d\nMaximum:%12d\n", smallest, biggest);
}

Manipulating random number arrays

The question: Given integer values of x and y generate 20 random values within [x, y] interval and put them in an array. Print the array. Determine the index of the largest even negative number in it (ranging from 0 to 19). Account for the possibility that there might be no such number in the array. Calculate the sum of all positive odd numbers. You are only allowed to go through the
array values once. You should define separate functions for generating random numbers and checking even and odd numbers.
What I have written:
#include <stdio.h>
int random(int min, int max, int arr[]){
int i, j = 1;
for(i = 0; i<20; i++){
arr[i] = min + rand() % (max+1 - min);}
for(i = 0; i<20; i++){
printf("%d. %d\n", j, arr[i]);
j++;}
return arr[20];}
int evenodd(int arr[], int size){
int i, holder, sum, index = 1;
holder = arr[i];
for(i = 0; i<20; i++){
if (holder>0){
if (holder%2 == 0){
sum = sum;}
else{
sum += i;}}
else{
sum = sum;}}
printf("\nThe sum of all odd positive numbers is %d.", sum);
for(i = 1; i<20; i++){
int top = arr[0];
if (arr[i]<0){
if(arr[i]<top){
top = arr[i];
index = i;}
else{
top = top;}}
else{
top = top;}}
printf("\nThe index of the largest negative number is %d", index);}
int main()
{
int min, max;
printf("Please input the minimum desired random number: ");
scanf("%d", &min);
printf("\nPlease input the maximum desired random number: ");
scanf("%d", &max);
int a[20];
random(min, max, a);
evenodd(a, 20);
}
It prints out fine, but the sum of positive odd number is wrong, as well as the index of the largest negative number.
In your loop for(i = 1; i<20; i++) when finding negative numbers, you begin the loop by resetting the value of top to be arr[0], and thus you will always be doing your comparisons against the first value of the array. Perhaps you want to move that initialization out of the loop.
I see several issues with your code (especially with respect to your problem statement), but the summation procedure is not working because you are initializing variable "holder" only once, that too, before the for loop. Also, you are using an uninitialized varaible "i" as an index for the array arr. A lot can go wrong here!
By the way, Please use proper indentation to make your code more readable.
Four things
1) You did not initialize your sum to zero for odd positive numbers. So you should do that.
2) In calculating the sum you should do sum+=sum[i] and not sum+=i;
3) You initialized your index to 1 and not 0 for index of the largest negative number. If the first element is your smallest negative your answer should be zero. Right now for both first and second element you will give answer as 1. If you want a range from 1 to 20 you can output i+1 in the prints. I think you also have to do if(arr[i]>top) to find the largest negative integer assuming -10 is larger than -20 which is usually the case
4) Your implementation in three still wont account for the fact that no such number exists. What I recommend doing is initialize your top to largest negative integer. Range of values in C Int and Long 32 - 64 bits . And you can set your index to -1. Compare this to the entire array and if your index is -1 in the end. Then you print that no such element exists. You also have to check if the integer you are comparing is even. You can do the summing and the even negative integer in one loop as the two things are independent of each other

Find the sum of digits of a number(in c)

I need to find the sum of the digits of a number. For example, the sum of the digits of the number 1123 is 1+1+2+3 =7
My idea:
1)User enters and integer
2)I calculate the number of digits in the number(in case above - 4 digits)
3)Than using for loop I divide users number by 10 to the power of 1,2...till the number of digits(not including the last one) and sum the numbers.
Here is my code:
int main (void)
{
int result,sum,n;
int div = 10,counter = 0,number;
printf("Enter the integer:");
scanf("%i",&number);
while(result >0){
result = number/div;
div *= 10;
++counter;
}
printf("The number consists of %i digits\n",counter);
sum = 0;
for(n=1;n<counter;++n){
sum += number/pow(10,n);
}
printf("%i",sum);
return 0;
}
the first part(while loop) separately works correct. But together with second part(for loop) it gives me incorrect result(0 digits from the while loop and the sum is also zero). Can you explain why does it happen?
How can I correct my solution?
P.S I know that exist more efficient solutions of my problem, but i want to use my own algorithm.
Several problems here:
When you first enter the while loop, result has not been initialized. Attempting to read an uninitialized variable is undefined behavior.
When you do the division, you aren't adding digits. You're adding the number divided by successive powers of 10. In the case of 1123, you're actually adding 112 + 11 + 1. You need to use modulus instead of division to get the digits.
You can do the adding and counting of digits in a single loop as follows:
sum = 0;
while(number > 0){
sum += number % 10;
number /= 10;
++counter;
}
printf("The number consists of %i digits\n",counter);
printf("%i",sum);
much simpler:
result = number;
sum = 0;
counter = 0;
while(result != 0){
sum += result % 10;
result /= 10;
++counter;
}
printf ("Counter:%d sum:%d\n", counter, sum);
First of all, for best debugging, use a number which has different digits, like 12345.
To do debugging, calculate and print the digit separately from accumulating it. That is, instead of sum += <... complex code ...>, do it like this:
int digit = ...
printf("Next digit is %i\n", digit);
sum += digit;
Also (you should discover this by debugging, but it's obvious enough to note directly), your algorithm for calculation of digits is wrong. Do something like this:
int div = 1;
for (...)
{
digit = number / div % 10;
div *= 10;
}
Note that I don't use pow here, because pow uses floating-point arithmetic, which has limited accuracy. If your int has 64 bits of precision (unlikely but possible), floating-point will calculate nonsense for large numbers (it has only 53 bits of precision).
There are many errors in the code, but overall the whole approach is wrong. Counting the digits is unnecessary.
A simpler way would be:
unsigned temp = number, sum = 0;
while (temp) {
sum += temp % 10;
temp /= 10;
}
Notice that you know when to stop looping because temp becomes 0 (temp as a condition is equivalent to temp != 0). You don't need to know the number of digits in advance.
If going with your code, this'll work:
for(n=1;n<=counter;++n){
sum += number%10;
number /= 10;
}
printf("%d",sum);
Simpler solution:
int c, n=0, sum=0;
printf("Enter number");
while((c=getchar())!='\n') { // IMPORTANT: '\n' in unix, '\r' in windows
if(c<'0' || c>'9') {
printf("Bad value");
break;
}
sum+=c-'0'; // c is the ASCII code of the digit, so you have to subtract an offset
n++;
}
printf("Number of digits: %d", n);
printf("Sum of digits: %d", sum;

Finding prime number between 1 and N

In fact my teacher has passed the program that calculates the prime numbers from 1 to N. But I did not understand some things in the code and would like to help.
In line 18 we have the following: for(j=2; j<=i/2; j++), because j was divided by 2? and why j start in 2? should not start i and j on 1?
#include <stdio.h>
int main() {
int i, j, n, isPrime; //isPrime is used as flag variable
/* Reads upper limit to print prime */
printf("Find prime numbers between 1 to : ");
scanf("%d", &n);
printf("\nAll prime numbers between 1 to %d are:\n", n);
/* Finds all Prime numbers between 1 to n */
for(i=2; i<=n; i++) {
/* Assume that the current number is Prime */
isPrime = 1;
/* Check if the current number i is prime or not */
for(j=2; j<=i/2; j++) {
/*
* If i is divisible by any number other than 1 and self
* then it is not prime number
*/
if(i%j==0) {
isPrime = 0;
break;
}
}
/* If the number is prime then print */
if(isPrime==1) {
printf("%d is Prime number\n", i);
}
}
return 0;
}
should not start i ... on 1?
Yes, i should at 1. Consider that the current code will evolve. Later code may look like the below. Notice the comment and code matches your contract "numbers between 1 and N". No implied short-cut starting at 2, but clarity that code is properly testing all numbers [1...N].
/* Finds all Prime numbers between 1 to n */
for(i=1; i<=n; i++) {
if (IsPrime(i)) {
printf("%d is Prime number\n", i);
}
}
The point is that as a programmer, you are given the task "Finding prime number between 1 and N". A common sub-task is to code bool IsPrime(int i). Certainly if you code everything together, i can start at 2 - we know 1 is not a prime. Yet good programming begins with software architecture and that involves divide and conquer. So making a stand-alone helper function that works for all input is a good first step.
should not start j ... on 1?
No. Now code is into its find-a-prime algorithm and starting j=1 would fail.
bool IsPrime(int i) {
if (i <= 1) return false; // Cope with negative, 0, and 1.
for (int j=2; j<=i/2; j++) {
if (i%j==0) {
return false;
}
}
return true;
}
Of course, we can optimize IsPrime() in many ways.
The first prime number is 2 -- which is why you start as 2 -- everything is divisible by 1, and if you start there your algo will fail.
You end with N/2 because testing larger number will not result in anything that you would not have found, simply because to be a non-prime means that you will have to have to have at least 2 factors, and the smallest prime is 2 and 2*(i/2) >= i -- but in reality it is better and safe to stop at square root of N (but maybe that is in the next lesson).
This starting at 2 and increment the loop by one is wasteful -- since all primes except 2 is odd it would be better to start at 3 and increment by 2, and just make a special test for dividing by 2 outside the loop.
The first prime number is known to be 2, so there is no reason to start with 1. Given number i, there is no reason to try to divide it by numbers greater than its half, as the result will always be less than 2 and yield a quotient of 0 and a non-zero remainder (unless we divide it by itself, which is pointless in the prime test).
This is the easiest way:
#include <iostream>
using namespace std;
int main (){
int first,second;
cout<<"Enter starting of limit";
cin>>first; //First value
cout<<"Enter Ending of limit";
cin>>second; //Second value
L:
if(first < second){ //Checking starts here
if(first % 2 != 0 && first % 5 != 0 || first - 5 == 0 && first % 7 != 0){
cout<<first<<endl;
first++ ;
goto L; //Iteration
}
}
}
#include<stdio.h>
int main()
{
int num,i,count,n;
printf("Enter max range:");
scanf("%d",&n);
for(num=1; num<=n; num++)
{
count=0;
for(i=2; i<=num/2; i++)
{
if(num%i==0)
{
count++;
break;
}
}
if(count==0 && num!=1)
printf("%d ",num);
}
return 0;
}

Resources