0

I'm supposed to implement a function that finds the middle number from three numbers given as input. All inputs are positive integers. I seem to not be treating a special case which is causing my program to fail some tests, but with a VERY small margin. I mean 1.46 standard deviation for 8bit pixel values, so the cases I'm missing ought to be very specific and rather few in between.

As I'm understanding this problem, there's three possibilities for the numbers:

  1. They are all equal, so return either
  2. Two of them are equal, thus return the smaller one (larger one doesn't work either)
  3. They're all different, thus find the middle value

There either is a fourth case I'm not seeing or I've missed something for the above three. I can't use libraries for sorting.

int middle(int a, int b, int c)
{
    if (a == b && b == c)
    {
        return c;
    }

    if ((a < b && b < c) || (c < b && b < a))
    {
        return b;
    }

    if ((b < a && a < c) || (c < a && a < c))
    {
        return a;
    }

    if ((a < c && c < b) || (b < c && c < a))
    {
        return c;
    }

    if (a == b || b == c || a == c)
    {
        if (a == b && a < c)
        {
            return c;
        }
        else
        {
            return a;
        }

        if (b == c && b < a)
        {
            return a;
        }
        else
        {
            return b;
        }

        if (a == c && a < b)
        {
            return b;
        }
        else
        {
            return c;
        }

    }

return c; // code sometimes reaches this point; it shouldn't
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
Andrei
  • 59
  • 5
  • 2
    please include example input for a case that fails and please tag the language you are using only – 463035818_is_not_an_ai Apr 20 '22 at 13:27
  • C and C++ are two different languages; only tag the one you are using. – ChrisMM Apr 20 '22 at 13:27
  • `if ((b < a && a < c) || (c < a && a < c))` this is wrong. – ChrisMM Apr 20 '22 at 13:28
  • frankly your code is too compilcated. You need to distinguish only 1 case: `a`, `b` and `c` are three numbers ;). Sort them, then return the middle one – 463035818_is_not_an_ai Apr 20 '22 at 13:28
  • by middle number do you mean that in terms of value, i.e. the number that best approximates the average or mean? – ryyker Apr 20 '22 at 13:29
  • `if (a == b && a < c) { return c; } else { return a; }` will *always* return, unconditionally. – Some programmer dude Apr 20 '22 at 13:29
  • Ok guys i've removed the C++ tag. I don't have access to the cases in which it fails as the verification is done on some test images. It expects a std deviation of 0 and only outputs the std deviation value. – Andrei Apr 20 '22 at 13:30
  • FWIW, sorting 3 variables is pretty trivial and makes picking the middle element really easy. examples can be seen here: https://stackoverflow.com/questions/4367745/simpler-way-of-sorting-three-numbers – NathanOliver Apr 20 '22 at 13:30
  • 1
    With only three numbers, the possible combinations to get the middle (or largest, or smallest) is limited (there are just three). You can easily get all three cases with the same condition, by just rotating the variables. – Some programmer dude Apr 20 '22 at 13:31
  • @Andrei If two of three numbers are equal then you should return one of the equal numbers. – Vlad from Moscow Apr 20 '22 at 13:36

2 Answers2

2

This case here:

if ((b < a && a < c) || (c < a && a < c))

is incorrect. It should be:

if ((b < a && a < c) || (c < a && a < b))

Further, in the

if (a == b || b == c || a == c)

Section, you have

if (...)
    return ...
else
    return ...

This will always return, and ignore the if statements following it.

That said, it would be a lot easier to sort the 3 values, then return b

if ( b < a ) {
    int t = a;
    a = b;
    b = t;
}
if ( c < b ) {
    int t = c;
    c = b;
    b = t;
}
if ( b < a ) {
    int t = a;
    a = b;
    b = t;
}
return b;
ChrisMM
  • 8,448
  • 13
  • 29
  • 48
1

In the interest of promoting simplicity when it is available, with only three values to compare, it is completely reasonable to use a single expression to determine and return the middle value. The following uses nested ternary operators to do this. It is tested with the inputs shown in the code:

int main(int argc, char *argv[])
{
//  int val[] = {7,12,1};
//  int val[] = {0,0,1};
    int val[] = {-1,-4,-2};
//  int val[] = {7,6,2};
//  int val[] = {100,99,103};
    
    printf ("middle value is: %d\n", return_middle(val[0], val[1], val[2]));
    return 0;
}

int return_middle(int a, int b, int c)
{
    return a>b ? ( c>a ? a : (b>c ? b : c)) : (c>b ? b : ( a>c ? a : c));
}
ryyker
  • 22,849
  • 3
  • 43
  • 87