FCC Bonfire Series 105: Check for Palindromes

Today, I bring you a new contender: Check for Palindromes. We must write a function that takes a string, be it a single word or full sentence, and should return true if said string is a palindrome, or false if it isn’t. But what, exactly, is a palindrome?

The definition given by Free Code Camp is spot on: “A palindrome is a word or sentence that’s spelled the same way both forward and backward, ignoring punctuation, case, and spacing.”. This means that ‘abba’ and ‘racecar’ are palindromes. It also means that “A man, a plan, a canal: Panama” is also a palindrome, even if not as obvious. Punctuation, capitalization and spacing pose a problem for our function; we human know when a space character should be ignored, we also know that A and a are the same character and that “racecar” and “race car” are pretty much the same thing. The computer, on the other hand, as smart as we think it is, is actually pretty stupid, and we must write the tasks he has to follow very concisely.

Let’s find us a few palindromes, a first approach to our problem may look like so:

1. Remove all capitalization.

This is pretty easy to fix. JavaScript, conveniently provides a String method that does exactly what we need (String.tolowerCase()).

2. Remove spaces and punctuation.

This time, we’ll need to use another method, String.replace(). This method takes two arguments, what to replace, and what to replace it with. We may use regular expressions for the first argument, and that’s exactly what we are going to do. If you do not know about regular expressions, RegExOne provides an excellent tutorial to get you going. To replace every punctuation, space or special character (and since every character is now in lower case), we’ll use /[^a-z]/g [^a-z0-9]/g to match every character that is not a lower case letter or number (Thanks to avid reader Piyari for pointing it out!). Since we want to get rid of them, we’ll pass an empty string (”) as the second argument (similar to what we did for split and join in the previous exercise).

3. Check letter by letter and compare it to it’s “mirror”, unless the number of total characters is odd. Ex.: In “abba”, compare the first and last letters, then the second, and second to last letters, but, “alula” has the “u” character, which doesn’t need to be compared to anything.

This is is a bit trickier, a simple for loop will not work exactly as we want it. There is a couple of ways to approach this task, but I’ll go ahead and explain the most straightforward way of doing it. We are going to procedurally compare each character to it’s mirrored character.

The first character in our string is: str[0] , and the last is str[str.length – 1] , the second character is str[1] , and the second to last is str[str.length – 2] , how can we automate this process for a string of any length? Let’s give it some though.

Lets start with a simple for loop:

for (var i = 0; i < str.length; i++) {
  // Do something with str[i] to it's mirror.
}

 

This will loop through every character in the string, but we only need it to check the first half of them, and ignore the center character when the string length is odd. I’ll get an example going so we can understand this, we’ll use the string ‘Bird Rib’, which should convert to ‘birdrib’ thanks to steps 1 and 2.

str = ‘birdrib’
We must compare the following:

str[0] to str[6] -> b == b OK
str[1] to srt[5] -> i == i OK
str[2] to str[4] -> r == r OK
Do not compare str[3].

The loop goes from 0 to 3 easily, but at the same time, we must from 6 to 4. First of all, let’s modify our loop, so it only loops through half of the array, but ignores the middle position (if there’s is one) by using Math.floor(). Math.floor() will round down a number to an integer (4.26 to 4, 9.88 to 9, etc.). If the string length is 7, Math.floor(7 / 2) will evaluate to 3.
To compare every number to it’s mirror, we’ll compare str[i]  to str[str.length – i – 1] . Since the indexing in JavaScript start at 0, we must substract 1 from the length. Out loop will end up looking like this:

for (var i = 0; i < Math.floor(str.length / 2); i++) {
  if (str[i] != str[str.length - i - 1]) {
    // Not a palindrome!
  }
}

 

4. If any check fails, return false. Else, return true.

To return true or false when the check has completed, we’ll start by assuming that the word is indeed a palindrome, and return false immediately after a check fails.

function palindrome(str) {
  str = str.toLowerCase();
  str = str.replace(/[^a-z]/g, '');
  for (var i = 0; i < Math.floor(str.length / 2); i++) {
    if (str[i] != str[str.length - i - 1]) {
      return false;
    }
  }
  return true;
}

 

And that’s it, we have a function that will detect those dodgy palindromes for us! We may give it some more depth, check if the provided string is indeed a string, check if the length is greater than 1 etc.!

Have fun with your newly acquainted palindromes, they are great life companions.