Tag: javascript



Bonfire: Check for Palindromes Solution

We’re going to check for palindromes today for one of our Bonfire challenges. This is something I haven’t done yet. I have two solutions this time. The first relies on pre-existing methods. The second is a for loop.

Approaching the Problem

Let’s first take a look at what we’re given.

function palindrome(str) {
  // Good luck!
  return true;
}

palindrome("eye");

Simple and familiar set up by now. A basic function with a function call. I’m a particular fan of the somewhat cheeky, “Good luck!” in there. All right, first of all, a palindrome is a word or phrase that when reversed is the same as it was prior to reversal if you ignore spacing, capitalization and punctuation. For instance:

racecar = racecar
eye = eye
tacocat = tacocat

And my personal favorite because I am apparently still a thirteen year old:

abutttuba = abutttuba

On the flipside, the following words and phrases are not palindromes:

deerrun = nurreed
hockey = yekcoh

We already know that we have to evaluate whether a string is a palindrome or not, and the Bonfire gives us a clue right off the bat in the challenge description: ignoring spacing, capitalization and punctuation. Now we know that even though the function call only references the palindrome “eye”, the Bonfire is serious about us doing this right so we’re likely to be tested against palindromes with things like spaces, capitals and punctuation too. Something like this:

Degas, are we not drawn onward, no? In union, drawn onward to new eras aged?

This means we’re probably going to have to strip capitalization, punctuation and spacing from whatever the Bonfire throws at us.

Next thing we have to consider is that we need to be able to check the reversed string to its unreversed state. Believe it or not, we did something similar to this for the the Reverse a String Solution where we converted the string into an array, reversed the array, then turned it back into a string. We can do the same thing to help us check for palindromes in this scenario.

Finally, we need to return a true or false value depending on whether the string evaluates a palindrome or not. Let’s get started on the pre-existing methods solution:

Checking for Palindromes Using Existing Methods

The first thing I’m going to address is the stripping of punctuation, capitalization and spaces from the string. I’m going to do that using a couple of pre-existing methods. The first is toLowerCase() which removes capitalization by forcing all characters to be lowercase. The second is a replace() function that will remove spaces and punctuation.

toLowerCase() is pretty self explanatory, but I think I need to take a moment to comment on how we’re going to use replace(). Here’s what I’ve got at this stage:

function palindrome(str) {
  var stripStr = str.toLowerCase().replace(/\W|\s/g,'');
}

palindrome(“Degas, are we not drawn onward, no? In union, drawn onward to new eras aged?”);

With replace(), we’re going to come back to something you should have been introduced to shortly before the Bonfires; Regular Expressions. Before we get to that though, let me explain my approach. The first thing I did with this is create a local variable within the function that is meant to strip the string of capitals, spaces and punctuation to make finding the palindromes easier.

With toLowerCase() I’m achieving that by using a pre-existing method to force all capitals in whatever string I feed palindrome() to become lowercase. Then I use replace() coupled with regex to filter out spaces and special characters. Within Regex, //g is used to represent a global search. What I’m doing is executing a search for all non-word characters with \W, and searching for spaces with \s.

After that, the comma and ” is meant to replace whatever is found for special characters and spaces with–basically nothing. Not even a space. This effectively cleans up whatever string we’re going to feed palindrome() and I chose the particularly meaty one we met earlier because it has all the components the Bonfire is probably going to look for when it attempts to validate our solution. At this point in time, our string that was originally: Degas, are we not drawn onward, no? In union, drawn onward to new eras aged?

Now probably looks more like: degasarewenotdrawnonwardnoinuniondrawnonwardtonewerasaged

Next step is to actually check for the palindrome itself. There’s actually two approaches to this, the first is a fully automated one using all pre-existing methods (particularly our friends, split(), reverse() and join()), which I was going to cover, but Wulkan from wulkan.me has already done a pretty good job of that. Mine only differs slightly, but here it is:

function palindrome(str) {
  
  var stripStr = str.toLowerCase().replace(/\W|\s/g,'');
  var checkStr = stripStr.split('').reverse().join('');
  
  if (stripStr === checkStr) {
    console.log("the string is a palindrome.");
    return true;
  } else {
    console.log("the string is not a palindrome.");
    return false;
  }
}
  
