Hal Lawrence
Hal Lawrence

Reputation: 111

Functions: Shift items in different directions within list?

I need to return a Boolean if moving values across the list is possible. '.' are empty spots where strings could move to. For the 1st func, how would I shift both identical values left and right? I'm not sure how to define the left and right variables and was wondering if I need the pop.() to delete the spot I'm moving the variables to.

area1 = [['.', '.', '.', 'e'], 
         ['A', 'A', '.', 'e'], 
         ['.', 'X', '.', 'e'], 
         ['.', 'X', 'Y', 'Y'], 
         ['.', '.', 'Z', 'Z']]

def shift_horizontal(value, direction, area):
    for i in range(len(area)-1):
        for j in range(len(row)-1):
            if right and value[i] == '.'[i+1]: # Will shift right if value next is '.'
                return True
            elif left and value[i] == '.'[i-1]: # Will shift left if value next is '.'
                return True
            else:
                return False
shift_horizontal('A', right, area1)

How the list should look like after(I don't actually need to return the list, just a visual reference):

area1 = [['.', '.', '.', 'e'], 
         ['.', 'A', 'A', 'e'], 
         ['.', 'X', '.', 'e'], 
         ['.', 'X', 'Y', 'Y'], 
         ['.', '.', 'Z', 'Z']]

I plan to write a 2nd function which will only moves values up and down the list. What would I need to change in the function above to make it only move like variables up and down within the list? Any help/advice appreciated. I'm trying to keep it simple with only loops and Booleans with few built in functions as tedious as it sounds.

Upvotes: 0

Views: 89

Answers (2)

Sweeney Todd
Sweeney Todd

Reputation: 880

You can simply use -1 & +1 instead of Left and Right.
To move all 'A's in a single run:
If the direction is +1 (to right), iterate over the inner list from right to left, try to move every 'A' as you encounter, until the end of that row.
If the direction is -1 (to left), iterate from left to right instead.

area1 = [['.', '.', '.', 'e'], 
         ['A', 'A', '.', 'e'], 
         ['.', 'X', '.', 'e'], 
         ['.', 'X', 'Y', 'Y'], 
         ['.', '.', 'Z', 'Z']]

def move_horizontal(table, value, direction):
    is_anything_moved = False
    for row in table:
        width = len(row)
        # Traverse the row (skipping the first element) from right to left if direction is 1. 
        for x in (range(1,width,1) if direction==-1 else range(width-2,-1,-1)): 
            if row[x]==value: #found a value match, now move it as far as we can
                i = x+direction # new index of value
                while i<width and i>=0 and row[i]=='.':
                    row[i-direction] = '.'
                    row[i] = value
                    i += direction
                    is_anything_moved = True
    return is_anything_moved

[print(row) for row in area1]
print()

move_horizontal(area1,'A',1)

[print(row) for row in area1]
print()

move_horizontal(area1,'e',-1)

[print(row) for row in area1]

This should output :

['.', '.', '.', 'e']
['A', 'A', '.', 'e']
['.', 'X', '.', 'e']
['.', 'X', 'Y', 'Y']
['.', '.', 'Z', 'Z']

['.', '.', '.', 'e']
['.', 'A', 'A', 'e']
['.', 'X', '.', 'e']
['.', 'X', 'Y', 'Y']
['.', '.', 'Z', 'Z']

['e', '.', '.', '.']
['.', 'A', 'A', 'e']
['.', 'X', 'e', '.']
['.', 'X', 'Y', 'Y']
['.', '.', 'Z', 'Z']

Upvotes: 0

Patrick Haugh
Patrick Haugh

Reputation: 61032

def shift_horizontal(value, direction, area):#direction True is left
    result = []
    for lane in area:
        if not direction:
            lane = reversed(lane)
        try:
            ind = lane.index(value)
            result.append( '.' in lane[:index])
        except ValueError:
            result.append(False)
    return result

Returns a list of booleans. Flip the list, depending on direction. Then find the leftmost index of value. Then check the list up to that point for '.'. Not sure if this is exactly what you want. If you want to see if there is an adjacent '.' then do if lane[index-1] == '.' instead

Upvotes: 1

Related Questions