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'}

Source: leetcode | Difficulty: MEDIUM_HARD
Tags: String algorithms

Mathematics

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
		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:

		def is_infinite_loop(command):
			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 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:
		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