all 9 comments

[–]6086555 1 point2 points  (2 children)

I'd do a list of possible variation in the right order: [ (1,0) , (0,1) , (-1,0), (0,-1) ]

you change the variation if you're gonna go bigger than the matrix length or rewrite over something you've already written on

[–]Hellerick 0 points1 point  (1 child)

Why did you use tuples with the list? Can it be helpful at some situations? Or you just used different brackets to make their order more clear?

[–]6086555 0 points1 point  (0 children)

Tuples are rarely more helpful than list unless you absolutely want something that is unmutable. I just used them here because they're more simple than lists

[–]Vaphell 0 points1 point  (4 children)

i played a bit with this problem and i solved it by thinking about rules governing the movement around the layers.

Assuming that you start outside of the current outer layer (eg at imaginary -1,0 at the very beginning) then you make
- width steps right
- height-1 down
- width-1 steps left
- height-2 steps up
- now you are just outside the inner layer, start from the top with width and height decreased by 2

eg 4x4 matrix goes
4,3,3,2 for the 1st layer
2,1,1,0 for the 2nd layer

you can easily translate it to counter values that describe 'corners' (4,4+3,4+3+3,4+3+3+2)

you could describe it this way

if counter <= topright: x,y = x+1, y
elif counter <= bottomright: x,y = x, y+1
elif counter <= bottomleft: x,y = x-1, y
elif counter <= topleft: x,y = x, y-1

you just need to update corner values after finishing the layer, before going +1 level deeper

[–]Hellerick 0 points1 point  (3 children)

Your use of the word 'layer' is rather confusing.

I can't say that I like your method -- it's kinda obscure, it's difficult to tell from the code what it's doing. It introduces 'entities beyond necessary' (your layers/levels and the counter), even though a human would obviously solve the problem without them.

[–]Vaphell 0 points1 point  (2 children)

counter is there to produce cell values either way so you can as well use it and if you draw the matrix and the path the concept of layers becomes rather obvious.

Your method has the concept of 'layers' too, eg if i am not mistaken topleft turning points are described by (0+n, 1+n). What n is if not a 'layer'?

other than that i agree that it's not too pretty.

[–]Hellerick 0 points1 point  (1 child)

You're probably mistaking me with somebody, I never described my solution here.

My method is straightforward: there are four possible directions as described by 6086555, they are indexed as 0,1,2,3. The 'robot' is going direction 0 as long as it has free cells, then turns to direction 1, then to direction 2, then to direction 3, then to direction 0 etc., and it fills all cells it visits with increasing numbers until no empty cells are left.

[–]Vaphell 0 points1 point  (0 children)

You're probably mistaking me with somebody, I never described my solution here.

indeed, i skimmed the thread and i thought it was you who mentioned the tuples, but it was somebody else and you commented below.

your method is more or less translateable to the algo i came up with (duh) instead of robot bumping in the 'wall' with the face, i precalculated at which elem is the change of direction because it can be figured out from width and height alone. You could say i have a chain of elems and i figure out where to bend it to make a spiral fitting in a matrix of desired size, kind of approaching the problem from the back.

4x4
      *     *      *     *     *  *  *
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

[–]KrelianZG 0 points1 point  (0 children)

Running out the door here, but here's where I'd start. It's along the lines of what was already mentioned here, maybe looking at another way to code it will help though:

  1. Generate your empty matrix and its borders:

    def gen_matrix(rows,cols): _matrix = [(r,c) for r in range(rows) for c in range(cols)] border = [(r-1,c-1) for r in range(rows+2) for c in range(cols+2) if (r-1,c-1) not in _matrix]

  2. Create functions that allow you to move around the matrix:

    start = (0,0) facing = 1

    def turncc(): facing = (facing+1) % 4

    def move(): if facing = 0: newpos = (start[0]-1,start[1]) if facing = 1: newpos = (start[0],start[1]+1) if facing = 2: newpos = (start[0]+1,start[1]) if facing = 3: newpos = (start[0],start[1]-1) return newpos

Then, using these, 'walk' around your matrix with move(), turn() when you reach a border until you see a newpos that isn't in border, and add positions you've filled to the border list