3

I have been going through some basic exercises from a recommended beginner's book: C Programming: A Modern Approach (2nd Edition)

The question states: Use as few if statements as possible to determine the largest and smallest of four numbers entered by the user. Four if statements are sufficient. -- Since this question was asked before loops, arrays and functions were covered in the book, I am assuming that these should not be used.

Also, I know there was a similar question to this one, however none meet the requirements of what I am trying to achieve.

  1. Using only 4 if statements
  2. No for-loops.

The first thing that came to my mind was using the logical or operator however as shown below, eight if statements were used. Also this method is very long and not efficient:

    int a, b, c, d;

printf("Enter 4 intgeres to find largest and smallest: ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);

if (a > b && a > c && a > d)
    printf("Largest: %d\n", a);
if (b > a && b > c && b > d)
    printf("Largest: %d\n", b);
if (c > a && c > b && c > d)
    printf("Largest: %d\n", c);
if (d > a && d > a && d > c)
    printf("Largest: %d\n", d);

if (a < b && a < c && a < d)
    printf("Smallest: %d\n", a);
if (b < a && b < c && b < d)
    printf("Smallest: %d\n", b);
if (c < a && c < b && c < d)
    printf("Smallest: %d\n", c);
if (d < a && d < a && d < c)
    printf("Smallest: %d\n", d);

return 0;

Next, I proceeded to the following code which would be a better solution:

    int a, b, c, d;

printf("Enter 4 intgeres to find largest and smallest: ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);

int max = a, min = a;

if (b > max) 
    max = b;
else if (b < min) 
    min = b;
if (c > max) 
    max = c;
else if (c < min) 
    min = c;
if (d > max) 
    max = d;
else if (d < min) 
    min = d;

printf("max: %d min : %d\n", max, min);

return 0;

However, still not meeting the requirement of using 4 if statements. I was wondering if I could shorten my code even further. Please excuse the basic nature of this question. Any suggestions would be appreciated.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
  • By the way, one can do that with zero `if`s, and even without `? :`, using only `&&` and `||`. – HolyBlackCat Feb 11 '17 at 11:23
  • Yes, I am aware of using conditional expressions would solve this with `zero` if s. However the requirement states that I use `if` statements to achieve the result. (4 would be sufficient) –  Feb 11 '17 at 11:25
  • Only `if`, so no else or else if? – Stefan Feb 11 '17 at 11:26
  • While I don't know if it helps (I haven't really given it much through) but if `a > b && b > c` then it follows that `a > c`. – Some programmer dude Feb 11 '17 at 11:26
  • @Stefan, `else if` can be used however, correct me if I am mistaken, an `else if` is also considered to be an if statement. Thus, in my last solution I am using 6 if statements. –  Feb 11 '17 at 11:28
  • @Someprogrammerdude, yes that would be the case in your example. However, I am using 4 integers, thus, the fourth integer `d` should also be utilised. This would still require me to use more than 4 `if` statements from what I have tried so far. –  Feb 11 '17 at 11:31

6 Answers6

6

We can use divide n conquer approach to solve this problem.

Imagine our input = [a, b, c, d]

We want to find answer from [a,b] and [c,d]

Then merge the final solution to find the answer.

if(a > b) swap(&a,&b); // solve [a,b]
if(c > d) swap(&c,&d); // solve [c,d]
if(a > c) swap(&a,&c); // find minimum from [a,b] and [c,d]
if(d > b) swap(&b,&d); // find maximum from [a,b] and [c,d]

// a will store the minimum value.
// b will store the maximum value.

Bonus (How to Swap Number in C Language)

void swap(int *a,int *b) {
    int c = *a;
    *a = *b;
    *b = c;
}
algojava
  • 743
  • 4
  • 9
  • `swap` exists in C++, but not in C, and cannot be implemented in C in a way that allows you to call it the way you do. But if this is meant to be pseudo-code, it's fine, in that case it would just help to point out that you realise that bits are missing. –  Feb 11 '17 at 12:25
  • yes, I know. I assume he can write swap(a,b) function easily. I will edit my original solution. – algojava Feb 11 '17 at 12:27
  • @algojava: The `swap(a, b)` is doable by C11 generic macros (though I agree it's not as elegant `std::swap` from C++). For instance, you could define `#define swap(a, b) _Generic((a), int: swapi)(&a, &b)`, where `swapi` is essentially the same as your `swap`. See https://godbolt.org/g/SFMdps. – Grzegorz Szpetkowski Feb 11 '17 at 13:05
4

Following should work.

It computes max1 = max(a, b) and max2 = max(c, d), as well as min1 = min(a, b) and min2 = min(c, d), using the first 2 ifs.

Then the maximum is equal to max(max(a, b), max(c, d)) = max(max1, max2). (The 3rd if.)

And the minimum is equal to min(min(a, b), min(c, d)) = min(min1, min2). (The 4th if.)

int a, b, c, d;

// ...

int min, max, max1, max2, min1, min2;

if (a > b) // 1
{
    max1 = a;
    min1 = b;
}
else
{
    max1 = b;
    min1 = a;
}

if (c > d) // 2
{
    max2 = c;
    min2 = d;
}
else
{
    max2 = d;
    min2 = c;
}

if (max1 > max2) // 3
    max = max1;
else
    max = max2;

if (min1 < min2) // 4
    min = min1;
else
    min = min2;

Bonus

Zero ifs.

int a, b, c, d;

// ...

int min = a, max = a;
b < min && (min = b);
c < min && (min = c);
d < min && (min = d);
b > max && (max = b);
c > max && (max = c);
d > max && (max = d);
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • 2
    This exercise is setting the reader up for divide and conquer sorting techniques like quicksort. The "zero ifs" is cheating, `cond && expression` is an `if`. The problem would probably be better expressed as "using only 4 comparisons". – Schwern Feb 11 '17 at 11:58
  • Is this solution considered to be more efficient than the second one i proposed since it has less if statements? –  Feb 11 '17 at 12:01
  • 1
    @Rizzo: Yes, HolyBlackCat's first example is more efficient that your proposed ones. Local temporary variables are "cheap"; the compiler can often optimize them away (i.e., only keep them in registers). The [Divide and conquer algorithm](https://en.wikipedia.org/wiki/Divide_and_conquer_algorithm) wikipedia page may shed light on the idea of splitting the problem like this. Splitting the problem up, and drawing [decision trees](https://en.wikipedia.org/wiki/Decision_trees), is a very useful design technique you could consider learning, for solving problems in general. – Nominal Animal Feb 11 '17 at 13:11
1
#include <stdio.h>

int main ()
{
    int num1, num2, num3, num4;
  
     printf("enter the numbers: ");
     scanf("%d %d %d %d", &num1, &num2, &num3, &num4);

     int large1 = num1, low1 = num2, low = num3, large = num4;
     if (num1 <= num2) {
         large1 = num2;
         low1 = num1;
     }
     if (num3 >= num4) {
         large = num3;
         low = num4;
     }
     if (large < large) {
         large = large1;
     }
     if (low > low1) {
         low = low1;
     }
     printf("%d\n", large);
     printf("%d\n", low);
     return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
0
#include <stdio.h>

int max_of_four(int a,int b, int c, int d)
{
    int max=0;
    max = (a > b ? (a > c ? (a > d ?   a :  d) :  (c > d ? c : d) ) : (b > c ? (b > d ? b : d>c? d : c ) : c>d? c : d)) ;

   return max;
}

int main() {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    int ans = max_of_four(a, b, c, d);
    printf("%d", ans);

    return 0;
}
  • 1
    Use of the ternary operator seems clearly off topic. Furthermore you only compute the max, not the min. – chqrlie Apr 06 '22 at 20:22
0

Here is an alternative solution with a single if statement:

#include <stdio.h>

int main() {
    int a, b, c, d;
  
    printf("enter the numbers: ");
    if (scanf("%d%d%d%d", &a, &b, &c, &d) == 4) {
        int lo1 = a * (a <= b) + (a > b) * b;
        int hi1 = a * (a >= b) + (a < b) * b;
        int lo2 = c * (c <= d) + (c > d) * d;
        int hi2 = c * (c >= d) + (c < d) * d;
        int lo = lo1 * (lo1 <= lo2) + (lo1 > lo2) * lo2;
        int hi = hi1 * (hi1 >= hi2) + (hi1 < hi2) * hi2;
        printf("%d %d\n", hi, lo);
        return 0;
    } else {
        return 1;
    }
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
-1

its a very creative question. I have solved your problem using only two if statements.

int a = 22, b = 25, c = 100, d = 4;
        int max = 0, min = 0;
        if ((a > b ? (a > c ? (a > d ? max = a : max = d) : max = c) : (b > c ? (b > d ? max = b : max = d) : max = c)) == 1)
        {
              //Control never goes inside this loop
        }
        else if ((a < b ? (a < c ? (a < d ? min= a : min= d) : min= c) : (b < c ? (b < d ? min = b : min = d) : min = c)) == 1)
        {
             //Control never goes inside this loop
        }
        printf("Maximum Value is:%d and Minimum Value is: %d", max, min);//at this statement max and min will have appropriate values
Raj Kumar Mishra
  • 516
  • 4
  • 16
  • `?:` is syntactic sugar for `if`/`else`. – rubenvb Feb 11 '17 at 12:53
  • 1
    It may be the same but they come under different classification in C ."?:" is a conditional operator and "if else" is a statement. And it was told not to use if statements more than 4 times. It didn.t mention that we cant use condtional operators. You better check your facts before rating negative to anyone. – Raj Kumar Mishra Feb 11 '17 at 13:02