palindrome("Degas, are we not drawn onward, no? In union, drawn onward to new eras aged?");

What we’re doing is first stripping the string of capitals, spaces and punctuation. Then since we now have:

degasarewenotdrawnonwardnoinuniondrawnonwardtonewerasaged

Which is still a string–and therefore, immutable, we need to reverse it to check for palindromes. Otherwise, you’re just checking the existing string against itself. So we use our good friends, split(), reverse() and join() to flip the string around. Finally, we use a simple if statement to check if stripStr and checkStr are deeply equivalent to each other. If they are, we return true. If they aren’t, we return false. You can replace the palindrome() parameter above with eye prior to validating if you wish, but the Bonfire should check the solution and issue you a pass whether you check for eye or check the above palindrome.

Checking for Palindromes With a For Loop

Let’s say you’re not really sure what those existing methods are doing and would rather step through this in a more “show your work” type of way. I’ve done a for loop solution for this, again, not sure if it’s really great, but it validated and seems to handle the Bonfire requests pretty well.

Here’s the problem I faced as I was thinking through this one myself. Despite my lofty goal of using no build-in methods, I still have no clue as to how to strip capitals, spaces and punctuation from a string without using the existing toLowerCase() and replace() methods. There are also a lot of solutions to the popular “check for palindromes” interview question online without relying on built-in methods. However, many of the solutions offered only check whole words for palindromes, not necessarily phrases. So in terms of prepping the string for a palindrome check, I started out the same:

function palindrome(str) {
var stripStr = str.toLowerCase().replace(/\W|\s/g,'');
}
palindrome("Degas, are we not drawn onward, no? In union, drawn onward to new eras aged?");

I’m still creating a stripped down string using toLowerCase() and replace() with regex, and the Bonfire specifically alludes to these two methods so for this particular approach, I assume that those two methods are OK to use in this case. From here, we can get to a palindrome check using a for loop.

function palindrome(str) {
    var stripStr = str.toLowerCase().replace(/\W|\s/g, '');
    for (i = 0; i < stripStr.length; i++) {
        if (stripStr.charAt(i) != stripStr.charAt(stripStr.length - 1 - i)) {
            console.log("the string is not a palindrome.");
            return false;
        }
    }
    console.log("the string is a palindrome.");
    return true;
}
palindrome("Degas, are we not drawn onward, no? In union, drawn onward to new eras aged?");

All right, let’s step through this one slowly. We already know stripStr is removing the special characters, spacing and capitals from the string we’re checking. Once we have that, we head into a for loop.

