Home > Enterprise >  My recursive function only calculates half of even numbers
My recursive function only calculates half of even numbers

Time:09-29

#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?

CodePudding user response:

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.

CodePudding user response:

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( "=/2 = %d\n", vals[i], half1( vals[i] ) );

    return 0;
}
 30/2 = 15
 17/2 = 8
-42/2 = -21
  0/2 = 0

CodePudding user response:

nice puzzle, I'll give you my answer in python because I don't remember C

def half(x):
   def inner(x, y):
      if is_zero(y) or not is_positive(y):
         return x
      else:
         return inner(pred(x), pred(pred(y)))
   return inner(x, x)
  • Related