On an infinite plane, a robot initially stands at (0, 0) and faces north.  The robot can receive one of three instructions:

"G": go straight 1 unit;
"L": turn 90 degrees to the left;
"R": turn 90 degress to the right.

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.
 
Example 1:
Input: "GGLLGG"
Output: true
Explanation: 
The robot moves from (0,0) to (0,2), turns 180 degrees, and then returns to (0,0).
When repeating these instructions, the robot remains in the circle of radius 2 centered at the origin.

Example 2:
Input: "GG"
Output: false
Explanation: 
The robot moves north indefinitely.

Example 3:
Input: "GL"
Output: true
Explanation: 
The robot moves from (0, 0) -> (0, 1) -> (-1, 1) -> (-1, 0) -> (0, 0) -> ...

 
Note:

1 <= instructions.length <= 100
instructions[i] is in {'G', 'L', 'R'}

Difficulty: interview

Starter code:

class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
        

Solutions:
class Solution:
    def move(self, pos, direction):
        x, y = pos
        if direction == 0:
            y += 1
        elif direction == 1:
            x += 1
        elif direction == 2:
            y -= 1
        elif direction == 3:
            x -= 1
        return (x, y)
    
    def isRobotBounded(self, instructions: str) -> bool:
        direction = 0 # 0 for north, 1 for east, 2 for south, 3 for west
        pos = (0, 0)
        for i in instructions:
            if i == 'G':
                pos = self.move(pos, direction)
            elif i == 'L':
                direction = (direction - 1) % 4
            elif i == 'R':
                direction = (direction + 1) % 4
        if pos == (0, 0) or direction != 0:
            return True
        else:
            return False


class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
        
        
        mapping = {0: [1, 0], 1: [0, 1], 2: [-1, 0], 3: [0, -1]}
        
        direction = 0
        current = [0, 0]
        
        for instr in instructions:
            if instr == 'L':
                direction -= 1
            elif instr == 'R':
                direction += 1
            elif instr == 'G':
                move = mapping[direction]
                
                current[0] += move[0]
                current[1] += move[1]
                
            direction %= 4
            
        if current == [0, 0] or direction != 0:
            return True
        return False
            


class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
        x, y, dx, dy = 0, 0, 0, 1
        for i in instructions:
            if i == 'R': dx, dy = dy, -dx
            if i == 'L': dx, dy = -dy, dx
            if i == 'G': x, y = x + dx, y + dy
        return (x, y) == (0, 0) or (dx, dy) != (0,1)


class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
      # loop through all the commands in the arr
      # scenario the direction is not facing the same

        def is_infinite_loop(command):
            # iterate over all the commands 
            # direction 0: NameError
            # x and y coordinates, if x and 0 is (0, 0) return True
            direction = [(0, 1), (1, 0), (0, -1), (-1, 0)]
            d_index = 0
            x, y = 0, 0
            for move in command:
                if move == 'G':
                    x += direction[d_index][0]
                    y += direction[d_index][1]
                elif move == 'R':
                    d_index = (d_index + 1) % 4
                elif move == 'L':
                    d_index = (d_index + 3) % 4
            # if back at origin
            # print(d_index)
            if x == y == 0:
                return True
            if (x != 0 or y != 0) and d_index != 0:
                return True
            return False

        return is_infinite_loop(instructions)

# class Solution:
#     def isRobotBounded(self, instructions: str) -> bool:
#         L_occurances = instructions.count('L')
#         R_occurances = instructions.count('R')
#         difference = L_occurances - R_occurances
        
#         if difference % 4 == 0:
#             # check if loop otherwise return False too
#             directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # N, E, S, W
#             d = 0                                           # start at North index
#             point = [0, 0]
#             for instruction in instructions:
#                 if instruction == 'G':
#                     point[0] += directions[d][0]
#                     point[1] += directions[d][1]
#                 elif instruction == 'L':
#                     d = (d + 3) % 4
#                 elif instruction == 'R':
#                     d = (d + 1) % 4
#             return True if point == [0, 0] else False
#         else:
#             return True
        
        
#         # return True if L_occurances - R_occurances != 0 else False


class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
        move = {'N':(0,1), 'S':(0,-1), 'E':(1,0), 'W':(-1,0)}
        right = {'N':'E', 'S':'W', 'E':'S', 'W':'N'}
        left = {'N':'W', 'S':'E', 'E':'N', 'W':'S'}
        
        pos = (0,0)
        dire = 'N'
        
        for c in instructions:
            if c=='G':
                x, y = pos
                dx, dy = move[dire]
                pos = (x+dx, y+dy)
            elif c=='L':
                dire = left[dire]
            else:
                dire = right[dire]

        return pos==(0,0) or dire!='N'


class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
        move = {'N':(0,1), 'S':(0,-1), 'E':(1,0), 'W':(-1,0)}
        right = {'N':'E', 'S':'W', 'E':'S', 'W':'N'}
        left = {'N':'W', 'S':'E', 'E':'N', 'W':'S'}
        
        pos = (0,0)
        dire = 'N'
        i=0
        while i<4:
            for c in instructions:
                if c=='G':
                    x, y = pos
                    dx, dy = move[dire]
                    pos = (x+dx, y+dy)
                elif c=='L':
                    dire = left[dire]
                else:
                    dire = right[dire]
            
            if pos==(0,0) and dire=='N':
                return True
        
            i+=1
        
        return False