I am trying to write a program for gcd(Greatest Common Divisor),I know the code is really long and inefficient but still it should run. It is taking the input of numbers but not executing the final printf statement and not doing the processing of decision making blocks. Can u tell me what am I doing wrong here?
#include <stdio.h>
void main()
{
int a, b;
printf("Enter the nos for gcd:");
scanf("%d\n%d", &a, &b);
int temp;
if (a > b)
{
for (int i = 0; i <= b; i++)
{
if ((a % i == 0) && (b % i == 0))
{
temp = i;
}
}
}
else if (a == b)
{
for (int i = 0; i <= a; i++)
{
if ((a % i == 0) && (b % i == 0))
{
temp = i;
}
}
}
else if (b > a)
{
for (int i = 0; i <= a; i++)
{
if ((a % i == 0) && (b % i == 0))
{
temp = i;
}
}
}
printf("Gcd for %d and %d is:%d", a, b, temp);
}
I tried making program for gcd and` was expecting the same
After reviewing your code and the good comments above, I decided it might be beneficial to you to distill these comments into what I found in debugging your program and providing how these good comments could be illustrated in a refactored version of your code for your edification.
First off, when I compiled and tested your program, I received a segmentation fault. This was due to the issue with your "for" loop values starting with a value of zero.
for (int i = 0; i <= b; i++)
That, coupled with attempting to find the modulo value of zero causes a "divide by zero" situation, which is not defined.
Revising each "for" loop from "int i = 0" to "int i = 1" gets one past the segmentation fault and allows the program to function.
#Vera:~/C_Programs/Console/GCDenominator/bin/Release$ ./GCDenominator
Enter the nos for gcd:45
60
Gcd for 45 and 60 is:15
The other thing I observed and was noted by the commentators is the fact that the program, as is, is repeating the same essential "for" loop three times for conditions of "a > b", "a == b", and "b > a". Seeing basically redundant code like that should be a signal that there could be a better way to streamline the use of "for" loops to possibly one iteration of the "for" loop. With that in mind, following is a refactored version of your program.
#include <stdio.h>
int main()
{
int a, b, c, temp;
printf("Enter the nos for gcd:");
scanf("%d\n%d", &a, &b);
if (a > b) /* Place the greater value into a work variable to simplify the loop test */
{
c = a;
}
else
{
c = b;
}
for (int i = 1; i <= c; i++) /* Start at "1" - otherwise a program dump can occur */
{
if ((a % i == 0) && (b % i == 0))
{
temp = i;
}
}
printf("GCD for %d and %d is:%d\n", a, b, temp);
return 0; /* Customary for the main function to return an integer */
}
Some points to note.
As noted in the comments above, you had defined the main function to not return a value (void); however, it is usual and customary for the main function to return an integer value, so the main function was redefined as such.
An additional work variable is added and used to contain the greater of the first or second value entered and then used in a single "for" loop to streamline the testing of greatest common denominator.
As noted earlier, the initial value for the "for" loop is "1" rather than "0" to avoid the segmentation fault being received when running the initial version of the program.
Following were some sample tests of the revised program.
#Vera:~/C_Programs/Console/GCDenominator/bin/Release$ ./GCDenominator
Enter the nos for gcd:45
60
GCD for 45 and 60 is:15
#Vera:~/C_Programs/Console/GCDenominator/bin/Release$ ./GCDenominator
Enter the nos for gcd:60
45
GCD for 60 and 45 is:15
#Vera:~/C_Programs/Console/GCDenominator/bin/Release$ ./GCDenominator
Enter the nos for gcd:144
144
GCD for 144 and 144 is:144
#Vera:~/C_Programs/Console/GCDenominator/bin/Release$ ./GCDenominator
Enter the nos for gcd:43
67
GCD for 43 and 67 is:1
Again, review this possible solution along with the helpful comments provided as you learn C programming. And, it probably would be a great idea to acquire some tutorial books on the C programming language as they usually have solid information on the language along with proven coding techniques.
Try this out and see if it meets the spirit of your project.
Related
Question :
Write a guessing game where the user has to guess a secret number. After every guess the program tells the user whether their number was too large or too small. At the end the number of tries needed should be printed. It counts only as one try if they input the same number multiple times consecutively.
My code :
#include<stdio.h>
#include<stdlib.h>
int compare(int m) {
int b;
b=73-m; ///I chose my number as 73 here.
if (b=0) printf("Congrats, you won.");
else {
if (-5 < b < 5) printf("Very Close\n"); ///always gives me this output two times.
else {
if (-15 < b < 15) printf("Close");
else {
printf("You are far");
}
}
}
return b;
}
int main() {
int arr[100],guess,count=0,i,m; ///I have 99 tries.
arr[0]=0;
for(i=1 ; i<=100 ; i++) {
printf("Enter your guess\n");
scanf("%d",&guess);
if(guess==arr[i-1]) {
arr[i]=guess;
printf("Guess is same as the previous input.\n");
} else {
arr[i]=guess;
compare(guess);
if (m = compare(guess)) {
count=count+1; /// can i create a separate function to keep the count?
printf("%d is the number of tries.\n",count);
break;
} else {
printf("\n");
}
}
}
return 0;
}
This is always giving me the same output two times i.e "Very close Very close". This is either faulty code (syntax) or wrong logic, I think. Also I want to know a better algorithm/logic with the code to solve this question (possibly shorter). Lastly I am new to programming with C as my first language.
The condition -5 < b< 5 is equal to (-5 < b) < 5, which means you compare the boolean (0 or 1) result of -5 < b with 5.
If you need to compare b to a range you need to do -5 < b && b < 5. I.e. compare b explicitly against both ends of the range.
Also, b = 0 is assignment not comparison, you need to use == for comparison.
I am starting to teach myself C and am trying to build a group of useful functions and programs for future reference. If relevant, this is C99.
Here is my most recent iteration of the program. At the output, I want to get the prime factorization of a number n. As is, however, I get a list of all factors, and no factors are repeated. I included some print statements to try and debug, and have found that the error is with the recursion, but can't figure out how to interpret it further. I previously tried making the recursive function of type int, but had difficulties getting it to work with the array p.
n is the number that I am trying to factor
p is an array for storing the found primes
j is an index for p
c is the number that I am testing as a divisor to n
I am aware that there are probably more efficient ways to declare p to save memory, but since this is mainly for reference, memory is not a huge concern.
I found these questions but don't think that they answer my question
finding greatest prime factor using recursion in c :This question is about crashing code. Mine compiles, runs, and produces reasonably sensible output, I'm just wondering why the output isn't what I expect.
is there ever a time you would not use recursion? [closed] :This indicates that recursion is not a good choice for prime factorization- I don't know, but suspect that this would also apply to C. Since this is for reference, I don't think it is a huge issue. If you disagree, please explain why.
My main questions are these:
Why does the output show all factors of n?
Why does it not repeat the prime factors?
What do I have to do to fix it?
#include <stdio.h>
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
void factors(int n, int p[], int j) {
/// if n is divisible by c, store c, and continue with n/c
int c;
for (c=2; c < n; c++) {
if (c > n) break;
if (n%c == 0) {
p[j] = c;
printf("%d has been added to p \t", c);
printf("n has been reduced to %d \t", n/c);
printf("j is %d \n", j);
j++;
if (n == c) break;
factors(n/c, p, j);
}
}
}
int main() {
/// set up number to factor, and array to hold factors
int n = 24;
int p[n/2];
int i=0;
for (i=0; i<NELEMS(p); i++) {
p[i]=0;
}
int j = 0;
factors(n, p, j);
printf("the prime factors of %d are:\n",n);
for (i=0; i<NELEMS(p); i++) {
printf("%d \n", p[i]);
}
}
You have already been told in comments that this algorythm is poor, which is an evidence here. And you really should learn to use a debugger: running this through a debugger immediately shows where the problems are.
That being said, your main problem here is what to do when the recursive functions return?. You failed to ask yourself this question which is a must in recursion, and simply continue in sequence, which is plain wrong because you will reuse a number that has already been processed in the recursive calls. So you must add a return line immediately after recursively calling factors.
Once this is done, there is another minor problem (that a debugger would make evident), you only search factors strictly lesser that n. So you miss the last prime factor...
With those 2 immediate fixes, your code becomes:
void factors(int n, int p[], int j) {
/// if n is divisible by c, store c, and continue with n/c
int c;
for (c=2; c <= n; c++) {
if (c > n) break;
if (n%c == 0) {
p[j] = c;
printf("%d has been added to p \t", c);
printf("n has been reduced to %d \t", n/c);
printf("j is %d \n", j);
j++;
if (n == c) break;
factors(n/c, p, j);
return;
}
}
}
But IMHO p[j] = c; should become *p = c; and factors(n/c, p, j); should become factors(n/c, p+1, j);. Said differently you pass directly a pointer to the next slot.
Edit It occurs to me that the smallest factor of n is guaranteed to be prime, so I have edited the answer accordingly.
Why does the output show all factors of n?
Because you test if c is a factor of n and add it to the array p whether c is prime or not. Then you carry on testing numbers above c, even multiples of c.
Why does it not repeat the prime factors?
Because when you find a number c that is a factor, you don't necessarily inspect it to find out if it is a compound number itself.
After adding c to p, you need to recursively call factor on (n / c) and then stop.
Here is roughly what you need (but not tested or even compiled)
int factorise(int n, int p[], int j)
{
int factorsFound = 0;
for (c = 2 ; c * c <= n && factorsFound == 0 ; ++ c)
{
if (n % c == 0)
{
p[j] = c;
factorsFound = factorise(n / c, p, j + 1) + 1;
}
}
if (factorsFound == 0) // n is prime
{
p[j] = n;
factorsFound = 1;
}
return factorsFound;
}
Also in a real solution, you probably want to pass the size of p so that you can detect if you run out of space.
Just for fun, since nobody else has posted it yet, here is a non recursive solution. It's actually the same as above but the recursion has been transformed into a loop.
int factorise(int number, int p[])
{
int j = 0;
for (int c = 2, int n = number ; n > 1 ; )
{
if (n % c = 0)
{
p[j++] = c;
n = n / c;
}
else
{
c++;
}
}
return j;
}
I disagree with some of Lundin's comments about recursion. Recursion is a natural way of breaking a problem down into easier subtasks but in C it is undeniably less efficient, especially in terms of stack space and in this particular case, the non recursive version is simpler.
From This answer:
why does recursion cause stackoverflow so much more than loops do
Because each recursive call uses some space on the stack. If your recursion is too deep, then it will result in StackOverflow, depending upon the maximum allowed depth in the stack.
When using recursion, you should be very careful and make sure that you provide a base case. A base case in recursion is the condition based on which the recursion ends, and the stack starts to unwind. This is the major reason of recursion causing StackOverflow error. If it doesn't find any base case, it will go into an infinite recursion, which will certainly result in error, as Stack is finite only.
-
It appears that your for is in the way, c will increment, and wont check that same value again.
For instance, if the input is 8, we want (2,2,2) and not (2,4).
I would recommend replacing your if (c%n ==0) by a while, don't forget to replace the value of n in that while, you don't want to loop in that.
This appears to be a good answer :
int primes(int nbr, int cur)
{
if (cur > nbr)
return (0);
else
{
if (nbr % cur == 0 && isprime(cur) == 1)
{
printf("%d\n", cur);
return (primes(nbr / cur, 2));
}
return (primes(nbr, cur + 1));
}
}
Call that function with cur = 2 in your main
I need your help on this problem , I've been trying to solve it all day but I can't reach a solution.
I just started studying C so I apologize if it is a stupid question, however
I am only allowed to use:
if
for
do-while
while
statements to solve the problem.
I need to check whether or not a given number can be written as the sum of two squares, I do not need to know which are these two squares, and I do not need to analyze cases when the number is 0 or 1. What I've managed to build till now is:
unsigned int x;
unsigned int q = 1;
printf("Enter a number : \n");
scanf("%u", &x);
unsigned int j = sqrt(x - (q*q));
if (x != 1 && x != 0)
for (q; (q*q) <= (x/2); q++)
if ((x - (q*q)) == (j*j))
printf("Given number is sum of two squares");
This one sometimes works and sometimes doesn't, for example it does work for 65 (8^2+1^2) and 90 (9^2+3^2) but wouldn't work when I put 181 (10^2+9^2) and so on..
Do you have any idea how I can fix this?
Ok, so here's pseudo code for a possible solution:
Input x;
int a;
int b;
for(a=0; a <= x; a++){
for(b=a; b <= x; b++){
if((a*a + b*b) == x){
Output is_solution;
}
}
}
In the nested loop, b is assigned the value of a to avoid checking the same sum of squares more than once.
Converting this to C, should look like this:
unsigned int x;
unsigned int a;
unsigned int b;
printf("Enter a number : \n");
scanf("%u", &x);
for(a=0; a<=x; a++){
for(b=a; b<=x; b++){
if((a*a + b*b) == x){
printf("Given number is sum of two squares");
}
}
}
I'm a bit rusted in C, hopefully it doesn't have any nasty errors.
You need to put the calculation of j inside the for loop. Currently, you only calculate j for q=1.
I recommend putting the blocks of the loops and the if into braces. I.e.,
if(condition)
{
// statements
}
Been trying to write program for displaying prime numbers and just wanted to know if there is much difference between the following two algorithms.
1,
#include <stdio.h>
#define MAXNUMB 100000
int main(void){
int flag;
long i,j=MAXNUMB;
printf ("The Prime Numbers up to %ld are:\n 2\n", j);
for(i=3 ; i<=MAXNUMB; i = i+2){
j = 3; //only difference is in this line
flag = 0;
while((j*j <= i) && flag == 0){
if(i%j == 0){
flag = 1;
}
j++;
}
if (flag == 0){
printf("%8ld\n",i);
}
}
}
2,
#include <stdio.h>
#define MAXNUMB 100000
int main(void){
int flag;
long i,j=MAXNUMB;
printf ("The Prime Numbers up to %ld are:\n 2\n", j);
for(i=3 ; i<=MAXNUMB; i = i+2){
j = 2; //again this is the only different line
flag = 0;
while((j*j <= i) && flag == 0){
if(i%j == 0){
flag = 1;
}
j++;
}
if (flag == 0){
printf("%8ld\n",i);
}
}
}
It seems to me that both work but im not sure, maybe someone can shed some light.
Also, any general tips for someone starting to code, that apply for all programmers?
Thanks!
They both have the same output because you're skipping over even numbers with i = i + 2 and starting the loop with i = 3. So the i % j == 0 condition will never be true when j = 2.
To me it seems like they have the same output but i cant check every number
Wrap your approaches into separate functions, return the results in an array and then compare both arrays.
You can very quickly see the time it takes for these to complete with the built in time function for GNU/Linux or Cygwin. Using the G++ compiler, it takes around 0.109s to run the first snippet and around 0.141s to run the second one. So I guess it depends on what your definition of "more efficient" is. Note: I did not check for the accuracy of the results, just running the programs as they are.
As for general programming tips, you have access to boundless information on the internet, just search up programming tips. One could write an entire book on "tips" for a beginning programmer. Here is a good example.
like 17, is a prime, when reversed, 71 is also a prime.
We manage to arrive at this code but we cant finish it.
#include <stdio.h>
main()
{
int i = 10, j, c, sum, b, x, d, e, z, f, g;
printf("\nPrime numbers from 10 to 99 are the follwing:\n");
while (i <= 99)
{
c=0;
for (j = 1; j <= i; j++)
{
if (i % j == 0) c++;
}
if (c == 2)
{
b = i;
d = b / 10;
e = b - (10 * d);
x = (e * 10) + d;
{
z = 0;
f = x;
for (j = 1; j <= f; j++)
{
if (f % j == 0) z++;
}
if (z == 2)
{
printf("%d %d\n", i, f);
}
}
}
i++;
}
getch();
}
my problem is how to add all the fs..
the answer should be 429.
how can i add all the f?
Why don't you break up the code into some functions:
bool isPrime(int number) that checks if a number is prime.
int reverse(int number) that reverses the number.
Then the algorithm would be:
sum = 0;
for (i = 2; i <= 99; ++i)
if (isPrime(i) && isPrime(reverse(i)))
sum += i;
At the beginning initialize sum = 0;. Then, next to your printf count the prime: sum += i;. you can then print it at the end.
If this is a basic programming class and you are just interested in the result then this will get you there, however if it is an algorithms class then you may want to look at the Sieve of Eratosthenes.
You may also want to think about what makes a 2 digit number the reverse of another 2 digit number and how you would express that.
There are many problems in your code. None of them will prevent compilation and none of them will cause problems in getting the output. I'll first tell you how to get the result you want and then highlight the problems.
Here is your code, modified to sum fs. You just need to add f to sum every time you print a prime satisfying the condition. Finally, you should print the sum of all fs.
#include <stdio.h>
//Use int as the return type explicitly!
int main()
{
int i=10,j,c,sum,b,x,d,e,z,f,g;
printf("\nPrime numbers from 10 to 99 are the follwing:\n");
//Set the sum of all primes whose reverse are also primes to zero
sum = 0;
while(i<=99)
{
//c is tyhe number of factors.
c=0;
for(j=1;j<=i;j++)
{
if(i%j==0)
c++;
}
//If there are only two factors.
//Two factors (1 and itself) => Prime
if(c==2)
{
//Reverse i and store it in x
b=i;
d=b/10;
e=b-(10*d);
x=(e*10)+d;
//Curly braces unnecessary
{
//Check if the reverse i.e. x is prime
//z is the number of factors
z=0;
//f is the number being tested for primality.
f=x;
for(j=1;j<=f;j++)
{
if(f%j==0)
z++;
}
//If f i.e. x i.e. the reverse has only two factors
//Two factors (1 and itself) => Prime
if(z==2)
{
//print the prime number.
printf("%d %d \n",i,f);
//Add f to the sum
sum += f;
}//if(z==2)
}//Unnecessary braces
}//if(c==2)
i++;
}//end while
//print the number of reversed primes!!
//That is sum of the reversed values of numbers satisfying the
//condition!
printf("\nThe sum is:%d\n", sum);
//getch() is non standard and needs conio.h
//Use getchar() instead.
//Better solution needed!!
getchar();
//Return 0 - Success
return 0;
}
Output
...#...-desktop:~$ gcc -o temp temp.c
...#...-desktop:~$ ./temp
Prime numbers from 10 to 99 are the follwing:
11 11
13 31
17 71
31 13
37 73
71 17
73 37
79 97
97 79
The sum is:429
...#...desktop:~$
Do take note of all the comments made in the code (above). In addition, consider doing the following:
Removing the unnecessary braces.
Using one variable for one thing. (x could have been used instead of f).
Using better variable names like number and numberOfFactors.
Breaking up your code into functions as Mehrdad Afshari has suggested.
Consider testing primality by checking if there is a divisor of the number (num) being tested up to sqrt(num) (Square root of the number).
Consider this:
For numbers upto 99, the reversed numbers are also 2 digit numbers.
If the number is in the set of primes already found, you can verify easily.
This will reduce the number of checks for primality. (which are expensive)
To do the above, maintain a list of primes that have been identified (primeList)
as well as a list of reversed primes (revList). Any item in revList that is also
in primeList satisfies your condition. You can then easily obtain the sum (429)
that you need.
Look at sweet61's answer, the use of the Sieve of Eratosthenes with my method will definitely be much more efficient. You can reverse primes at the end of the sieve and populate the revList (at the end).
On a personal level, I try to find the best solution. I hope you will also attempt to do the same. I have tried to help you out without giving it all away.
I hope this helps.
Note
I had suggested checking for divisors up to num/2. I fixed it to sqrt(num) on vartec's suggestion.