My recursive greatest common denominator function isn't working properly - c

I'm trying to create a GCD (greatest common denominator) function using recursion.
I cannot understand why it isn't working properly.
For input 10 and 50 is returning 36.
Here's my code:
int main()
{
printf("Rez=%d ", gcd(10,50));
return 0;
}
int gcd(int a, int b)
{
static int n=0;
int result=1;
n++;
if(a<=1 || b<=1)
return 1;
else
{
if(a%n==0 && b%n==0)
result=n* gcd(a/n,b/n);
else
gcd(a,b);
}
return result;
}

Using a static variable is a problem because you use it in the form n * gcd(...) and the value of n shouldn't be the same than that used by the recursion. So you should pass a parameter instead. You should also add a condition to stop when n becomes greater than the smaller term :
#include <stdio.h>
int main()
{
printf("%d\n", gcd(10, 50, 1)); //==>10
printf("%d\n", gcd(7, 35, 1)); //==>7
printf("%d\n", gcd(8, 22, 1)); //==>2
printf("%d\n", gcd(49, 5, 1)); //==>1
printf("%d\n", gcd(0, 0, 1)); //==>1
printf("%d\n", gcd(4, 2, 0)); //==>0
return 0;
}
int gcd(int a, int b, int n)
{
if (n <= 0) return 0;
if (n > (a < b ? a : b) || a<=1 || b<=1) return 1;
else if(a%n==0 && b%n==0) return n * gcd(a/n, b/n, n+1);
else return gcd(a, b, n+1);
}

the static variable is the cause for the error. In
result=n* gcd(a/n,b/n);
n is evaluated after the recursion is called. So, as your recursion stops when you call gcd( 5/5, 25/5 ) and n is incremented to 6 by that call you just have
6 * gcd( 10/1, 50/1 ) = 6 * 6 * gcd( 10/2, 50/2 ) = 6 * 6 * 6 = gcd( 5/5, 25/5 ) = 6 * 6 * 6 * 1 = 216

Related

My recursive function only calculates half of even numbers

#include <stdio.h>
int succ(int x) {
return x+1;
}
int pred(int x) {
return x-1;
}
int is_zero(int x) {
return x == 0;
}
int is_pos(int x) {
return x >= 0;
}
int half(int x, int y) {
return is_zero(y) ? x: half(pred(x), pred(pred(y)));
}
int half1(int x) {
return half(x,x);
}
int main() {
int x;
scanf("%d", &x);
int z = half1(x);
printf("%d\n", z);
return 0;
}
This is one of the first exercises I received in college and I am having a little difficulty. I can only use the functions succ,pred,is_zero,is_pos to make a recursive function that calculates half of a number and I can't use if or while. I made this code, but it only works for even numbers, for example input=30 output=15 but if input=17 it will not return an output. Any tips?
What happens when you try half1(17)?
half1(17)
half(17, 17)
half(pred(17), pred(pred(17)))
half(16, pred(16))
half(16, 15)
half(15, 13)
half(14, 11)
half(13, 9)
half(12, 7)
half(11, 5)
half(10, 3)
half(9, 1)
half(8, -1)
half(7, -3)
...
y in this case will never equal 0, so the recursion never ends.
You want to check if y is negative (not positive) or equal to zero.
int half(int x, int y) {
return !is_pos(y) || is_zero(y) ? x : half(pred(x), pred(pred(y)));
}
Now, the recursion will end with half(8, -1) and 8 will be returned.
Nesting AND recursion? Too complicated for my little brain... Trying to double increment one parameter while aiming for a particular target (zero)? Could be tricky to get the conditionals right (as comments and another answer have already indicated.)
Why not simply "meet in the middle"?
#include <stdio.h>
int succ(int x) { return x+1; }
int pred(int x) { return x-1; }
// int is_zero(int x) { return x == 0; }
int is_pos(int x) { return x >= 0; }
int half( int l, int h ) {
return is_pos( l - h ) ? h : half( succ(l), pred(h) );
}
int half1( int x ) {
// terms are multiplied by 0 or 1 depending on x being +/-.
return half( (!is_pos(x))*x, is_pos(x)*x );
}
int main() {
int vals[] = { 30, 17, -42, 0 };
for( int i = 0; i < sizeof vals/sizeof vals[0]; i++ )
printf( "%3d/2 = %d\n", vals[i], half1( vals[i] ) );
return 0;
}
30/2 = 15
17/2 = 8
-42/2 = -21
0/2 = 0

Unexpected result of trace table

