1

There is a task on CodeFights involving building a two-dimensional array:

A spiral matrix is a square matrix of size n × n. It contains all the integers in range from 1 to n * n so that number 1 is written in the bottom right corner, and all other numbers are written in increasing order spirally in the counterclockwise direction.

Given the size of the matrix n, your task is to create a spiral matrix.

One is supposed to fill only one gap denoted by ... in the following code:

def createSpiralMatrix(n):
    dirs = [(-1, 0), (0, -1), (1, 0), (0, 1)]
    curDir = 0
    curPos = (n - 1, n - 1)
    res = ...

    for i in range(1, n * n + 1):
        res[curPos[0]][curPos[1]] = i
        nextPos = curPos[0] + dirs[curDir][0], curPos[1] + dirs[curDir][1]
        if not (0 <= nextPos[0] < n and
                0 <= nextPos[1] < n and
                res[nextPos[0]][nextPos[1]] == 0):
            curDir = (curDir + 1) % 4
            nextPos = curPos[0] + dirs[curDir][0], curPos[1] + dirs[curDir][1]
        curPos = nextPos

    return res

When I fill in the following code, all tests are passed:

res = [[0 for item in range(n)] for sublist in range(n)]

However, if I slightly change it to:

res = [[None for item in range(n)] for sublist in range(n)]

I receive the following error message:

Execution error on test 1: Something went wrong when executing the solution - program stopped unexpectedly with an error.
Traceback (most recent call last):
  file.py3 on line ?, in getUserOutputs
    userOutput = _runiuljw(testInputs[i])
  file.py3 on line ?, in _runiuljw
    return createSpiralMatrix(*_fArgs_jlosndfelxsr)
  file.py3 on line 8, in createSpiralMatrix
    res[curPos[0]][curPos[1]] = i
IndexError: list index out of range

Test 1 Input: n: 3 Output: Empty Expected Output: [[5,4,3], [6,9,2], [7,8,1]] Console Output: Empty

The same result (with the error message) is with the following code:

res = [list(range(n)) for sublist in range(n)]

All three options build arrays of the same size:

n = 3

res = [[0 for item in range(n)] for sublist in range(n)]
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

res = [[None for item in range(n)] for sublist in range(n)]

[[None, None, None], [None, None, None], [None, None, None]]

res = [list(range(n)) for sublist in range(n)]

[[0, 1, 2], [0, 1, 2], [0, 1, 2]]

Am I missing something obvious?

1 Answer 1

1

If you want it to work with None, then you simply have to change the third condition of your if not ... statement to agree with how you initialized res. Otherwise, nextPos will incorrectly become out of the range of your 2D array.

def createSpiralMatrix(n):
    dirs = [(-1, 0), (0, -1), (1, 0), (0, 1)]
    curDir = 0
    curPos = (n - 1, n - 1)
    res = [[None for item in range(n)] for sublist in range(n)]

    for i in range(1, n * n + 1):
        res[curPos[0]][curPos[1]] = i
        nextPos = curPos[0] + dirs[curDir][0], curPos[1] + dirs[curDir][1]
        if not (0 <= nextPos[0] < n and
                0 <= nextPos[1] < n and
                res[nextPos[0]][nextPos[1]] is None): # Changed this line
            curDir = (curDir + 1) % 4
            nextPos = curPos[0] + dirs[curDir][0], curPos[1] + dirs[curDir][1]
        curPos = nextPos

    return res
Sign up to request clarification or add additional context in comments.

2 Comments

Could you please elaborate why the difference?
In your original code, the third condition was res[nextPos[0]][nextPos[1]] == 0. But you initialized res to all None entries. So, why would you expect that condition to ever be true? If you initialized res with "asdf", then that third condition should be res[nextPos[0]][nextPos[1]] == "asdf". The problem was never that your 2D array was the wrong size. The problem was that you initialized it with None, then compared it against 0.

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.