Arrays and Sets - Palindrome.swift Project (Swift)

Hey all, another question. I was able to easily enough to follow the directions in this project and make the project work. However, I am confused as to WHY it is working. Here is the code below:

var text = [“h”, “e”, “l”, “l”, “o”]
var reversed = [ String ] ( )
var counter = text.count - 1
while counter >= 0 {
reversed.append(text[counter])
counter -= 1
}
if text == reversed {
print(" \ (text) is a palindrome!")
}
else {
print(" \ (text) is not a palindrome.")
}

I am getting hung up on the “while” loop, what is going on here? How does this this sequence of code reverse the var text? Furthermore how does this code know through counters that a word is a Palindrome? I usually “read” through the code line by line to see wha it is “saying” but I am at a lose here. Could some one kindly explain how this code works?

Thanks!

Hi!

For algorithms, as they become more complicated, reading straight will only show a partial idea of the big picture. The bigger prize is in conceptualizing the problem abstractly and understanding what it needs.

You may know this already, but a palindrome is a word that is symmetrical in its construction of letters. Some palindromic strings: aba, cddc, oopoo. You might want to think about whether some edge cases are considered palindromes, such as the empty string "" and a length-1 string "x", are these palindromes?

Then the question becomes, how would one check if the string has this symmetry?
There’s more than one way to do it, but the code you provide works as well (just think, how would the code manipulate the following strings and make it work?).

Also, n.b. for future: [How to] Format code in posts :slight_smile:

Hey toastedpitabread,

Thanks again for following up with my question. And thank you for letting me know how to format code lines in the forums. :slight_smile:

To answer your question as to how I would conceptually approach answering this problem, I would make a program that would take an Array, reverses that Array, and then checks if the two Arrays are equal. Now coding that is a whole different story as I am learning how to code those conceptualizations. I do understand that the original code I provided does not account for Arrays of 0-1 characters, as the code stands, the output print will state that those Arrays are palindromic, which of course those type of Arrays are not. But, for the purpose of this exercise I will make a comment that this problem works for Arrays for 2 or more characters. :slight_smile: Here is how I would make this program based on my conceptualized answer:

//Works for Arrays for 2 or more characters.

var text = ["o","t","t","o"]

//We have not learned how to .reverse() yet in Codecademy, but it would be simple 
//enough to look up as I understand how these functions can work though other
//lessons that used ".count". This function would work with Arrays or Strings,
//but I stayed with Arrays to keep this as close to the lesson topic.

var reversedText = Array(text.reversed())

if text == reversedText {
  print("\(text) is a Palindrome!")
 }
  else {
    print("\(text) is a Palindrome!")
}

Now back to my original question, I am confused as to how the code below (the one Codecademy is asking us to complete) is indeed “reversing” the original, or doing something of the sort:

var text = ["h", "e", "l", "l", "o"]
var reversed = [String]()
var counter = text.count - 1
while counter >= 0 {
reversed.append(text[counter])
counter -= 1
}
if text == reversed {
print("\(text) is a palindrome!")
}
else {
print("\(text) is not a palindrome.")
}

As I look at this var:

var counter = text.count -1

Is this var saying that “counter= text counting backwards or -1, so, starting at the “o” in hello?” If so, how does that make sense? If I print(counter) after that var I get 4, which makes sense as text (5) - 1 = 4.

The while loop body also baffles me:

reversed.append(text[counter])
counter -= 1

To me this “reads”: add (hello[4]) to the var reversed. Codecademy just ends that section of the project step with, " Now we have reversed , the exact flip of text , we now want our program to check whether or not we have a palindrome." But HOW and WHY?

I’m so confused.

You’re very close! Try putting a print statement inside the loop. Put one of the reversed array and one for the counter.

The key thing to remember is that arrays are 0-indexed in most (but not all) programming languages. This means that word lengths always have to have a minus one when iterating through their arrays. (0 through length minus one).

Hmm, so I understand that Array’s in Swift are 0-indexed. (h=0, e=1, l=2, l=3, o=4)

So:

var counter = text.count -1
print(counter)

Is stating that if counter is printed right after there are now 4 Characters in the Array “hello”.

Then:

while counter >= 0 {
reversed.append(text[counter])
counter -= 1
print(counter)
print(reversed)
}

Continue the loop while the counter is more than or equal to zero, leaving us with the (4, 3, 2, 1, 0) Then add in the “reversed” String the Characters in “text” that correspond with their order going from highest to lowest. This would mean that the Array “text’” Characters that would be printed would be (o=4, l=3, l=2, e=1, h=0) But this is not the case when printed. The Array “text’” Characters’ Int(s) changed to (o=-3, l=2, l=1, e=0, h=-1).

3
["o"]
2
["o", "l"]
1
["o", "l", "l"]
0
["o", "l", "l", "e"]
-1
["o", "l", "l", "e", "h"]

How/why did that happen?

I see now how the Array “text” was able to be reversed and appended into the var “reversed”. But why did the Int(s) change in “hello”.

text and reversed are two separate arrays. The integer indices don’t change as the original array is never modified.

What does change is the counter, with the line counter -= 1. This could be done in a reversed for-loop but this illustrates nicely how it would work explicitly. And sometimes it’s necessary to use counters as pseudo-pointers for different algorithms.

Oh wow, now I understand. Thank you for clarifying this for me!!!

Man, my mind didn’t think to solve the problem that way. It seems like such an arduous method, but mathematically it makes sense. If Swift didn’t have properties built into the language then one would have to do this all by “scratch” as in the Project example. And maybe even still, some algorithms may need to be “spelled” out like this because there isn’t a property like Array(text.reversed()) to “do the job.” I suppose older languages were like this where you had to explicitly write code in this manner because the language did not have certain built-in features?

Thank you again, this definitely stretched my mind as to how to solve problems differently.

No problem!

Without getting too complicated, a lot of algorithms are spelled out because fine-tuning them yields faster results, which, when scaled up, make a huge difference (think a program running billions of times becoming twice as fast).

Most languages will have optimized libraries for the most common methods, but the more specific/unique of a tool one tries to build, the more it pays off to know how to leverage the code to be its most efficient self.