Question

I've recently been trying to learn ruby using Learn to Program by Chris Pine, and at chapter 10 he gives a recursive code for counting continent size

M = 'land'
O = 'water'

world = [[O, O, O, M, O, O, O, O], 
         [O, O, M, M, O, O, M, O], 
         [M, M, M, M, M, O, O, M], 
         [M, M, O, M, O, O, O, O],
         [O, M, M, M, M, O, O, O],
         [O, O, M, M, O, M, M, M], 
         [O, O, M, O, O, O, O, O]]

def continent_size world, x, y
    if world[y][x] != M
        return 0
    end

    size = 1
    world[y][x] = 'counted'

    size += continent_size world, x-1, y-1
    size += continent_size world, x, y-1
    size += continent_size world, x+1, y-1
    size += continent_size world, x-1, y
    size += continent_size world, x+1, y
    size += continent_size world, x-1, y+1
    size += continent_size world, x, y+1
    size += continent_size world, x+1, y+
    size
end
puts continent_size world, 5, 5

in the book he states that this code would give errors if some of the land is attached to the edge (which, as you can see, I tried), but the code runs just fine. When I did try adding very simple checks, as in:

def continent_size world, x, y
    if y < 0
        return 0
    end
    if world[y][x] != M
        return 0
    end
    .
    .

suddenly I get "undefined method '[]' for nil:NilClass" error on "if world[y][x] != M" line and I really have no idea what have changed to cause this. Where is this error coming from?

edit: after some testing it does seem like the problem now is with the numbers being out of bound, since the following does work:

def continent_size (world, x, y)
    if y < 0 || y > 6 || x < 0 || x > 7
        return 0
    end
    if world[y][x] != M
        return 0
    end
    .
    .

I'm still confused as to why the original code worked with no problems though

Was it helpful?

Solution

You have the problem with edges, if your world is 5x5 then you are calling world[6][6] against it (negative numbers still works). world[6] return nil, which does not define [] method.

To fix it, you need to add:

def continent_size world, x, y
  if y < 0 || world[y].nil? || world[y][x] != M
    return 0
  end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top