1

I have this following logic which needs simplifing to look clearer and consise:

 if (x1 < y1)
    return 1;
 else if (x1 == y1)) {
     if (x2 < y2)
         return 1;
     else if (x2 == y2) {
         if (x3 < y3)
             return 1;
     } else 
         return 0;
     }
 } else
    return 0;

In order to solve this above problem, I have applied logical expressions to further simplify these few lines of conditions:

if (x1 < y1 || (x1 == y1 && x2 < y2) || (x1 == y1 && x2 == y2 && x3 < y3))
    return 1;
else
    return 0;

I am not sure how to simplify further from here. Can anyone help me?

Update: For further simplifying, I tried applying boolean algebra to this expression, but no luck! I have come up with this:

A + (A1 * B) + (A1 * B1 * C)

Where A denotes to x1 < y1 and A1 denotes to x1 == y2

Nipun Tharuksha
  • 2,496
  • 4
  • 17
  • 40
Sedmaister
  • 475
  • 1
  • 4
  • 11
  • Are you trying to simplify this to make it clearer and more concise or is it in a tight loop that needs to be heavily optimized? If it is the second and your values have limited range you can do it with some shifts and a single comparison. But there would have to be pretty specific reasons to make that the right way to do it. – John Meacham Aug 20 '19 at 00:08
  • I believe that the question belongs here: https://codereview.stackexchange.com/ –  Aug 20 '19 at 00:12
  • `x1 < y1 || (x1 == y1 && (x2 < y2 || (x2 == y2 && x3 < y3)))` – Scott Hunter Aug 20 '19 at 00:12
  • 1
    I am trying to simplify this to make it clearer and more concise. Performance is not important in this case, readability is. If bit shifting makes it look readable - so be it. – Sedmaister Aug 20 '19 at 00:13

1 Answers1

0

IMO the cleanest way to do this sort of chained relation in C is with ?::

return x1 == y1 ? x2 == y2 ? x3 < y3 : x2 < y2 : x1 < y1;

As noted in the question comments, if you really care about performance, and the values have limited range, you can use bit twiddling to combine them into a single value for comparison. If the fields are all uint16_t (unsigned 16-bit values), for example, you can do:

uint64_t x = ((uint64_t)x1 << 32) + ((uint64_t)x2 << 16) + x3;
uint64_t y = ((uint64_t)y1 << 32) + ((uint64_t)y2 << 16) + y3;
return x < y;

but this is probably less clear and probably a premature optimization.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • I believe this is more readable: `return x1 != y1 ? x1 < y1 : (x2 != y2 ? x2 < y2 : x3 < y3);` Because `x1 != y1` and `x1 < y1` are close, the same for x2, y2. It also handles the short branch immediately. –  Aug 20 '19 at 13:22
  • @dyukha: reasonable, though you should probably delete the redundant parentheses that make it less clear. – Chris Dodd Aug 20 '19 at 19:44