In our Hack Reactor remote program, we were given a "Toy Problem" every morning to solve. A Toy Problem is an algorithm that we have about 45 minutes to solve (that's the goal but we have until the next day to turn it in). Many of them are best solved using recursion and most if not all take advantage of a for loop or while loop. Any time you are solving something recursively or using a loop, you have to be careful of inadvertently creating an infinite loop and getting the dreaded "call stack size exceeded" or worse, locking up your browser and being forced to restart it.

I recently had a Toy Problem with an infinite loop and it took me at least an hour to find the problem, mostly because I refused to debug because I thought I knew where the problem was. Turns out it was in a while loop all along that if I'd just debugged it from the start, I would have found right off. However, I'm going to show you how to debug your JavaScript using WebStorm, a great IDE and one that I'm coming to cherish.

I'll lay out the Toy Problem and my solution if for no other reason than to have a good problem to dig into and discuss possible infinite loops. Now I admit, I'm most often worried about an infinite loop in a recursive solution and the solution below does not use recursion. So, I was not on the lookout for that dreaded loop of infinity. You could say I was snoozing. This problem assumes a prior knowledge of stacks and queues.

Here's the prompt for the problem.

Write a stack using your preferred instantiation pattern. Once you're done, implement a queue using two stacks.

Now, let's just say right off that it doesn't make much sense to use a stack for a queue but for Toy Problems, anything goes.

Here's my solution with bug included so see if you can spot it.

/**
  * Stack Class
  */
var Stack = function() {
  this.start = 0;
  this.end = -1;
  this.storage = {};
};

Stack.prototype.push = function(value){
  this.storage[++this.end] = value;
};

Stack.prototype.pop = function(){
  if( this.size() <= 0 ) {
    return null;
  } else {
    var popped = this.storage[this.end];
    delete this.storage[this.end];
    this.end--;
    return popped;
  }
};

Stack.prototype.size = function(){
  return this.end - this.start + 1;
};

/**
  * Queue Class
  */
var Queue = function() {
  // Use two `stack` instances to implement your `queue` Class
  var inbox = new Stack();
  var outbox = new Stack();

  // called to add an item to the `queue`
  this.enqueue = function(value){
    inbox.push(value);
  };

  // called to remove an item from the `queue`
  this.dequeue = function(){
    if( this.size() === 0 ) { return null; }
    if( outbox.size() === 0 ) {
      while(inbox.size() !== 0) {
        outbox.push(inbox.pop());
      }
    var result = outbox.pop();
    }
    while(outbox.size() >= 0) {
      inbox.push(outbox.pop());
    }
    return result;
  };

  // should return the number of items in the queue
  this.size = function(){
    return inbox.size() + outbox.size();
  };
};

Note that I've gone the route of using an object for storage but it could more easily be handled with an array because you wouldn't need to keep track of the start and the end. We are using the Pseudo-classical style of instantiation here which will take the new keyword when an instance is created from the constructor functions.

So, you probably spotted it but even so, check out this short webcast showing how I used WebStorm to quickly help me debug this problem and kept me from crashing my browser, even with an infinite loop.

And now you know that the issue was in my while loop. Instead of the code I have above, I want to keep popping from the outbox and pushing to the inbox until there is nothing left in the outbox. But the way I had it, while( outbox.size() >= 0 ) sets up a condition which creates an infinite loop. The last pop will leave the outbox empty but my while loop will keep cycling because a size of zero still satisfies the condition. The corrected version of the while loop is below.

while(outbox.size() !== 0) {
   inbox.push(outbox.pop());
}

One tiny oversight in your logic will create that infinite loop that will make you pull your hair out. If you are using WebStorm, the technique showed in the video above can help you quickly bebug and move on with your life.