MTG
MTG

Reputation: 163

Python - Shift/Delete Elements in a 2-Dimensional Array

I need help with shifting and deleting elements in a 2-dimensional array.

  1. If the value in a list is negative and their is a list above it with positive values in the same location. It should shift everything down, causing the negative values to disappear.

  2. If there isn't any list above it or the corresponding values in the list above are just 0. It will replace the negative values with 0.

Note: The positive values should never disappear, they can only move down when needed. Only the negative values (below -100) disappear.

These examples should explain it better:

Scenario 1:

DATA: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0], [-103, -103, -103, 0, 0]]

EXPECT: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]

Scenario 2:

DATA: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, -101, -101, -101], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]

EXPECT: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]

Scenario 3: (This is the only one that I got working in my code below.)

DATA: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [-102, -102, -102, 0, 0], [3, 1, 3, 0, 0]]

EXPECT: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]

def move(data):

    c_count = 4

    while c_count >= 0:

        count = len(data) - 1
        prev = count - 1

        while count > 0 and prev >= 0:
            if data[count][c_count] < -100:

                while prev >= 0 and data[prev][c_count] == 0:
                    prev -= 1

                data[count][c_count] = data[prev][c_count]
                data[prev][c_count]= 0

            count -= 1
            prev -= 1

        c_count -= 1

    return data

my_data = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [-102, -102, -102, 0, 0], [3, 1, 3, 0, 0]] 
x = move(my_data) # This is (scenario 3) is the only one that works. 
print(x)

Thanks so much for your help! I have been stuck on this for a while.

Upvotes: 0

Views: 932

Answers (2)

furas
furas

Reputation: 142641

I work with columns separately, not with full rows.

  • search in column from bottom to top
  • find negative value
  • find positive value (bigger then zero) above
  • if not found then put zero in place of negative
  • if found then move down all value above
    move above to row, above-1 to row-1, above-2 to row-2, etc.

BTW: it is easier to search solution when rows are displayed one below another.

def move(data):

    # work in column, not with full rows
    for col in range(len(data)):

        # move from bottom to top
        for row in range(len(data[0])-1, -1, -1):

            # check if negative value
            if data[row][col] < 0:
                print('debug: negative:', data[row][col])

                # find positive value above
                above = row-1
                while above > -1 and data[above][col] <= 0:
                    above -= 1

                # check if found positive value 
                if above == -1:
                    # put zero if not found value above
                    print('debug: put zero')
                    data[row][col] = 0
                else:
                    # move down all values above 
                    print('debug: move down', above+1, 'element(s)')
                    while above > -1:
                        data[row][col] = data[above][col]
                        data[above][col] = 0
                        row -= 1
                        above -= 1

    return data

# --- function to run one scenario, display data and check result ---

def run(data, expect):
    print('data:')
    print('\n'.join(str(row) for row in data))
    print()
    result = move(data)
    print()
    print('result:')
    print(result)
    print('expect:')
    print(expect)
    print('expect == result:', expect == result)
    print('---')

# --- scenarios ---

def scenario1():

    DATA = [
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [1, 2, 1, 0, 0], 
        [2, 1, 2, 0, 0], 
        [-103, -103, -103, 0, 0]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [1, 2, 1, 0, 0], 
        [2, 1, 2, 0, 0]
    ]

    run(DATA, EXPECT)

def scenario2():

    DATA = [
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [0, 2, -101, -101, -101], 
        [0, 1, 2, 3, 2], 
        [0, 3, 3, 2, 3]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [0, 2, 0, 0, 0], 
        [0, 1, 2, 3, 2], 
        [0, 3, 3, 2, 3]
    ]

    run(DATA, EXPECT)

def scenario3(): #(This is the only one that I got working in my code below.)

    DATA = [
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [1, 3, 1, 0, 0], 
        [-102, -102, -102, 0, 0], 
        [3, 1, 3, 0, 0]
    ]

    EXPECT = [
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [0, 0, 0, 0, 0], 
        [1, 3, 1, 0, 0], 
        [3, 1, 3, 0, 0]
    ]

    run(DATA, EXPECT)

# --- start scenarios ---

scenario1()
scenario2()
scenario3()

Results:

data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[1, 2, 1, 0, 0]
[2, 1, 2, 0, 0]
[-103, -103, -103, 0, 0]

debug: negative: -103
debug: move down 4 element(s)
debug: negative: -103
debug: move down 4 element(s)
debug: negative: -103
debug: move down 4 element(s)

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 2, -101, -101, -101]
[0, 1, 2, 3, 2]
[0, 3, 3, 2, 3]

debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero
debug: negative: -101
debug: put zero

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
expect == result: True
---
data:
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[1, 3, 1, 0, 0]
[-102, -102, -102, 0, 0]
[3, 1, 3, 0, 0]

debug: negative: -102
debug: move down 3 element(s)
debug: negative: -102
debug: move down 3 element(s)
debug: negative: -102
debug: move down 3 element(s)

result:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]
expect:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]
expect == result: True
---

Upvotes: 1

Bharath M Shetty
Bharath M Shetty

Reputation: 30605

Here's a simple numpy approach i.e

import numpy as np 
def get_arr(arr):
    arr = np.array(arr)
    arr[arr<1] = 0
    new_arr = arr[np.argsort(arr.sum(1)),:]
    return new_arr.tolist()

arr = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0], [-103, -103, -103, 0, 0]]
arr1 = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, -101, -101, -101], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
arr2 = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [-102, -102, -102, 0, 0], [3, 1, 3, 0, 0]]

print(get_arr(arr))
print(get_arr(arr1))
print(get_arr(arr2))
#[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 2, 1, 0, 0], [2, 1, 2, 0, 0]]
#[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 1, 2, 3, 2], [0, 3, 3, 2, 3]]
#[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 3, 1, 0, 0], [3, 1, 3, 0, 0]]

Upvotes: 0

Related Questions