I don't quite understand how to "initialize a multidimensional array to equal 1" as the initial for loops seem to suggest here. I haven't learned to properly read pseudocode, and I don't fully understand how this program works.
function countRoutes(m,n)
grid ← array[m + 1][n + 1]
for i = 0 to m do
grid[i][0] ← 1
end for
for j = 0 to n do
grid[0][j] ← 1
end for
for i = 1 to m do
for j = 1 to n do
grid[i][j] ← grid[i − 1][j] + grid[i][j − 1]
end for
end for
return grid[m][n]
end function
Thanks for your help!
This isn't hard to translate.. Ruby uses
=
instead of left arrow for assignment, anddef
instead offunction
to define a subroutine (which it calls a method instead of a function), but that's about it. Let's go through it.That's beginning a function definition. In Ruby we use a method instead, and the keyword to define such a thing is
def
. It's also convention in Ruby to use snake_case for multiword names instead of camelCase:Now to create the grid:
Ruby arrays are dynamic, so you don't normally need to specify the size at creation time. But that also means you don't get initialization or two-dimensionality for free. So what we have to do here is create an array of m+1 arrays, each of which can be empty (we don't need to specify that the sub-arrays need to hold n+1 items). Ruby's Array constructor has a way to do just that:
Now the initialization. Ruby technically has
for
loops, but nobody uses them. Instead, we use iterator methods. For counting loops, there's a method on integers calledtimes
. But the pseudocode counts from0
throughm
inclusive;times
also starts at0
, but only counts up to one less than the invocant (so that way when you call3.times
, the loop really does execute "three times", not four). In this case, that means to get the behavior of the pseudocode, we need to calltimes
onm+1
instead ofm
:As an aside, we could also have done that part of the initialization inside the original array creation:
Anyway, the second loop, which would be more awkward to incorporate into the original creation, works the same as the first. Ruby will happily extend an array to assign to not-yet-existent elements, so the fact that we didn't initialize the subarrays is not a problem:
For the nested loops, the pseudocode is no longer counting from 0, but from 1. Counting from 1 through m is the same number of loop iterations as counting from 0 through m-1, so the simplest approach is to let
times
use its natural values, but adjust the indexes in the assignment statement inside the loop. That is, where the pseudocode starts countingi
from 1 and referencesi-1
andi
, the Ruby code starts countingi
from 0 and referencesi
andi+1
instead.And the
return
statement works the same, although in Ruby you can leave it off:Putting it all together, you get this: