0

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

4
  • On which line does that error come? Commented May 13, 2014 at 8:31
  • on the "if world[y][x] != M" Commented May 13, 2014 at 8:32
  • It should be def continent_size(world,x,y) i guess. Commented May 13, 2014 at 8:33
  • still gives the same error Commented May 13, 2014 at 8:35

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! It's pretty much what I thought, but why does the original code without the check does work then? And how exactly do negative numbers work with arrays?
It shouldn't and it doesn't, at least in my irb. Can you try running it again?
Well now it doesn't... I have to say I'm thoroughly confused

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.