Tag Archives: blocks

The Locker Problem

I was recently given a puzzle to solve in Ruby called “The Locker Problem”. Hearing it for the first time kind of made me feel overwhelmed, but that’s what motivated me to try to solve it. After a lot of thinking, I’ve finally figured it out. The solution actually ended up being a lot simpler than I made it out to be in my head. Here’s the puzzle, as well as the solution and my thought process in solving it:

In front of you, there are 100 open gym lockers in a row.
You walk around the entire row 100 times. The first time,
you stop at each locker and close all the opened ones. The
second time around, you stop at each 2nd locker and open
the ones that are closed. The third time around, you stop at each
3rd locker and close the ones that are opened and open the ones
that are closed. You continue this pattern until you’ve done it a
total of 100 times.
At the end, which lockers are opened and which are closed?

Did reading that puzzle make your head hurt? This is actually pretty simple to solve after breaking it down piece by piece. First, I’ll show you my solution:

Ruby

As you can see, it doesn’t take a lot of code to solve this puzzle but there’s a lot going on. Let’s break it down.

First we create an array representing 100 opened lockers (true == open). For our loop that will represent walking around the lockers 100 times, we use 'i' as a placeholder and assign 1 to it. This will represent the first time walking around the lockers, stopping at each locker. Therefore, 'i' will represent the rounds we take around the lockers. At first glance, it may seem to you that we’re only walking around the lockers 99 times but remember that we’re already starting at the first round (i = 1) and therefore adding 1 to 'i' 99 more times. Totaling 100 times that we’ll walk around the lockers.

(0..open_lockers.size - 1) is a range from 0-99 that represents the index positions of all 100 lockers in our array. .step is a method that iterates through a range and passes every nth element to the supplied block. For example, lets say we’re walking around the lockers for the 2nd time. This means that 2 will be supplied to the .step method as a parameter. .step will then start at 0 and pass each 2nd element to the block, including 0. (0, 2, 4, 6, 8,…). If this made you notice a potential problem with properly identifying the lockers, then you’re doing great (I figured it out the hard way). The problem is that if we’re trying to identify every 2nd locker, the 0, 2, 4, 6, 8,… index positions are actually going to identify the 1st, 3rd, 5th, 7th, 9th,… lockers. This is why we subtract 1 from the index positions to properly identify the correct locker that we’re trying to access within the array. So in actuality, the index positions we’ll be accessing are [-1, 1, 3, 5, 7,…]. This will properly identify every 2nd locker (100th, 2nd, 4th, 6th, 8th,…98th). Now we can be certain that all 100 times that we walk around the lockers, we’ll be closing or opening the correct ones.

We then use a boolean expression (or flow control) that represents closing a locker if it is open, or opening a locker if it is closed.

Lastly, we pass the each_with_index method to the open_lockers array that iterates
through the array, grabbing each locker and it’s index position. We then use string interpolation to add 1 to the index position to properly display the locker onto the screen. i.e. Locker #1 instead of Locker #0 (that wouldn’t make much sense). We also use string interpolation to display “Opened” onto the screen if the locker is ‘true’ or “Closed” if ‘false’.

Tagged , , , , ,

Ruby Blocks, Procs, and Lambdas

I’ve always had a hard time understanding the differences between a block, a proc, and a lambda and an even harder time understanding when to use which. A friend of mine recommended reading a simple tutorial cleverly named “Understanding Ruby Blocks, Procs and Lambdas” written by Robert Sosinski. So far, this has been the most straightforward explanation of closures in Ruby that I have found, it doesn’t get too complicated and Robert provides detailed examples of the differences between these different types of closures in Ruby. Here are some of my takeaways:

  1. Block: A block is essentially a proc but cannot be saved as an object or assigned to a variable and is therefore a “one time” use solution. Also, a block itself cannot be passed to a method as an argument.
  2. Proc: A proc is a block that can be saved as an object, stored in a variable, and passed to a method as an argument. Since procs are objects, they can be reused in your code over and over again. Besides this obvious benefit, the real benefit comes when you need to pass more than one block to a method. Because procs are objects themselves, you can pass as many procs as you want as method arguments.
  3. Lambda: A lambda is like another way of writing methods, but anonymously. When writing code or going through the tutorial above, you’ll notice that using a lambda looks almost exactly like using a proc; at first it will seem like there isn’t any difference at all. This is why it is important to remember the conceptual differences between lambdas and procs; a lambda is like an anonymous method and a proc is a procudure, or a drop in code snippet, as Robert describes them. If this still doesn’t help you understand what a lambda is or what the differences are between a proc, don’t worry, it didn’t help me much either. Robert Sosinski provided some great examples describing the subtle differences though. Here’s what I took away from it all:
      • Because lambdas are like methods, they check the number of arguments passed (unlike procs) and return an ArgumentError in the case that the wrong number of arguments are passed. Procs on the other hand will simply set any extra arguments passed to nil.
      • A lambda will return it’s value to the method and let the method continue to process the rest of the code. However, if you instead had a proc within that same method, the proc will stop processing the rest of the method once it hits it’s return keyword. Here’s the code snippet from Robert Sosinski’s tutorial:

Ruby Procs & Lambdas

        • Lastly, because a lambda acts like a method, you can pass a lambda containing a return keyword as an argument to another method. A proc containing a return keyword however, cannot be passed as a method argument.

Conclusion: When to use

  • Block: I’ve concluded from reading this tutorial that a block should be used over a proc when you simply want to break an object down and manipulate those elements in some sort of way.
  • Proc: A proc should be used over a block when you want to reuse a block of code multiple times and when you have a method that needs to take more than one block as arguments.
  • Lambda: I’ve concluded that the benefits of using a lambda over a proc (argument checking and return values) are minor and what you use will depend on your preference and what makes most sense to you.

What are your thoughts?

Tagged , , , , , ,
%d bloggers like this: