Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MacToby

macrumors member
Original poster
May 13, 2020
66
19
Europe
So, I'm currently learning Swift (with no programming experience at all) with Swift Playgrounds.

I am currently on Learn To Code 2 at the level Round Up the Switches.
My solution for this level was:

Swift:
var numberOfGems = 0
var numberOfSwitches = 0

func checkTile() {
    if isOnGem {
        collectGem()
        numberOfGems += 1
    }
    if isOnClosedSwitch {
        toggleSwitch()
        numberOfSwitches += 1
    }
}

func checkWhereToGo() {
    if isBlocked {
        turnRight()
    }
}

while numberOfGems != numberOfSwitches && numberOfSwitches == 0 {
    moveForward()
    checkTile()
    checkWhereToGo()
}

However, I noticed that this solution doesn't work. Byte didn't even start to move.
I had to replace the And (&&) operator with the Or (||) operator in the while loop, but why do I have to do that?

Swift:
var numberOfGems = 0
var numberOfSwitches = 0

func checkTile() {
    if isOnGem {
        collectGem()
        numberOfGems += 1
    }
    if isOnClosedSwitch {
        toggleSwitch()
        numberOfSwitches += 1
    }
}

func checkWhereToGo() {
    if isBlocked {
        turnRight()
    }
}

while numberOfGems != numberOfSwitches || numberOfSwitches == 0 {
    moveForward()
    checkTile()
    checkWhereToGo()
}

I just wanted my while loop to be executed when both conditions are true. Both conditions were met, right?

Thank you very much in advance. :)
 

casperes1996

macrumors 604
Jan 26, 2014
7,599
5,771
Horsens, Denmark
Surely what you want is for your loop to execute when either condition is true, not when both are true.

Otherwise when a switch is interacted with, numberOfSwitches is no longer == 0. There could still be more gems, but the whole condition is now false because you get
true && false

Assuming I’ve understood the problem properly; I didn’t look up the Learn To Code task
 

casperes1996

macrumors 604
Jan 26, 2014
7,599
5,771
Horsens, Denmark
Also if numberOfGems = 0 in the beginning, and numberOfSwitches = 0 in the beginning the first condition will start false, so if you do && the loop will never have both conditions true at the beginning of execution and thus never run. That’s likely the issue you were facing actually and not what I was talking about above; I just checked the actual challenge.
 
  • Like
Reactions: MacToby

MacToby

macrumors member
Original poster
May 13, 2020
66
19
Europe
Another example, which I also don't understand, where the Or (||) operator is used instead of the And (&&) operator is again in Learn To Code 2 Level Three Gems, Four Switches.

My solution for the level was:

Swift:
var numberOfGems = 0
var numberOfSwitches = 0

func checkTile() {
    if isOnGem {
        if numberOfGems != 3 {
            collectGem()
            numberOfGems = numberOfGems + 1
        }
    }
    if isOnClosedSwitch {
        if numberOfSwitches != 4 {
            toggleSwitch()
            numberOfSwitches = numberOfSwitches + 1
        }
    }
}

func checkWhereToGo() {
    if isBlocked {
        if isBlockedRight {
            turnLeft()
        } else {
            turnRight()
        }
    }
}

while numberOfGems != 3 && numberOfSwitches != 4 {
    moveForward()
    checkTile()
    checkWhereToGo()
}

Right Solution:

Swift:
var numberOfGems = 0
var numberOfSwitches = 0

func checkTile() {
    if isOnGem {
        if numberOfGems != 3 {
            collectGem()
            numberOfGems = numberOfGems + 1
        }
    }
    if isOnClosedSwitch {
        if numberOfSwitches != 4 {
            toggleSwitch()
            numberOfSwitches = numberOfSwitches + 1
        }
    }
}

func checkWhereToGo() {
    if isBlocked {
        if isBlockedRight {
            turnLeft()
        } else {
            turnRight()
        }
    }
}

while numberOfGems != 3 || numberOfSwitches != 4 {
    moveForward()
    checkTile()
    checkWhereToGo()
}

However, I also had to replace the And (&&) operator with the Or (||) operator, but this time when I ran my code with the And (&&) operator instead of the Or (||) operator byte went off ... but the while loop stopped after the first condition (collect three gems) was met.

Actually the while loop should continue until the other condition (toggle four switches) is fulfilled, or not?
Again, both conditions were fulfilled, weren't they?

I just don't understand why I had to choose the Or (||) operator instead of the And (&&) operator to make it work.
Hopefully someone can explain it to me so that I understand it.

Thanks a lot again!
 

MacToby

