pythonpython-3.xalgorithmdata-structuressliding-tile-puzzle

Why are both of the arrays being modified when I copy one array into another?


I am trying to solve 8puzzle problem and for that, I need neighboring elements of the current state.

Current state(or data) looks like this - a 2D array with 0 representing blank state.

1 0 2
3 4 5
6 7 8

I have created a function that takes 5 arguments - x and y position of zero(a,b)

x and y position of the index of the element that is to be swapped(c,d)

data, i.e. the array which is the current state of the board

This function swaps the blank position with an appropriate element in the array and then saves the current board in the list result_state. It then swaps the two values again back to their original position so that more new states can be calculated later on. This is what it looks like -

def append_in_list(self,a,b,c,d,data=None):

        #print(data)
        #print(store_values)
        result_state = []
        tmp = data[a][b]
        data[a][b] = data[c][d]
        data[c][d] = tmp


        for i in range(0,len(data)):
            result_state.append(data[i])

        print(result_state)

        tmp = data[c][d]
        data[c][d] = data[a][b]
        data[a][b] = tmp
        #print(data)
        print(result_state)
        return result_state

The output of this is when just ran for once is-

[[1, 4, 2], [3, 0, 5], [6, 7, 8]]
[[1, 0, 2], [3, 4, 5], [6, 7, 8]]

Why do the result_state changes when there is no modification in it?

Expected output -

[[1, 4, 2], [3, 0, 5], [6, 7, 8]]
[[1, 4, 2], [3, 0, 5], [6, 7, 8]]

Can someone please point out the mistake that I am committing?

Also, I need to save the output of this function in a list which will contain multiple elements, each element being an output of this function. How should I do that?

Thank you in advance for your help.


Solution

  • Use:

    # Creates a new list (copy of data[i]).
    # This operation is O(len(data[i])).
    result_state.append(data[i][:]) 
    

    Instead of:

    # Does not create a new list (does not copy data[i]).
    # Both result_state[i] and data[i] points to the same list.
    # Hence, any modification will be visible in both of them.
    # This operation is O(1).
    result_state.append(data[i]) 
    

    Also, I need to save the output of this function in a list which will contain multiple elements, each element being an output of this function. How should I do that?

    outputs = []
    outputs.append(append_in_list(0, 1, 1, 1, data))