< algorithm > snake matrix solution

Serpentine matrix

Solutions:

  • In the process of single step forward, only one of x and y can change
  • Every time you turn, x and y switch
  • After switching, both X and y are in the opposite direction of the last time (step 1: x increases, X switches to y after reaching the limit; step 2: y starts to increase, y switches to X after reaching the limit; step 3: X decreases (opposite to the last time), switches to y after reaching the limit; step 4: y decreases (opposite to the last time), switches to X after reaching the limit; so on and so on)
  • The implementation idea is to set a x,y switching variable, which has only two states of 0 and 1. When one of them reaches the limit, they switch to the other. X and y should also set a variable respectively, which is responsible for recording whether the last limit value of X and Y reached the maximum or minimum value!

The optimization idea to determine the limit value:

If the current limit value of x and y is calculated in each cycle, the performance will be very expensive. Let x and y directly cross the boundary. When the point beyond the boundary does not exist, go back one step, and determine the "correct direction of turning (left or right) according to the last limit value (maximum or minimum) of" opposite party "

import time
import sys
"""
# x change or y change
x and y There can only be one job(0 by x work, 1 by y work, Initially 1)
x_y_work = 1

//Set the state add or cut:
//First control x: 0 is increase, 1 is decrease
//Second control y: 0 is increase, 1 is decrease
//Initial: [0, 0]
"""
# Try to remove the coordinates. If it succeeds, it will return 0. If it fails, it will return 1
def remove_atom(x_y_list, snake_node, result_list):
    # time.sleep(1)
    if snake_node in x_y_list:
        x_y_list.remove(snake_node)
        result_list.append(snake_node)
        print(snake_node)
        print("Remaining elements",len(x_y_list),"individual!")
        return 0
    else:
        return 1

# Convert 2D list to actual number position
def l_to_num(N, result_list):

    for n in range(len(result_list)):
        result_list[n] = result_list[n][0] * N + result_list[n][1] + 1
    return result_list

def main():
    # Determine side length
    N = input("Please enter the side length:")

    try:
        N = int(N)
    except Exception as e:
        print("Entered must be an integer,Please re-enter!")
        sys.exit()

    # Decide x or y work
    x_y_work = 1

    # Decide whether x or y is plus or minus, 0 is plus, 1 is minus

    add_or_cut = [0, 0]

    # Current location
    source_x = 0
    source_y = 0
    x_y_list = [[x,y] for x in range(N) for y in range(N)]
    result_list = list()

    print("The original map is:")
    for m in range(N):
        for n in range(N):
            print(x_y_list[m+n],end=",")
        print("")

    # Start moving

    while len(x_y_list) != 0:
        print("Start a cycle")

        # Operate on y
        if x_y_work == 1:
            # Get current coordinates
            snake_node = [source_x, source_y]
            # Attempt to remove coordinates
            sign = remove_atom(x_y_list, snake_node, result_list)
            # Normal deletion
            if sign == 0:
                if add_or_cut[1] == 0:
                    source_y += 1
                elif add_or_cut[1] == 1:
                    source_y -= 1
                else:
                    pass

                pass
            # Delete failed, reverse, turn, take one step (but do not delete), and switch to x
            elif sign == 1:
                # Reversing
                if add_or_cut[1] == 0:
                    source_y -= 1
                elif add_or_cut[1] == 1:
                    source_y += 1

                # Judge the current state of x and determine the steering direction
                # If x is zero, the next step is to increase
                if add_or_cut[0] == 0:
                    source_x += 1
                elif add_or_cut[0] == 1:
                    source_x -= 1
                else:
                    print("According to reason,It's not supposed to be here")

                # Handle your own affairs (determine the direction of the next step's addition or subtraction)
                if add_or_cut[1] == 0:
                    add_or_cut[1] = 1
                elif add_or_cut[1] == 1:
                    add_or_cut[1] = 0

                print("The point before switching the engine is:", [source_x, source_y])

                # Official switch engine

                x_y_work = 0

            else:
                print("According to reason,It's not supposed to be here")
                pass

        # Then operate on x
        elif x_y_work == 0:
            # Get current coordinates
            snake_node = [source_x, source_y]
            # Attempt to remove coordinates
            sign = remove_atom(x_y_list, snake_node, result_list)

            # Normal deletion
            if sign == 0:
                if add_or_cut[0] == 0:
                    source_x += 1
                elif add_or_cut[0] == 1:
                    source_x -= 1
                else:
                    pass

                pass
            # Delete failed, reverse, turn, take one step (but do not delete), and switch to x
            elif sign == 1:
                # Reversing
                if add_or_cut[0] == 0:
                    source_x -= 1
                elif add_or_cut[0] == 1:
                    source_x += 1

                # Judge the current state of y and determine the steering direction
                # If y points to zero, the next step is to increase
                if add_or_cut[1] == 0:
                    source_y += 1
                elif add_or_cut[1] == 1:
                    source_y -= 1
                else:
                    print("Penalty zone")
                    pass
                # Handle your own affairs (determine the direction of the next step's addition or subtraction)
                if add_or_cut[0] == 0:
                    add_or_cut[0] = 1
                elif add_or_cut[0] == 1:
                    add_or_cut[0] = 0

                # Official switch engine
                x_y_work = 1


            else:
                print("According to reason,It's not supposed to be here")
                pass


    result_list = l_to_num(N, result_list)
    print("In 2D coordinate system,The path is:")
    print(result_list)

    print("The coordinate of the actual passing position is:")
    for m in range(N):
        for n in range(N):
            print(result_list[m*N+n],end=",")
        print("")

if __name__ == '__main__':
    main()
raw data
Operation results

Posted by Asnom on Thu, 30 Apr 2020 13:11:02 -0700