I wanted to make one of my code more concise
Baking in a number of side effects into a single expression of nested non-parenthesized ternary operators (making use of implicit conversion to bool) does, if anything, make your code more complex, more bug-prone and may hide the fact that the original code should actually have been broken up and re-factored into something simpler.
Why not favour clarity over over-complex brevity? E.g. starting with the straight-forward approach:
while(m <= r) {
if (nums[m] != 0) {
if (nums[m] == 1) {
++m;
}
else {
swap(nums[m], nums[r--]);
}
}
else {
swap(nums[m++], nums[l++]);
}
}
which can be re-factored into:
while(m <= r) {
if (nums[m] != 0) {
if (nums[m] == 1) {
++m;
}
else {
swap(nums[m], nums[r]);
--r;
}
}
else {
swap(nums[m], nums[l]);
++m;
++l;
}
}
which can be re-factored into:
while(m <= r) {
const std::size_t swap_from_idx = m;
std::size_t swap_with_idx = m; // default: no swapping.
if (nums[m] == 1) {
++m;
continue;
}
else if (nums[m] == 0) {
swap_with_idx = l;
++l;
}
else {
swap_with_idx = r;
--r;
++m;
}
swap(nums[swap_from_idx], nums[swap_with_idx]);
}
or e.g.:
while(m <= r) {
// No swapping.
if (nums[m] == 1) {
++m;
}
// Swapping.
else {
const std::size_t swap_from_idx = m;
std::size_t swap_with_idx = l;
if (nums[m] == 0) {
++l;
}
else {
swap_with_idx = r;
--r;
++m;
}
swap(nums[swap_from_idx], nums[swap_with_idx]);
}
}
At this point you may ask yourself is the original loop design is overly complex, and/or if you should break out part of the loop body into a separate utility function.
If your if
/else if
/else
logic is reaching a too high cyclomatic complexity, the answer is seldom to try to hide it by means of a highly complex tenary operator expression, but rather by re-factoring and, if applicable, breaking out some parts in separate functions.