I am a newborn programmer and i've been studying trace tables thus far. However, it seems i'm unable to understand this one. By what i could gather the function would return (-15) as the variable 'a' receives 25 and later the 'num', which is 10, is subtracted by the former.
Yet it seems i'm wrong by PythonTutor's calculations and i still cannot get why num is still 10 after all that C magic. Would someone be so kind to explain why is this happening?
#include <stdio.h>
int num;
int func(int a, int b);
int main() {
int first = 0, sec = 50, num2;
num = 10;
num += func(first, sec);
printf("\nnum = %d\tfirst = %d\tsec = %d", num, first, sec);
return 0;
}
int func(int a, int b) {
a = (a + b) / 2;
num -= a;
return a;
}
Would someone be so kind to explain why is this happening?
Let us take this step by step
int num;
int func(int a, int b);
int main() {
// 1) `num == 0` as it is a global variable without explicit initialization.
int first = 0, sec = 50, num2;
// 2) `num` is 10
num = 10;
// 3) Before the function call, `num` is 10
num += func(first, sec);
// 7) At the end of the function call, `num` is -15 and
// the return value of 25 is added to it due to +=.
// 8) `num` is now 10 again.
printf("\nnum = %d\tfirst = %d\tsec = %d", num, first, sec);
return 0;
}
int func(int a, int b) {
a = (a + b) / 2;
// 4) `a` is 25, `num` is 10
// 5) `num` becomes 10 - 25 --> -15
num -= a;
// 6) `a == 25` and 25 is returned
return a;
}

How do I reverse the order of the digits of an integer using recursion in C programming?