The for loop iterates through i which is set to continue looping until i is greater than the length of stripStr. This ensures that we check all characters within the string and iterate through each as well. Inside of the for loop, we have an if conditional that checks both ends of our string. stripStr.charAt(i) begins at the start of the string, and stripStr.charAt(stripStr.length – 1 – i begins at the end of the string. charAt() is a method that checks the character at the specified parameter. Technically, you might refer to these as pointers on either end of the string, but I’m not confident if that’s really the terminology we want to use.

Regardless, the subtraction portion at the end ensures that we move through backwards iteration as we subtract 1 each time we loop through. In other words, each iteration moves one further into the string, either right or left, as the loop iterates through stripStr’s length. As the loop moves through, we check each character to its equivalent partner on the other end.

Here is a partial step through as I understand it:

Pass 1:
i = 0
Add 1 to stripStr.charAt(beginning)
degasarewenotdrawnonwardnoinuniondrawnonwardtonewerasaged
Subtract 1 from stripStr.charAt(end)

Pass 2:
Add 1 to stripStr.charAt(beginning)
degasarewenotdrawnonwardnoinuniondrawnonwardtonewerasaged
Subtract 1 from stripStr.charAt(end)

Pass 3:
degasarewenotdrawnonwardnoinuniondrawnonwardtonewerasaged
Add 1 to stripStr.charAt(beginning)

Subtract 1 from stripStr.charAt(end)

And on and on it goes until the two pointers reach the other end and have evaluated the entire string against each other. If the entire string matches on either end all the way through, our function returns true. If, at any point, there is a discrepancy and one of the characters doesn’t match the other character on the other end, our function returns false. Plug it into the Bonfire and it will evaluate appropriately.

A Faulty Sidetrack

What I attempted prior to checking for false was checking for true where:

if (stripStr.charAt(i) === stripStr.charAt(stripStr.length - 1 - i))

This evaluates perfectly for nearly everything except for a two-middle character non-palindrome such as almostomla, where it inaccurately evaluated the s and t and returned true for palindrome. Changing the deeply equivalent to deeply false resolved this issue and I’m frankly still trying to figure out why. If you have an explanation, let me know!

Bonfire’s Added Underscore (Update: 04/24/2017)

It would appear that I had a situation with my solution where the underscores the Bonfire threw at it would cause the code not to validate. The regex wasn’t written to recognize underscores, even though \W takes care of dashes. So, a quick fix for this would be to add an underscore selection to our regex. This isn’t the prettiest thing I’ve seen, but it’ll do: /\W|\_|\s/g

That means our updated solution would look like this:

function palindrome(str) {
  
  var stripStr = str.toLowerCase().replace(/\W|\_|\s/g,'');
  var checkStr = stripStr.split('').reverse().join('');
  
  if (stripStr === checkStr) {
    console.log("the string is a palindrome.");
    return true;
  } else {
    console.log("the string is not a palindrome.");
    return false;
  }
}
  
palindrome("Degas, are we not drawn onward, no? In union, drawn onward to new eras aged?");

Shout outs to Paul and Mike in the comments for pointing this out! And a sincere apology to Paul for getting to this so, so, so much later than I really meant to.

Resources

JSPerf, Is Palindrome?
Benchmarking solutions to check for palindromes. These show you efficiency specifically related to Palindrome checking. Great if you want to browse.

JSBeautifier
I’m always annoyed every time I copy and paste my code from Bonfire or my text editor into WordPress that it inexplicably loses all its formatting. So JSBeautifier really deserves a shout out.

StackOverflow, Check in JS for Palindromes
Great resource with tons of different solutions.

Regex Tester
If you ever thought to yourself, “Gee, I get way too much sleep at night and don’t have enough stress in my life”, get into Regex. It’s all around us! Regex101 is a good tool to use to test out the regex you write to see what it will and will not select.



Bonfire: Reverse a String Solution

It seems my previous Bonfire post has been fairly popular, so I figured I might as well share some of my other solutions in case someone might find it useful. This time, I’m tackling the Bonfire prior to the Factorializing one.

These solutions aren’t necessarily the best, most efficient way of solving the Bonfires. They’re just my approach to the problem. Within programming, coding and development, there’s usually multiple ways to solve the same problem. And depending on the philosophy of the coder, they might view certain approaches as more ideal than others. I’m just presenting what I have in case it helps someone.

Approaching the Problem

So the Free Code Camp Bonfire starts us off with the following code:

function reverseString(str) {
  return str;
}

reverseString('hello');

Already we see that we need to use a function that takes a parameter of str. Str in the function call has a value of “hello”. So, we are going to have to figure out how to reverse the string, “hello”. Having gone through the old Free Code Camp (they updated their lessons sometime in late-August) track that involved moving through Codeacademy’s JS course, we’ve encountered this problem before.

What I did for that solution was I separated the string by the letter and loaded them into an array. From that array, we can rebuild the string but backwards this time using a for loop. While this works, it’s hardly efficient and has us writing a ton of convoluted code to do something relatively simple.

Here’s what exists within JS to allow us to do this more efficiently. There are three pre-made functions within JS: split(), reverse() and join(). We can combine all three of these to quickly split up the string into an array that will resemble: [h, e, l, l, o], reverse it and turn it into [o, l, l, e, h], then join it back into a string: “olleh”.

The Immutable String Issue

Why do we need to turn the string into an array? Strings in JS are immutable. Immutable elements cannot be modified after they have been created.

So in the above code, str is set to a string that says “hello”. We cannot actually modify hello because it is immutable. That means, we can’t even do something as simple as reverse the string. To get around this, you have to turn the string into an array, reverse the array, then join the array back into a string. Because you join the array back into a string that will then say “olleh”.

Reversing the String & Returning It

Now we need to do all this in one step and on the str parameter. To combine functions you use the . (dot) operator. So it should look like this:

return str.split('').reverse().join('');

The above code is doing exactly what I said in the previous section. It is taking whatever str is, splitting it into an array. Then it reverses the array, then joins the array back into a string. Using a pre-built function allows us to sidestep the messy exercise of writing a loop.

So overall, this is what the final code looks like:

function reverseString(str) {
  return str.split('').reverse().join('');
}

reverseString('hello');

All this gets returned outside the function and the console in the Bonfire should return “olleh” and validate all the conditions.

Resources

Ten Ways to Reverse a String in JS, Edd Man
Really good resource for exactly what we’re facing in this Bonfire. It also includes the above solution using pre-built functions as well as a few other approaches using various loops. And one example using recursion if you really felt like it.

How Do You Reverse a String in Place in Javascript, StackOverflow
Excellent resource and discussion on how to reverse a string.



Bonfire: Factorialize a Number Solution

I’m going through FreeCodeCamp’s coding track as a way to brush up on Javascript, and re-familiarize myself with its more programming-centered features. I have been using Javascript primarily with websites. Most of the time, I’m not dealing with anything beyond timing, detecting user actions and maybe a little bit of animation. So and wanted to branch into more web application development. It’s also a good excuse to remind myself of programming practices without relying 100% on Swift–a language I’m still learning and is a few degrees more complex, versus doing it with Javascript–a language I’m more comfortable with.

I was cruising along fine with my skills map. A large proportion of the first few lessons centers around Codecademy’s online Javascript track. When I finished it up, FreeCodeCamp introduces the concept of Paired Programming and Bonfires. I decided to look into a couple of the the Bonfires on my own. The first three were pretty standard challenges. In fact, #1 and #2 weren’t actual challenges. #3 took a tiny bit of research and I had encountered it before while learning C++. Then I hit the fourth, where it tells you to Factorialize a Number. It was a great exercise that made me think outside of my comfort zone. After trying some really sloppy loops, I ended up with a recursive function.

I’m going to show both of my approaches to this one, first with the recursive function and second using a for loop. I’ve seen both approaches, and I’m by no means an expert at this. I just want to store my attempts at these challenges and walk through them to gain a better understanding. And if it helps someone else understand it too, then great!

Let’s Factorialize a Number

The first thing I had to establish was what factorializing a number is actually about. The explanation was clear cut enough, but being a math dummy, I had to question myself every time I looked at it. And it was as simple as it seems. In laymans terms, when you factorialize a number, you are multiplying that number by each consecutive number minus one. So for example, if your number was 3. You would have something like this:

3! = 3 * 2 * 1

There’s a pretty easy pattern for this:

0! = 1
1! = 1
2! = 2 * 1
3! = 3 * 2 * 1
4! = 4 * 3 * 2 * 1

And on and on, so by the time you reach, let’s say, 9 for example, you might have this:

9! = 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1

Factorials are expressed in shorthand as x!, so when you see a number or value with an exclamation mark, you should know that we’re looking at factorials. Now that we kind of understand how that works, we can try to express that in code.

Breaking It Down With a Math Dummy

I said it before, and it needs to be said again. I am bad at math. Terrible at it. I don’t know if it’s because of the way math was taught to me, or what. But me and math don’t go well together. However, even if you are as terrible at math as I am, this one is solvable! So here’s how I broke it down. The Bonfire on FreeCodeCamp starts you off with this:

function factorialize(num) {
  return num;
}

factorialize(5);

Right off the bat, you know they want you to factorialize 5. They also want this written inside of a function called “factorialize”. That’s stuff we already know. So here’s what I was thinking…

1. Since we are essentially looking at determining what num is and then multiplying it by each consecutive number minus one, that can expressed like this num(-1). We need to stop it when num is equal to 1 because going further means hitting 0.

2. In factorials, 0! is always 1. Because multiplying by 0 will frequently return 0, we need to have an exception to prevent that from occurring when the function runs. So we probably need an if conditional statement that checks for 0 and returns 1. Since the conditional will check for and weed out 0, anyway, it might prevent num(-1) from ever getting there.

3. I’ll weed out 0 with the if conditional first. Then deal with num(-1) in a recursive function–which is kind of a hairy exercise for people might be completely new to coding.

Writing Out the Code

Let’s start by doing Step 1 under the break down above. I’m going to weed out the incidence of hitting 0 using an if conditional.

function factorialize(num) {
  if (num === 0) {
         return 1;
      }
}

That was the easy part. What this does is evaluate num. If it detects num is equal to 0 at any point, it will run the statement inside of the if conditional and return 1. Dealing with the recursive function next is where it gets tricky. Though the code is minimal, sometimes the most minimalist of things are the most complicated.

function factorialize(num) {
  if (num === 0) {
         return 1;
      }
   return num * factorailize(num-1);
}

Oh boy, recursive functions. This is something I see in Swift and it always makes me go cross-eyed. Recursive functions run inside of themselves. So you might run a non-recursive function and it spits out a return value and you move on with your life. If you run a recursive function, it spits out a value that gets run again within the function, spits out another value which then gets run again in the function, spits out another and gets run again…on and on until it exits the recursion.

It’s hard to visualize this for me, but the best way is to remember sixth grade math and the order of operations (which, funny enough, is a core component of programming). Within the hallowed rule book of order of operations, you would perform the calculations inside of the parenthesis first. So if you had a formula like this:

(5 * 6) + 9 = n

You would do 5 * 6 first, then take the value you got from that and add 9 to get n. A similar thing is happening with our code. We are first taking num, subtracting 1, then using that value to multiply by num.

So if you had num set to 5, we would be returning this on factorialize()’s first pass:

5 * (5-1)

Second pass:

5 * (4-1)

Third pass:

5 * (3-1)

Fourth pass:

5 * (2 -1)

Fifth pass:

5 * (1-1)
return 1
5 * 1

During the fifth and final pass, our function falls into the if conditional. It returns 1 which num will multiply itself with and the function will exit with a total value.

In the case of factorialize(5). You should get 120. So, the final code all written out:

function factorialize(num) {
  if (num === 0) {
  return 1;
}
     return num * factorialize(num-1);
}

factorialize(5);

We pass a parameter of 5 to factorialize(). It takes it into the function as num and checks if num is equal to 0. If num is equal to 0 it returns 1 and factorializes it as 5(1), where it will stop the recursion. If it’s not 0, it takes num and multiplies it by whatever num-1 is and continues to perform this action until num is equal to 0. The final return is the factorialization of the number 5 that we passed into factorialize(). That number should be 120.

The For Loop Alternative

A for loop will also work as a solution to this Bonfire. There might be other solutions too, because a lot of problems in code can be solved multiple ways depending on style, approach and preferences. I just don’t know of any others. I had actually written a for loop that validates on Free Code Camp and technically does the same thing. I’ve seen others use this approach as well. Though it’s quite a bit more legwork. Here it is:

function factorialize(num) {
  
  for (var i = num - 1; i >= 1; i--)
    num *= i;
  if (num === 0) {
    return 1;
  } else {
    return num;
    }
}

factorialize(5);

Above, we have a for loop within factorialize() that will continue to run so long as i remains greater than or equal to 1. In the above for loop, we make i equal to num -1. Then check if i is still greater than or equal to 1. If it is, then subtract 1 from i, and run the block of code. Within the block, we take num and multiply it by whatever i is. Then we return the result, which in this case should be 120.

More recently (or I could have just overlooked it), FreeCodeCamp added a check for 0 (thus foiling my plans) so I added an if conditional to check for 0 and return 1 if num === 0 ever evaluates to true. Thanks go out to Lena for bringing this to my attention in the comments.

I have a feeling there’s a more elegant way to express this in the For Loop so if you have alternatives or suggestions let me know!

Resources

Bonfire: Factorialize a Number – luishendrix92
One of the more amusing explanations of what a recursive function is. This approach is pretty close to what I got, but it features a check for 1 as well as 0. I’m not sure if you really need that check for 1 and if I’m missing out on anything by not checking for 1 in my own solution. Or it could be another case of different approaches, different styles.