On an infinite plane, a robot initially stands at (0, 0) and faces north. Note that:


	The north direction is the positive direction of the y-axis.
	The south direction is the negative direction of the y-axis.
	The east direction is the positive direction of the x-axis.
	The west direction is the negative direction of the x-axis.


The robot can receive one of three instructions:


	"G": go straight 1 unit.
	"L": turn 90 degrees to the left (i.e., anti-clockwise direction).
	"R": turn 90 degrees to the right (i.e., clockwise direction).


The robot performs the instructions given in order, and repeats them forever.

Return true if and only if there exists a circle in the plane such that the robot never leaves the circle.

&nbsp;
Example 1:

Input: instructions = "GGLLGG"
Output: true
Explanation: The robot is initially at (0, 0) facing the north direction.
"G": move one step. Position: (0, 1). Direction: North.
"G": move one step. Position: (0, 2). Direction: North.
"L": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: West.
"L": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: South.
"G": move one step. Position: (0, 1). Direction: South.
"G": move one step. Position: (0, 0). Direction: South.
Repeating the instructions, the robot goes into the cycle: (0, 0) --&gt; (0, 1) --&gt; (0, 2) --&gt; (0, 1) --&gt; (0, 0).
Based on that, we return true.


Example 2:

Input: instructions = "GG"
Output: false
Explanation: The robot is initially at (0, 0) facing the north direction.
"G": move one step. Position: (0, 1). Direction: North.
"G": move one step. Position: (0, 2). Direction: North.
Repeating the instructions, keeps advancing in the north direction and does not go into cycles.
Based on that, we return false.


Example 3:

Input: instructions = "GL"
Output: true
Explanation: The robot is initially at (0, 0) facing the north direction.
"G": move one step. Position: (0, 1). Direction: North.
"L": turn 90 degrees anti-clockwise. Position: (0, 1). Direction: West.
"G": move one step. Position: (-1, 1). Direction: West.
"L": turn 90 degrees anti-clockwise. Position: (-1, 1). Direction: South.
"G": move one step. Position: (-1, 0). Direction: South.
"L": turn 90 degrees anti-clockwise. Position: (-1, 0). Direction: East.
"G": move one step. Position: (0, 0). Direction: East.
"L": turn 90 degrees anti-clockwise. Position: (0, 0). Direction: North.
Repeating the instructions, the robot goes into the cycle: (0, 0) --&gt; (0, 1) --&gt; (-1, 1) --&gt; (-1, 0) --&gt; (0, 0).
Based on that, we return true.


&nbsp;
Constraints:


	1 &lt;= instructions.length &lt;= 100
	instructions[i] is 'G', 'L' or, 'R'.


class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
        pos, d = [0,0], "N"
        def move(d, pos, instructions):
            for i in instructions:
                if i == "G":
                    if d == "N": pos[1] += 1
                    elif d == "S": pos[1] -= 1
                    elif d == "W": pos[0] -= 1
                    else: pos[0] += 1
                elif i == "L":
                    if d == "N": d = "W"
                    elif d == "W": d = "S"
                    elif d == "S": d = "E"
                    else: d = "N"
                else:
                    if d == "N": d = "E"
                    elif d == "W": d = "N"
                    elif d == "S": d = "W"
                    else: d = "S"
            return (d, pos)
        for i in range(4):
            d, pos = (move(d, pos, instructions))
        return True if pos == [0,0] else False
class Solution {
    public boolean isRobotBounded(String instructions) {
        if (instructions.length() == 0) {
            return true;
        }

        Robot bender = new Robot();
        int[] start = new int[]{0, 0};

        // 4 represents the max 90 degree turns that can restart initial orientation.
        for (int i = 0; i < 4; i++) {
            boolean orientationChanged = bender.performSet(instructions);

            int[] location = bender.location;
            if (location[0] == start[0] && location[1] == start[1]) {
                return true;
            }

            // If robot never turns and the first instruction isn't at start, exit.
            else if (!orientationChanged) {
                return false;
            }
        }

        return false;
    }
}

class Robot {
    int[] location;
    int[] orientation;
    int[][] orientations;
    int orientationPos;
    boolean orientationChangeCheck;

    Robot() {
        // Start in center
        location = new int[]{0, 0};

        // N, E, S, W
        orientations = new int[][]{{1,0}, {0, 1}, {-1, 0}, {0, -1}};

        // Start pointing north
        orientationPos = 0;
        orientation = orientations[orientationPos];

        // Track if robot has turned
        orientationChangeCheck = false;
    }

    public boolean performSet(String orders) {
        this.orientationChangeCheck = false;

        for (int i = 0; i < orders.length(); i++) {
            this.perform(orders.charAt(i));
        }

        return this.orientationChangeCheck;
    }

    public void perform(char order) {
        if (order == 'G') {
            this.go();
        } else if (order == 'L' || order == 'R') {
            this.turn(order);
        } else {
           // do nothing
        }
    }

    public void turn(char direction) {
        if (direction == 'L') {
            this.orientationPos = this.orientationPos == 0 ? 3 : this.orientationPos - 1;
        } else if (direction == 'R') {
            this.orientationPos = (this.orientationPos + 1) % 4;
        }

        this.orientation = this.orientations[this.orientationPos];
        this.orientationChangeCheck = true;
    }

    public int[] go() {
        this.location[0] += this.orientation[0];
        this.location[1] += this.orientation[1];
        return this.location;
    }
}
class Solution {
public:
    bool isRobotBounded(string instructions) {
        char direction = 'N';
        int x = 0, y = 0;
        for (char &instruction: instructions) {
            if (instruction == 'G') {
                if (direction == 'N') y++;
                else if (direction == 'S') y--;
                else if (direction == 'W') x--;
                else x++;
            } else if (instruction == 'L') {
                if (direction == 'N') direction = 'W';
                else if (direction == 'S') direction = 'E';
                else if (direction == 'W') direction = 'S';
                else direction = 'N';
            } else {
                if (direction == 'N') direction = 'E';
                else if (direction == 'S') direction = 'W';
                else if (direction == 'W') direction = 'N';
                else direction = 'S';
            }
        }
        return (x == 0 && y == 0) || direction != 'N';
    }
};
var isRobotBounded = function(instructions) {
        // north = 0, east = 1, south = 2, west = 3
        let directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
        // Initial position is in the center
        let x = 0, y = 0;
        // facing north
        let idx = 0;
        let movements = [...instructions];

        for (let move of movements) {
            if (move == 'L')
                idx = (idx + 3) % 4;
            else if (move == 'R')
                idx = (idx + 1) % 4;
            else {
                x += directions[idx][0];
                y += directions[idx][1];
            }
        }

        // after one cycle:
        // robot returns into initial position
        // or robot doesn't face north
        return (x == 0 && y == 0) || (idx != 0);
};
Robot Bounded In Circle