Christopher
Christopher

Reputation: 25

How to shift the columns of a 2D array multiple times, while still considering its original position?

Alright, so consider that I have a matrix m, as follows:

m = [[0, 1, 0, 0, 0, 1],
     [4, 0, 0, 3, 2, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0]]

My goal is to check each row of the matrix and see if the sum of that row is zero. If the sum is not zero, I want to shift the column that corresponds to that row to the end of the matrix. If the sum of the row is zero, nothing happens. So in the given matrix above the following should occur:

  1. The program discovers that the 0th row has a sum that does not equal zero
  2. The 0th column of the matrix is shifted to the end of the matrix, as follows:

    m = [[1, 0, 0, 0, 1, 0],
         [0, 0, 3, 2, 0, 4],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0]]
    
  3. The program checks the next row and does the same, shifting the column to the end of the matrix

    m = [[0, 0, 0, 1, 0, 1],
         [0, 3, 2, 0, 4, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0]]
    
  4. Each of the other rows are checked, but since all of their sums are zero no shift is made, and the final result is the matrix above.

The issue arises after shifting the columns of the matrix for the first time, once all of the values are shifted it becomes tricky to tell which column corresponds to the correct row.

I can't use numpy to solve this problem as I can only use the original Python 2 libraries.

Upvotes: 1

Views: 856

Answers (2)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250981

Use a simple loop and when the sum is not equal to zero loop over rows again and append the popped first item to each row.

>>> from pprint import pprint
>>> m = [[0, 1, 0, 0, 0, 1],
    [4, 0, 0, 3, 2, 0],
    [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0]]
>>> for row in m:
    # If all numbers are >= 0 then we can short-circuit this using `if any(row):`.
    if sum(row) != 0:
        for row in m:
            row.append(row.pop(0))
...
>>> pprint(m)
[[0, 0, 0, 1, 0, 1],
 [0, 3, 2, 0, 4, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0]]

list.pop is O(N) operation, if you need something fast then use collections.deque.

Upvotes: 2

stamaimer
stamaimer

Reputation: 6475

deque can rotate elements.

from collections import deque

def rotate(matrix):

    matrix_d = [deque(row) for row in matrix]

    for row in matrix:

        if sum(row) != 0:

            for row_d in matrix_d:

                row_d.rotate(-1)

    return [list(row) for row in matrix_d]

Upvotes: 1

Related Questions