macrumors member
Original poster
May 13, 2020
66
19
Europe
Also if numberOfGems = 0 in the beginning, and numberOfSwitches = 0 in the beginning the first condition will start false, so if you do && the loop will never have both conditions true at the beginning of execution and thus never run. That’s likely the issue you were facing actually and not what I was talking about above; I just checked the actual challenge.
But why does the while loop work with the Or (||) operator?

Edit:
Okay I think I understand you now! Thank you very much for the great explanation.
But could you please clarify my second problem I'm facing?
 
Last edited:

casperes1996

macrumors 604
Jan 26, 2014
7,599
5,771
Horsens, Denmark
But why does the while loop work with the Or (||) operator?

Apologies if the following rehashes things you already know.

I will explain boolean operations in three phases.
1) I will explain it in a programmatic sense that pertains to your specific issue.
2) I will go over the machine level functioning of boolean operations
3) I will explain via Propositional Logic

I have some fear of confusing matters even further so I encourage you to only consider explanation 1 if that makes sense to you. If not, look at 2 if you are into electrical engineering and 3 if you're more mathematical :)

--------------

1)
Are you familiar with the break keyword? It stops a loop from inside the loop. So for example

Code:
let x = 0
while x==0 {
    print("Hello\n")
    break
}
will only print once even though x continues to be 0.

Thee reason I mention this is that I will show you a way of rewriting your two while loops that may make it a bit clearer what happens.

Code:
while true {
    if numberOfGems != numberOfSwitches{ 
        if numberOfSwitches == 0 {
            // Loop Body
       }
    }
 else { break }
}

Code:
while true {
    if numberOfGems != numberOfSwitches{ 
        // Loop body
    }
    else if numberOfSwitches == 0 {
        // Loop Body
    }
    else { break }
}

Can you tell which corresponds to && and which corresponds to ||?

The top one is && and the bottom one is ||

It may be more clear to see here that the first one falls into the break immediately while the second one executes the loop body on either condition being true.

-----------------
2)

Assume we have three registers in the CPU, for this example called A, B and C. This is an instruction set just for demonstration purposes and not directly relating to x86 or ARM.

A will contain the value true, which we will encode as
00000001

B will contain false, which we will encode:
00000000

C is empty, so all 0's just like false.

On Input
A || B -> C

We will take the signals of all bits in A and B and set all bits that are turned on in C, resulting in
C = 00000001
Because the value of the least significant bit was 1 in A
Think of it like a gate that takes power from both A and B and pushes that power to the same bit position in C.
If either A or B is turned on that bit position in C gets power. If both are turned on, C also gets power in that position. Only if neither is turned on does C not get power for that bit position.

On input A && B -> C
the gate between AB and C only activates a relevant bit position in C if it gets power from both A and B. You can consider it a threshold filter; That the power of just one bit position from one register is not enough to make power flow through the gate. Thus,

C = 00000000
Because there is no bit-position turned on in both A and B.

(Bonus chapter)
On input
A ⊻ B -> C (XOR)

The gate blocks power to C if both A and B send power for a bit, and lets power through if one and only one of the two registers sends power; In this case it is identical to OR.

---------------

3)

Let us consider your two condition:
A := (numberOfGems != numberOfSwitches)
B := (numberOfSwitches == 0)

Then the operation A && B
Results in the Propositional Logic Expression
A⋀B

And A || B
A⋁B.

It is a simple rephrasing but consider the case of &&. If B is false, regardless of the value of A
Given:
B = ⊥
Then:
(A⋀B) = ⊥
Would hold.

Similarly
Given:
A = ⊥
(A⋀B) = ⊥

However, for || the opposite relation holds.
Given: A = ⊤
Then:
(A⋁B) = ⊤

and

A = ⊤ => (A⋁B) = ⊤
(The above is just a shorter way of writing the implication)

-------------------

I will now look at your second question :)
 
  • Like
Reactions: Buggs and Rastafabi

casperes1996

macrumors 604
Jan 26, 2014
7,599
5,771
Horsens, Denmark
Edit:
Okay I think I understand you now! Thank you very much for the great explanation.
But could you please clarify my second problem I'm facing?

Upon reviewing your second question, my above writeup about the boolean operators may serve as sufficient explanation. If not do let me know and I'll try to clarify further.

I also usually offer people on here who are trying to learn programming some further mentorship. If you want you're welcome to contact me at any time, here or through other means (I can be reached on Discord and mail:
https://www.theparallelthread.com/about.html )

I'm happy to help, read any code you write, help you when you don't know where next to go to learn, and generally give feedback as time permits.

-Casper S.
 
  • Like
Reactions: Buggs and MacToby
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.