Tyler
Tyler

Reputation: 11

QBasic/QB64: How to clean up an IF THEN IF "ladder"?

Not sure if I'm using the right terms here, but for whatever reason, QBasic doesn't understand something along the lines of "x = y = z". It's limited to two.

To fix that, I did this:

IF sum(1) = sum(2) THEN
    IF sum(2) = sum(3) THEN
        IF sum(3) = sum2(1) THEN
            IF sum2(1) = sum2(2) THEN
                IF sum2(2) = sum2(3) THEN
                    IF sum2(3) = sum3 THEN
                        IF sum3 = sum4 THEN
                            PRINT "This is a Lo Shu Square, with all sums equaling"; sum(1)
                        ELSE
                            PRINT "This is not a Lo Shu Square."
                        END IF
                    END IF
                END IF
            END IF
        END IF
    END IF
END IF
END

Definitely works, but something tells me there's a simpler way to have it check if all of the sums equal the same. Any suggestions?

Upvotes: 1

Views: 364

Answers (6)

eoredson
eoredson

Reputation: 1165

Another way to check an array in a loop in a function:

DIM sums(8) AS DOUBLE
sums(1) = sum(1)
sums(2) = sum(2)
sums(3) = sum(3)
sums(4) = sum2(1)
sums(5) = sum2(2)
sums(6) = sum2(3)
sums(7) = sum3
sums(8) = sum4
IF isLoShuSquare(sums()) = 0 THEN
    PRINT "This is not a Lo Shu square."
ELSE
    PRINT "This is a Lo Shu square, with all sums equaling"; sum(1)
END IF
END
FUNCTION isLoShuSquare (sums() AS DOUBLE)
isLoShuSquare = -1
FOR i = 1 TO UBOUND(sums) - 1
    IF sums(i) <> sums(i + 1) THEN
        isLoShuSquare = 0
        EXIT FUNCTION
    END IF
NEXT
END FUNCTION

Upvotes: 0

Joe
Joe

Reputation: 1340

Consolidate the logic into a function:

FUNCTION isLoShuSquare (sums() AS DOUBLE)

    isLoShuSquare = 1

    DIM i AS INTEGER
    FOR i = 0 TO UBOUND(sums) - 1
        IF sums(i) <> sums(i + 1) THEN
            isLoShuSquare = 0
            EXIT FOR
        END IF
    NEXT i

END FUNCTION

Then load the array and pass it to the function:

DIM sums(7) AS DOUBLE
DIM i AS INTEGER
i = 0
sums(i) = sum(1): i = i + 1
sums(i) = sum(2): i = i + 1
sums(i) = sum(3): i = i + 1
sums(i) = sum2(1): i = i + 1
sums(i) = sum2(2): i = i + 1
sums(i) = sum2(3): i = i + 1
sums(i) = sum3: i = i + 1
sums(i) = sum4

PRINT isLoShuSquare(sums())

Upvotes: 1

user9617746
user9617746

Reputation:

A simpler way to check a loop:

testvals(1) = sum(1)
testvals(2) = sum(2)
testvals(3) = sum(3)
testvals(4) = sum2(1)
testvals(5) = sum2(2)
testvals(6) = sum2(3)
testvals(7) = sum3
testvals(8) = sum4
FOR i = 1 TO 7
    IF testvals(i) <> testvals(i + 1) THEN
        PRINT "This is not a Lo Shu square."
        END
    END IF
NEXT
PRINT "This is a Lo Shu square, with all sums equaling"; sum(1)

Upvotes: 1

eoredson
eoredson

Reputation: 1165

A simpler way to check arrays:

testvals(1) = sum(1)
testvals(2) = sum(2)
testvals(3) = sum(3)
testvals(4) = sum2(1)
testvals(5) = sum2(2)
testvals(6) = sum2(3)
testvals(7) = sum3
testvals(8) = sum4
FOR i = 1 TO 7
    IF testvals(i) <> testvals(i + 1) THEN
        f = -1
        EXIT FOR
    END IF
NEXT
IF f THEN
    PRINT "This is not a Lo Shu square."
ELSE
    PRINT "This is a Lo Shu square, with all sums equaling"; sum(1)
END IF

Upvotes: 1

user539810
user539810

Reputation:

You could also code the logic into a loop:

DIM testvals(8)
testvals(0) = sum(1)
testvals(1) = sum(2)
testvals(2) = sum(3)
testvals(3) = sum2(1)
testvals(4) = sum2(2)
testvals(5) = sum2(3)
testvals(6) = sum3
testvals(7) = sum4
DO 
    FOR i = 1+LBOUND(testvals) TO UBOUND(testvals)
        IF testvals(i-1) <> testvals(i) THEN
            PRINT "This is not a Lo Shu square."
            EXIT DO
        END IF
    NEXT
    PRINT "This is a Lo Shu square, with all sums equaling"; sum(1)
LOOP WHILE 1 = 0

This has a couple of benefits:

  1. It's easier to spot a typo if you change the code.
  2. You can always add and remove test values in similar cases. In this case, there's no need to do such a thing, but in some other cases, it may be beneficial to simply type testvals(8) = value and change the 8 to a 9 in the DIM line.
  3. It short-circuits the comparison, meaning if the first condition is false, it stops checking and says it's not a Lo Shu Square, similar to a tower of IF-THEN-ELSE statements (where every ELSE is PRINT "This is not a Lo Shu square.") QB64's AND operator evaluates both operands, even if the first operand is 0 or another "false" value. This can be much faster, though you likely won't notice a difference in this case.

On the other hand, it does have some drawbacks:

  1. It's an unusual pattern in QB64 to not use AND in a case like this. In fact, this is one very good reason why AND exists.
  2. You can just as easily remove test values that are combined using AND with no need to renumber the items in the testvals array or change its dimensions.
  3. Even if you have many test values, it's often better to write a small program that generates the IF a AND b AND c AND ... THEN ... END IF block yourself (or something similar to your IF-THEN tower to retain short-circuit behavior) and paste the output into your program's code where it's needed.

Upvotes: 1

eoredson
eoredson

Reputation: 1165

It would work if all comparisons where put on one line separated by AND like this:

REM code to shrink IFTHEN ladder:
IF sum(1) = sum(2) AND sum(2) = sum(3) AND sum(3) = sum2(1) AND sum2(1) = sum2(2) AND sum2(2) = sum2(3) AND sum2(3) = sum3 AND sum3 = sum4 THEN
    PRINT "This is a Lo Shu Square, with all sums equaling"; sum(1)
ELSE
    PRINT "This is not a Lo Shu Square."
END IF
END

Upvotes: 3

Related Questions