Problem statement :
Given a 32-bit signed integer, reverse digits of an integer.
Note: Assume we are dealing with an environment that could only store
integers within the 32-bit signed integer range: [ −2^31, 2^31 − 1]. For
the purpose of this problem, assume that your function returns 0 when
the reversed integer overflows.
I'm trying to implement the recursive function reverseRec(), It's working for smaller values but it's a mess for the edge cases.
int reverseRec(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverseRec(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
I've implemented non recursive function which is working just fine :
int reverse(int x)
{
long long val = 0;
do{
val = val*10 + (x%10);
x /= 10;
}while(x);
return (val < INT_MIN || val > INT_MAX) ? 0 : val;
}
Here I use variable val of long long type to check the result with MAX and MIN of signed int type but the description of the problem specifically mentioned that we need to deal within the range of 32-bit integer, although somehow it got accepted but I'm just curious If there is a way to implement a recursive function using only int datatype ?
One more thing even if I consider using long long I'm failing to implement it in the recursive function reverseRec().
If there is a way to implement a recursive function using only int datatype ?
(and) returns 0 when the reversed integer overflows
Yes.
For such +/- problems, I like to fold the int values to one side and negate as needed. The folding to one side (- or +) simplifies overflow detection as only a single side needs testing
I prefer folding to the negative side as there are more negatives, than positives. (With 32-bit int, really didn't make any difference for this problem.)
As code forms the reversed value, test if the following r * 10 + least_digit may overflow before doing it.
An int only recursive solution to reverse an int. Overflow returns 0.
#include <limits.h>
#include <stdio.h>
static int reverse_recurse(int i, int r) {
if (i) {
int least_digit = i % 10;
if (r <= INT_MIN / 10 && (r < INT_MIN / 10 || least_digit < INT_MIN % 10)) {
return 1; /// Overflow indication
}
r = reverse_recurse(i / 10, r * 10 + least_digit);
}
return r;
}
// Reverse an int, overflow returns 0
int reverse_int(int i) {
// Proceed with negative values, they have more range than + side
int r = reverse_recurse(i > 0 ? -i : i, 0);
if (r > 0) {
return 0;
}
if (i > 0) {
if (r < -INT_MAX) {
return 0;
}
r = -r;
}
return r;
}
Test
int main(void) {
int t[] = {0, 1, 42, 1234567890, 1234567892, INT_MAX, INT_MIN};
for (unsigned i = 0; i < sizeof t / sizeof t[0]; i++) {
printf("%11d %11d\n", t[i], reverse_int(t[i]));
if (t[i] != INT_MIN) {
printf("%11d %11d\n", -t[i], reverse_int(-t[i]));
}
}
}
Output
0 0
0 0
1 1
-1 -1
42 24
-42 -24
1234567890 987654321
-1234567890 -987654321
1234567892 0
-1234567892 0
2147483647 0
-2147483647 0
-2147483648 0
You could add a second parameter:
int reverseRec(int x, int reversed)
{
if(x == 0)
{
return reversed;
}
else
{
return reverseRec(x/10, reversed * 10 + x%10);
}
}
And call the function passing the 0 for the second parameter. If you want negative numbers you can check the sign before and pass the absolute value to this function.
In trying to learn C programming I programed this question and get some correct results and some incorrect. I don't see the reason for the difference.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h> // requires adding link to math -lm as in: gcc b.c -lm -o q11
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0) // if done returns value
{
return startValue;
}
int temp = startValue % 10; // gets units digit
int newStart = (startValue -temp)/10; // computes new starting value after removing one digit
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal); // calls itself recursively until done
}
int main()
{
int x, decimalP, startValue;
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
if (x > 214748364)
{
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
}
decimalP = round(log10(x)); // computes the number of powers of 10 - 0 being units etc.
startValue = ReverseInt(x, decimalP); // calls function with number to be reversed and powers of 10
printf("\n reverse of %d is %d \n", x, startValue);
}
Output is: reverse of 1234 is 4321 but then reverse of 4321 is 12340
It's late and nothing better does not come into my mind. No float calculations. Of course, integer has to be big enough to accommodate the result. Otherwise it is an UB.
int rev(int x, int partial, int *max)
{
int result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
int reverse(int x)
{
int max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d", reverse(-456789));
}
https://godbolt.org/z/M1eezf
unsigned rev(unsigned x, unsigned partial, unsigned *max)
{
unsigned result;
if(x / partial < 10)
{
*max = partial;
return (x % 10) * partial;
}
result = rev(x, partial * 10, max) + (x / (*max / partial) % 10) * partial;
return result;
}
unsigned reverse(unsigned x)
{
unsigned max;
return rev(x, 1, &max);
}
int main(void){
printf("%u", reverse(123456));
}
when using long long to store the result all possible integers can be reversed
long long rev(int x, long long partial, long long *max)
{
long long result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
long long reverse(int x)
{
long long max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d reversed %lld\n", INT_MIN, reverse(INT_MIN));
printf("%d reversed %lld\n", INT_MAX, reverse(INT_MAX));
}
https://godbolt.org/z/KMfbxz
I am assuming by reversing an integer you mean turning 129 to 921 or 120 to 21.
You need an initial method to initialize your recursive function.
Your recursive function must figure out how many decimal places your integer uses. This can be found by using log base 10 with the value and then converting the result to a integer.
log10 (103) approx. 2.04 => 2
Modulus the initial value by 10 to get the ones place and store it in a variable called temp
Subtract the ones place from the initial value and store that in a variable called newStart.
divide this value by 10
Subtract one from the decimal place and store in another variable called newDecimal.
Return the ones place times 10 to the power of the decimal place and add it to the function where the initial value is newStart and the decimalPlace is newDecimal.
#include <stdio.h>
#include <math.h>
int ReverseInt(int startValue, int decimalPlace);
int main()
{
int i = -54;
int positive = i < 0? i*-1 : i;
double d = log10(positive);
int output = ReverseInt(positive,(int)d);
int correctedOutput = i < 0? output*-1 : output;
printf("%d \n",correctedOutput);
return 0;
}
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0)
{
return startValue;
}
int temp = startValue % 10;
int newStart = (startValue -temp)/10;
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal);
}

Find the minimum number of steps to decrease N to zero

I'm facing some difficulties in the last few days while trying to finish the following task, I hope you guys can assist :
I'm given a single number N, and I'm allowed to perform any of the two operations on N in each move :
One - If we take 2 integers where N = x * y , then we can change the value of N to the maximum between x and y.
Two - Decrease the value of N by 1.
I want to find the minimum number of steps to reduce N to zero.
This is what I have so far, I'm not sure what is the best way to implement the function to find the divisor (someFindDevisorFunction), and if this 'f' function would actually produce the required output.
int f(int n)
{
int div,firstWay,secondWay;
if(n == 0)
return 0;
div = SomefindDivisorFunction(n);
firstWay = 1 + f(n-1);
if(div != 1)
{
secondWay = 1 + f(div);
if (firstWay < secondWay)
return firstWay;
return secondWay;
}
return firstWay;
}
For example, if I enter the number 150 , the output would be :
75 - 25 - 5 - 4 - 2 - 1 - 0
I see this a recursive or iterative problem.
OP's approach hints at recursive.
A recursive solution follows:
At each step, code counts the steps of the various alternatives:
steps(n) = min(
steps(factor1_of_n) + 1,
steps(factor2_of_n) + 1,
steps(factor3_of_n) + 1,
...
steps(n-1) + 1)
The coded solution below is inefficient, but it does explore all possibilities and gets to the answer.
int solve_helper(int n, bool print) {
int best_quot = 0;
int best_quot_score = INT_MAX;
int quot;
for (int p = 2; p <= (quot = n / p); p++) {
int rem = n % p;
if (rem == 0 && quot > 1) {
int score = solve_helper(quot, false) + 1;
if (score < best_quot_score) {
best_quot_score = score;
best_quot = quot;
}
}
}
int dec_score = n > 0 ? solve_helper(n - 1, false) + 1 : 0;
if (best_quot_score < dec_score) {
if (print) {
printf("/ %d ", best_quot);
solve_helper(best_quot, true);
}
return best_quot_score;
}
if (print && n > 0) {
printf("- %d ", n - 1);
solve_helper(n - 1, true);
}
return dec_score;
}
int main() {
int n = 75;
printf("%d ", n);
solve(n, true);
printf("\n");
}
Output
75 / 25 / 5 - 4 / 2 - 1 - 0
Iterative
TBD
If you start looking for a divisor with 2, and work your way up, then the last pair of divisors you find will include the largest divisor. Alternatively you can start searching with divisor = N/2 and work down, when the first divisor found will have be largest divisor of N.
int minmoves(int n){
if(n<=3){
return n;
}
int[] dp=new int[n+1];
Arrays.fill(dp,-1);
dp[0]=0;
dp[1]=1;
dp[2]=2;
dp[3]=3;
int sqr;
for(int i=4;i<=n;i++){
sqr=(int)Math.sqrt(i);
int best=Integer.MAX_VALUE;
while(sqr >1){
if(i%sqr==0){
int fact=i/sqr;
best=Math.min(best,1+dp[fact]);
}
sqr--;
}
best=Math.min(best,1+dp[i-1]);
dp[i]=best;
}
return dp[n];
}

C: Recursive function for inverting an int

I had this problem on an exam yesterday. I couldn't resolve it so you can imagine the result...
Make a recursive function: int invertint( int num) that will receive an integer and return it but inverted, example: 321 would return as 123
I wrote this:
int invertint( int num ) {
int rest = num % 10;
int div = num / 10;
if( div == 0 ) {
return( rest );
}
return( rest * 10 + invert( div ) )
}
Worked for 2 digits numbers but not for 3 digits or more. Since 321 would return 1 * 10 + 23 in the last stage.
Thanks a lot!
PS: Is there a way to understand these kind of recursion problems in a faster manner or it's up to imagination of one self?
int invertint( int num ) {
int i ;
for(i=10;num/i;i*=10);
i/=10;
if(i == 1) return num;
return( (num % 10) * i + invertint( num / 10 ) );
}
Your mistake is that in the last statement you are multiplying rest by 10. Why only 10? You need to shift the rest digit by as many digits as there are left in the remaining part of the number. You are shifting by only 1. No wonder it works only for 2-digit numbers.
The last part should be done along the lines of
int tail = invert( div );
int deg = /* number of digits in `tail` */;
return rest * (int) pow(10, deg) + div;
The problem is with return(rest * 10 + invert(div)). You can't do the multiplication yourself. The factor depends on the number of times the function is recursed, thus you have to provide the carry as a second argument to your function (carry is initialized with 0)
If you do it the other way, you won't need a counter.
int invertint(int num)
{
if (0 == num || 0 == num % 10) {
return num / 10;
}
int digits = floor(log10(num)) + 1;
int modulus = pow(10, digits - 1);
return invertint(num % modulus) * 10 + num / modulus;
}
Note that this isn't as simple as I originally thought - I had to use math.
int reverse(int no,int rev)
{
if(no!=0)
return reverse(no/10,rev*10+no%10);
else
return rev;
}
call this method as reverse(numberToReverse,0)
Just as an alternative, this could be done without recursion.
int invertint(int num)
{
int res = 0;
while (num != 0)
{
res = res * 10 + (num % 10);
num /= 10;
}
return res;
}
But since recursion was the assignment, given the int(int) signature, easiest would be with a pow(log10)) variation (provided that you're allowed to include math.h ? )
int invertint(int num)
{
if (num == 0) return 0;
return invertint(num / 10) + (int)pow(10, (int)log10(num)) * (num % 10);
}
This is the simplest approach.
int sum=0;
int reverse(int n)
{
if(n>0)
{
sum=(sum*10)+(n%10);
reverse(n/10);
}
return sum;
}

Resources