Skip to content
Sign upLog in
← Back to Community

[Resolved] Logic optimization; how to remove/combine redundant logic/branching?

Profile icon
xxpertHacker

I had forked the popular "fake" 3D box on /share right now:
https://repl.it/talk/share/3d-but-its-actually-fake/80420.

Cleaned up the code a bit, and took a look at the branching logic.

I realized that some of the if statements were impossible in certain conditions.

There were 4 if statements.

The simplified version of a core part of the code was this:

if (x || a) { foo(); } if (x || b) { bar(); } if (y || a) { baz(); } if (y || b) { qux(); }

Normally, I am great at removing double checks, and merging stuff into one branch, but the best that I could get was this:

if (x) { foo(); bar(); } else { if (a) { foo(); } if (b) { bar(); } } if (y) { baz(); qux(); } else { if (a) { baz(); } if (b) { qux(); } }

Now, that's better, but a and b are checked seperately.

After analyzing the code, and running it, I realized the following: x and y may never both be true. (x && y == always false), both may be false (x || y != always true)

The same applies to the relation between a and b.
(I didn't observe the relation between x and a/b or y and a/b)

So, I realized that:

if (a); if (b);

Should've been:

if (a); else if (b);

So, I'm thinking that I could've tried moving the y checks into an else branch after x, like so:

if (x) { foo(); bar(); } else { if (a) { foo(); } else if (b) { bar(); } if (a) { baz(); } else if (b) { qux(); } }

But that logic is totally wrong.

I also tried to deal with the fact that a and b are duplicated, but they execute different code, so I can't wrap my head around how to handle this.

Voters
Profile icon
xxpertHacker
Comments
hotnewtop
Profile icon
fuzzyastrocat

You've pretty much minimized it. The problem is that a and b need to execute different things based on the values of x and y, so you can't merge their code without just "inverting" the whole thing (making a and b the outer checks and x and y the inner ones).

if (x) { foo(); bar(); } else { if (a) { foo(); } else if (b) { bar(); } else if (y) { baz(); qux(); } else { if (a) { baz(); } else if (b) { qux(); } }
Profile icon
xxpertHacker

@fuzzyastrocat
I was actually thinking of inverting it like that, but it would be massive:

if (x) { foo(); bar(); } else { if (a) { foo(); } else if (b) { bar(); } else { nop; } } if (y) { baz(); qux(); } else { if (a) { baz(); } else if (b) { qux(); } else { nop; } }

->

if (a) { if (x) { foo(); bar(); } else { foo(); } if (y) { baz(); qux(); } else { baz(); } } else if(b) { if (x) { foo(); bar(); } else { bar(); } if (y) { baz(); qux(); } else { qux(); } }

But, at that point, I'm like, "wait, now x and y are being checked in both branches"

And we end up with an infinitely recursing logic and I go back and forth between which should be outer vs inner.

In order to go further, I think I need the relation between
x <-> a,
x <-> b,
y <-> a,
y <-> b

Right now I only know
x <-> y,
a <-> b

Profile icon
realTronsi

@fuzzyastrocat
^ except

if(x){ foo() bar() } else if(y){ baz() qux() } else if(a) { foo() baz() } else { bar() qux() }

this is just the most intuitive answer, no need for nested if else

Profile icon
realTronsi

@xxpertHacker
lol whats up with those nested loops, just use 4 if else, it's more intuitive and way simpler

Profile icon
fuzzyastrocat

@realTronsi
This doesn't do what
@xxpertHacker
's nested system does. (In
@xxpertHacker
's system, the part about a or b changes depending on whether x or y is not true. In your version, it doesn't.)

Profile icon
realTronsi

@fuzzyastrocat

if (x || a) { foo(); } if (x || b) { bar(); } if (y || a) { baz(); } if (y || b) { qux(); }

I thought he was just minifying that ^ but alrigt.

@xxpertHacker
not sure what you're concerned about, you really can't make it more logically optimized

Profile icon
fuzzyastrocat

@realTronsi
Suppose x is true, y is false, a is true and b is false. Then the original calls foo, bar, baz. Yours would only call foo, bar.

Profile icon
xxpertHacker

@realTronsi
But there's the duplicate x || and y || code, so I know that it could be optimized further.

Then again, I literally wrote this:

centerX.value = (canvas_width.value = canvas.width = innerWidth) >> 1;

So yeah, I'm probably going too far.

Profile icon
xxpertHacker

@fuzzyastrocat

Suppose x is true, y is false, a is true and b is false. Then the original calls foo, bar, baz. Yours would only call foo, bar.

No no, not at all.
The only 6 possible call combination are:

  • foo

  • bar

  • foo and bar

  • baz

  • qux

  • baz and qux

Profile icon
fuzzyastrocat

@xxpertHacker
My scheme of xs and ys being true/false is ok by your rules. And let's just trace the original example:

x || a = true || true = true, so we have foo
x || b = true || false = true, so we have bar
y || a = false || true = true, so we have baz
y || b = false || false = false, so no more

Where is the flaw in my reasoning?

Profile icon
xxpertHacker

@fuzzyastrocat
I'm looking at this, and I think that my logic is off now.

Ahh, I see it, I really do need the relation between x <-> a/b as I had said earlier.

Just checked, they may mix and match.

In the post I said:

But [my] logic is totally wrong.

Yeah, I'm thinking like that again.

What you showed explains why I can't say

if (x); else if (y); else;

And why I've been so thrown off by this.

Ugh, I think I'm just tired.

Profile icon
realTronsi

@xxpertHacker

if(x){ foo() bar() if(y){ if(a){ baz() } if(b){ qux() } } } else if(y) { baz() qux() if(a){ foo() } if(b){ bar() } }

what about that?

Profile icon
fuzzyastrocat

@realTronsi
x and y could both be false, but that automatically runs y if x is false.

Profile icon
realTronsi

@fuzzyastrocat
sorry just put else if(y) lmao I just wrote that on a whiz

Profile icon
xxpertHacker

@realTronsi
Nope, didn't work.

Profile icon
realTronsi

@xxpertHacker
oh really? where's my logic error then

Profile icon
xxpertHacker

@realTronsi
I don't even know, lmao.

Profile icon
xxpertHacker

@realTronsi

not sure what you're concerned about, you really can't make it more logically optimized

@fuzzyastrocat

You've pretty much minimized it. The problem is that a and b need to execute different things based on the values of x and y, so you can't merge their code without just "inverting" the whole thing (making a and b the outer checks and x and y the inner ones).

I wish I could accept both of your answers; consider it solved.

Profile icon
realTronsi

@xxpertHacker
okay accept
@fuzzyastrocat
since I'm literally did nothing to help lol

Profile icon
xxpertHacker

@realTronsi
Na, y'all got your cycle for spending your time here.
I upvoted both.

Profile icon
fuzzyastrocat

@xxpertHacker
Suggestion: Put [resolved] in the title so no one comes by thinking it's unsolved.

Profile icon
xxpertHacker