A robot on an infinite grid starts at point (0, 0) and faces north.  The robot can receive one of three possible types of commands:

-2: turn left 90 degrees
-1: turn right 90 degrees
1 <= x <= 9: move forward x units

Some of the grid squares are obstacles. 
The i-th obstacle is at grid point (obstacles[i][0], obstacles[i][1])
If the robot would try to move onto them, the robot stays on the previous grid square instead (but still continues following the rest of the route.)
Return the square of the maximum Euclidean distance that the robot will be from the origin.
 
Example 1:
Input: commands = [4,-1,3], obstacles = []
Output: 25
Explanation: robot will go to (3, 4)


Example 2:
Input: commands = [4,-1,4,-2,4], obstacles = [[2,4]]
Output: 65
Explanation: robot will be stuck at (1, 4) before turning left and going to (1, 8)


 
Note:

0 <= commands.length <= 10000
0 <= obstacles.length <= 10000
-30000 <= obstacle[i][0] <= 30000
-30000 <= obstacle[i][1] <= 30000
The answer is guaranteed to be less than 2 ^ 31.

Source: leetcode | Difficulty: EASY
Tags: Data structures

Starter code: class Solution:
    def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
        

Solutions:
class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		obstacles = set([tuple(x) for x in obstacles])
		face = 0
		(x, y) = (0, 0)
		max_dist = 0
		for command in commands:
			if command == -2:
				face = (face - 1) % 4
			elif command == -1:
				face = (face + 1) % 4
			else:
				if face == 0:
					for i in range(1, command + 1):
						if (x, y + i) in obstacles:
							i -= 1
							break
					y += i
				elif face == 1:
					for i in range(1, command + 1):
						if (x + i, y) in obstacles:
							i -= 1
							break
					x += i
				elif face == 2:
					for i in range(1, command + 1):
						if (x, y - i) in obstacles:
							i -= 1
							break
					y -= i
				else:
					for i in range(1, command + 1):
						if (x - i, y) in obstacles:
							i -= 1
							break
					x -= i
				max_dist = max(max_dist, x ** 2 + y ** 2)
		return max_dist


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		pos = [0, 0]
		deg_x = 0
		deg_y = 1
		obstacles = set(map(tuple, obstacles))
		ans = 0
		for walk in commands:
			if walk == -2:
				(deg_x, deg_y) = (-deg_y, deg_x)
			elif walk == -1:
				(deg_x, deg_y) = (deg_y, -deg_x)
			else:
				while walk > 0:
					pos[0] += deg_x
					pos[1] += deg_y
					walk -= 1
					if (pos[0], pos[1]) in obstacles:
						pos[0] -= deg_x
						pos[1] -= deg_y
						break
				ans = max(ans, pos[0] ** 2 + pos[1] ** 2)
		return ans


class Solution(object):

	def robotSim(self, commands, obstacles):
		dx = [0, 1, 0, -1]
		dy = [1, 0, -1, 0]
		x = y = di = 0
		obstacleSet = set(map(tuple, obstacles))
		ans = 0
		for cmd in commands:
			if cmd == -2:
				di = (di - 1) % 4
			elif cmd == -1:
				di = (di + 1) % 4
			else:
				for k in range(cmd):
					if (x + dx[di], y + dy[di]) not in obstacleSet:
						x += dx[di]
						y += dy[di]
						ans = max(ans, x * x + y * y)
		return ans


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		dx = [0, 1, 0, -1]
		dy = [1, 0, -1, 0]
		x = y = di = 0
		o_set = set(map(tuple, obstacles))
		max_dis = 0
		for cmd in commands:
			if cmd == -2:
				di = (di - 1) % 4
			elif cmd == -1:
				di = (di + 1) % 4
			else:
				for _ in range(cmd):
					if (x + dx[di], y + dy[di]) not in o_set:
						x += dx[di]
						y += dy[di]
						max_dis = max(max_dis, x * x + y * y)
		return max_dis


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		dx = [0, 1, 0, -1]
		dy = [1, 0, -1, 0]
		d = 0
		(x, y) = (0, 0)
		oset = set()
		for o in obstacles:
			oset.add(tuple(o))
		result = 0
		for c in commands:
			if c == -1:
				d = (d + 1) % 4
			elif c == -2:
				d = (d + 4 - 1) % 4
			else:
				for k in range(c):
					if (x + dx[d], y + dy[d]) not in oset:
						x += dx[d]
						y += dy[d]
						result = max(result, x * x + y * y)
		return result


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		cur = [0, 0]
		directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
		cur_direction = 0
		max_distance = -1
		obstacles = {tuple(i) for i in obstacles}
		for c in commands:
			if c > 0:
				while c > 0:
					(cx, cy) = cur
					next_pos = [cx + directions[cur_direction][0], cy + directions[cur_direction][1]]
					if (cx + directions[cur_direction][0], cy + directions[cur_direction][1]) in obstacles:
						break
					cur = next_pos
					c -= 1
			elif c == -1:
				cur_direction += 1
				if cur_direction > 3:
					cur_direction = 0
			elif c == -2:
				cur_direction -= 1
				if cur_direction < 0:
					cur_direction = 3
			max_distance = max(max_distance, cur[0] * cur[0] + cur[1] * cur[1])
		return max_distance


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		maxD2 = 0
		pos = [0, 0]
		ori = [[0, 1], [1, 0], [0, -1], [-1, 0]]
		pOri = 0
		obsSet = set()
		for i in obstacles:
			obsSet.add(tuple(i))
		for i in commands:
			if i == -1:
				pOri += 1
				pOri %= 4
			elif i == -2:
				pOri -= 1
				pOri %= 4
			else:
				n = 1
				while n <= i:
					tempx = pos[0] + ori[pOri][0]
					tempy = pos[1] + ori[pOri][1]
					if (tempx, tempy) not in obsSet:
						pos[0] = tempx
						pos[1] = tempy
						n += 1
					else:
						break
				maxD2 = max(maxD2, pos[0] ** 2 + pos[1] ** 2)
		return maxD2


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]
		d = 0
		x = 0
		y = 0
		obs = set([tuple(x) for x in obstacles])
		res = 0
		for c in commands:
			if c == -1:
				d = (d + 1) % 4
			elif c == -2:
				d = (d - 1 + 4) % 4
			else:
				(dx, dy) = dirs[d]
				for i in range(c):
					if (x + dx, y + dy) not in obs:
						x += dx
						y += dy
						res = max(res, x * x + y * y)
		return res


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		i = j = mx = d = 0
		(move, obstacles) = ([(0, 1), (-1, 0), (0, -1), (1, 0)], set(map(tuple, obstacles)))
		for command in commands:
			if command == -2:
				d = (d + 1) % 4
			elif command == -1:
				d = (d - 1) % 4
			else:
				(x, y) = move[d]
				while command and (i + x, j + y) not in obstacles:
					i += x
					j += y
					command -= 1
					mx = max(mx, i ** 2 + j ** 2)
		return mx


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		(x, y) = (0, 0)
		d = 1
		result = 0
		dxy = [[1, 0], [0, 1], [-1, 0], [0, -1]]
		obstacles = set(map(tuple, obstacles))
		for c in commands:
			if c == -2:
				d = (d + 1) % 4
			elif c == -1:
				d = (d - 1) % 4
			else:
				for i in range(c):
					if (x + dxy[d][0], y + dxy[d][1]) in obstacles:
						break
					x += dxy[d][0]
					y += dxy[d][1]
					result = max(result, x ** 2 + y ** 2)
		return result


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		gldis = 0
		pos = [0, 0]
		dr = 0
		obs = {tuple(i) for i in obstacles}

		def nex(dr):
			if dr == 0:
				return [pos[0], pos[1] + 1]
			if dr == 1:
				return [pos[0] + 1, pos[1]]
			if dr == 2:
				return [pos[0], pos[1] - 1]
			if dr == 3:
				return [pos[0] - 1, pos[1]]
		for i in commands:
			if i == -1:
				ne = dr + 1
				dr = ne % 4
			if i == -2:
				ne = dr - 1
				dr = ne % 4
			else:
				j = 0
				while j < i and tuple(nex(dr)) not in obs:
					pos = nex(dr)
					j += 1
				gldis = max(gldis, pos[0] * pos[0] + pos[1] * pos[1])
		return gldis


class Solution:

	def __init__(self):
		self.x = 0
		self.y = 0
		self.direction = (0, 1)
		self.obstacleSet = set()

	def _turnLeft(self):
		newXDirection = -self.direction[1]
		newYDirection = self.direction[0]
		self.direction = (newXDirection, newYDirection)

	def _turnRight(self):
		newXDirection = self.direction[1]
		newYDirection = -self.direction[0]
		self.direction = (newXDirection, newYDirection)

	def _tryMoveForward(self, numUnits):
		canMoveNumUnits = 0
		xMove = self.direction[0]
		yMove = self.direction[1]
		for i in range(1, numUnits + 1):
			newX = self.x + xMove * i
			newY = self.y + yMove * i
			if (newX, newY) not in self.obstacleSet:
				canMoveNumUnits = i
			else:
				break
		return canMoveNumUnits

	def _move(self, numUnits):
		self.x += self.direction[0] * numUnits
		self.y += self.direction[1] * numUnits

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		maxDistance = 0
		for obstacle in obstacles:
			self.obstacleSet.add(tuple(obstacle))
		for command in commands:
			if command == -2:
				self._turnLeft()
			elif command == -1:
				self._turnRight()
			else:
				canMoveNumUnits = self._tryMoveForward(command)
				self._move(canMoveNumUnits)
				maxDistance = max(maxDistance, self.x ** 2 + self.y ** 2)
		return maxDistance


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		if not commands:
			return 0
		(x, y, res) = (0, 0, 0)
		directions = {0: 1, 1: 1, 2: -1, 3: -1}
		cur_dir = 1
		obs = set(map(tuple, obstacles))
		for cmd in commands:
			if cmd == -2:
				cur_dir = (cur_dir + 1) % 4
			elif cmd == -1:
				cur_dir = (cur_dir + 3) % 4
			else:
				t = directions[cur_dir]
				(x_move, y_move) = (t, 0) if cur_dir in (0, 2) else (0, t)
				for _ in range(cmd):
					if (x + x_move, y + y_move) not in obs:
						x += x_move
						y += y_move
						res = max(res, x ** 2 + y ** 2)
					else:
						break
		return res


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		obs = set((tuple(t) for t in obstacles))
		turns = {}
		turns['N', -1] = 'E'
		turns['E', -1] = 'S'
		turns['S', -1] = 'W'
		turns['W', -1] = 'N'
		turns['N', -2] = 'W'
		turns['W', -2] = 'S'
		turns['S', -2] = 'E'
		turns['E', -2] = 'N'
		shifts = {}
		shifts['N'] = (0, 1)
		shifts['S'] = (0, -1)
		shifts['E'] = (1, 0)
		shifts['W'] = (-1, 0)
		cur = [0, 0]
		curD = 'N'
		res = 0
		for command in commands:
			if command < 0:
				curD = turns[curD, command]
			else:
				shift = shifts[curD]
				for i in range(command):
					tmp = [cur[0] + shift[0], cur[1] + shift[1]]
					if tuple(tmp) in obs:
						break
					cur = tmp
					res = max(res, cur[0] * cur[0] + cur[1] * cur[1])
			print(cur)
		return res


class Solution:

	def robotSim(self, c: List[int], b: List[List[int]]) -> int:
		(x, y, d, b, M) = (0, 0, 0, set([tuple(i) for i in b]), 0)
		for i in c:
			if i < 0:
				d = (d + 2 * i + 3) % 4
			elif d in [1, 3]:
				for x in range(x, x + (i + 1) * (2 - d), 2 - d):
					if (x + (2 - d), y) in b:
						break
			else:
				for y in range(y, y + (i + 1) * (1 - d), 1 - d):
					if (x, y + (1 - d)) in b:
						break
			M = max(M, x ** 2 + y ** 2)
		return M


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		arrow = [(-1, 0), (0, 1), (1, 0), (0, -1)]
		arrowNow = 1
		curPoint = [0, 0]
		obstacles = [tuple(e) for e in obstacles]
		setObs = set(obstacles)
		ans = 0
		for e in commands:
			if e == -1:
				arrowNow = (arrowNow + 1) % 4
			elif e == -2:
				arrowNow = (arrowNow - 1) % 4
			else:
				for i in range(e):
					rowNow = curPoint[0] + arrow[arrowNow][0]
					colomNow = curPoint[1] + arrow[arrowNow][1]
					if (rowNow, colomNow) not in setObs:
						ans = max(ans, rowNow ** 2 + colomNow ** 2)
						(curPoint[0], curPoint[1]) = (rowNow, colomNow)
		return ans


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		move_pos = [[1, 0], [0, 1], [-1, 0], [0, -1]]
		now_pos = move_pos[0]
		idx_now_pos = 0
		obstacles = set(map(tuple, obstacles))
		row_now = 0
		col_now = 0
		answer = 0
		for command in commands:
			if command > 0:
				for _ in range(command):
					row_tmp = row_now + now_pos[0]
					col_tmp = col_now + now_pos[1]
					if (col_tmp, row_tmp) not in obstacles:
						row_now += now_pos[0]
						col_now += now_pos[1]
						answer = max(answer, row_now ** 2 + col_now ** 2)
			else:
				if command == -1:
					idx_now_pos += 1
					if idx_now_pos > 3:
						idx_now_pos = 0
				elif command == -2:
					idx_now_pos -= 1
					if idx_now_pos < 0:
						idx_now_pos = 3
				now_pos = move_pos[idx_now_pos]
		return answer


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		dx = [0, 1, 0, -1]
		dy = [1, 0, -1, 0]
		obs = set(map(tuple, obstacles))
		(x, y, direction, result) = (0, 0, 0, 0)
		for cmd in commands:
			if cmd == -1:
				direction = (direction + 1) % 4
			elif cmd == -2:
				direction = (direction - 1) % 4
			else:
				for _ in range(cmd):
					(nx, ny) = (x + dx[direction], y + dy[direction])
					if (nx, ny) in obs:
						break
					(x, y) = (nx, ny)
			result = max(result, x ** 2 + y ** 2)
		return result


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		direction = (0, 1)
		start = [0, 0]
		obstacleSet = set(map(tuple, obstacles))
		ans = 0
		for cmd in commands:
			if cmd == -2:
				direction = (-direction[1], direction[0])
			elif cmd == -1:
				direction = (direction[1], -direction[0])
			else:
				for g in range(cmd):
					if (start[0] + direction[0], start[1] + direction[1]) not in obstacleSet:
						start[1] += direction[1]
						start[0] += direction[0]
						ans = max(ans, start[0] ** 2 + start[1] ** 2)
		return ans


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		obSet = set(map(tuple, obstacles))
		print(obSet)
		result = 0
		X = 0
		Y = 0
		directions = [[0, 1], [-1, 0], [0, -1], [1, 0]]
		dirs = 0
		for i in commands:
			if i == -2:
				dirs = (dirs + 1) % 4
			elif i == -1:
				dirs = (dirs + 3) % 4
			else:
				for j in range(i):
					new_X = X + directions[dirs][0]
					new_Y = Y + directions[dirs][1]
					if (new_X, new_Y) in obSet:
						break
					X = new_X
					Y = new_Y
				result = max(result, X * X + Y * Y)
		return result


class Solution:
	directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
	dir_idx = 0
	curr_coords = (0, 0)

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		max_distance = 0
		obstacles = set((tuple(obstacle) for obstacle in obstacles))
		for command in commands:
			if command == -2:
				self.dir_idx = (self.dir_idx - 1) % 4
			if command == -1:
				self.dir_idx = (self.dir_idx + 1) % 4
			else:
				for i in range(command):
					(x_move, y_move) = self.directions[self.dir_idx]
					new_coords_x = self.curr_coords[0] + x_move
					new_coords_y = self.curr_coords[1] + y_move
					if (new_coords_x, new_coords_y) in obstacles:
						break
					self.curr_coords = (new_coords_x, new_coords_y)
					max_distance = max(max_distance, sum((coord ** 2 for coord in self.curr_coords)))
		return max_distance


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		obstacleSet = set()
		for p in obstacles:
			obstacleSet.add(tuple(p))
		dirs = [1, 1, -1, -1]
		axis = [0, 1]
		position = [0, 0]
		ax = 1
		up = 0
		result = 0
		for cmd in commands:
			if cmd > 0:
				nextstop = list(position)
				for c in range(cmd):
					nextstop[ax] = nextstop[ax] + dirs[up]
					if tuple(nextstop) in obstacleSet:
						break
					position = list(nextstop)
					result = max(result, position[0] ** 2 + position[1] ** 2)
			elif cmd == -2:
				ax = (ax + 1) % 2
				up = (up + 3) % 4
			elif cmd == -1:
				ax = (ax + 1) % 2
				up = (up + 1) % 4
		return result


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		x = y = d = ans = 0
		obs = set(map(tuple, obstacles))
		move = [[0, 1], [1, 0], [0, -1], [-1, 0]]
		for i in commands:
			if i == -2:
				d = (d - 1) % 4
			elif i == -1:
				d = (d + 1) % 4
			else:
				for j in range(i):
					if (x + move[d][0], y + move[d][1]) not in obs:
						x += move[d][0]
						y += move[d][1]
						ans = max(ans, x ** 2 + y ** 2)
		return ans


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		d = [(0, 1), (1, 0), (0, -1), (-1, 0)]
		di = 0
		cur = [0, 0]
		obs = set([tuple(x) for x in obstacles])
		maxx = 0
		for i in commands:
			if i == -2:
				di = di - 1 if di > 0 else 3
			elif i == -1:
				di = (di + 1) % 4
			else:
				for x in range(i):
					(xi, yi) = (cur[0] + d[di][0], cur[1] + d[di][1])
					if (xi, yi) in obs:
						break
					cur = (xi, yi)
					maxx = max(maxx, cur[0] ** 2 + cur[1] ** 2)
		return maxx


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		(x, y) = (0, 0)
		ob = set([tuple(i) for i in obstacles])
		dd = {0: [[-1, 0]], 1: [[0, 1]], 2: [[1, 0]], 3: [[0, -1]]}
		d = 1
		ans = 0
		for i in commands:
			if i < 0:
				d += 1 if i == -1 else -1
				d %= 4
			else:
				for (m, n) in dd[d]:
					while i and (x + m, y + n) not in ob:
						x += m
						y += n
						i -= 1
					ans = max(ans, x ** 2 + y ** 2)
		return ans


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		dx = [0, 1, 0, -1]
		dy = [1, 0, -1, 0]
		x = y = di = 0
		obstacleSet = set(map(tuple, obstacles))
		ans = 0
		for command in commands:
			if command == -2:
				di = (di - 1) % 4
			elif command == -1:
				di = (di + 1) % 4
			else:
				for _ in range(command):
					if (x + dx[di], y + dy[di]) not in obstacleSet:
						x += dx[di]
						y += dy[di]
					ans = max(ans, pow(x, 2) + pow(y, 2))
		return ans


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		x = y = 0
		max_dist = 0
		directions = ((0, 1), (1, 0), (0, -1), (-1, 0))
		obstacles = set((tuple(x) for x in obstacles))
		direction = 0
		for command in commands:
			if command == -1:
				direction += 1
				if direction == 4:
					direction = 0
			elif command == -2:
				direction -= 1
				if direction == -1:
					direction = 3
			else:
				(new_x, new_y) = directions[direction]
				while command > 0 and (x + new_x, y + new_y) not in obstacles:
					x += new_x
					y += new_y
					command -= 1
				max_dist = max(max_dist, x ** 2 + y ** 2)
		return max_dist


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		(x, y) = (0, 0)
		(dx, dy) = (0, 1)
		obs = {tuple(i) for i in obstacles}
		maxdist = 0
		for step in commands:
			if 0 < step < 10:
				for i in range(step):
					(x, y) = (x + dx, y + dy)
					if (x, y) in obs:
						(x, y) = (x - dx, y - dy)
						break
			elif step == -2:
				(dx, dy) = (-dy, dx)
			elif step == -1:
				(dx, dy) = (dy, -dx)
			maxdist = max(maxdist, x ** 2 + y ** 2)
		return maxdist


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		direct = [[0, 1], [1, 0], [0, -1], [-1, 0]]
		i = 0
		pos = [0, 0]
		obstacles = set((tuple(x) for x in obstacles))
		max_dis = 0
		for num in commands:
			if num >= 0:
				for j in range(num):
					pos[0] += direct[i][0]
					pos[1] += direct[i][1]
					if tuple(pos) in obstacles:
						pos[0] -= direct[i][0]
						pos[1] -= direct[i][1]
						break
			elif num == -1:
				i = (i + 1) % 4
			elif num == -2:
				i = i - 1
				if i < 0:
					i = 3
			max_dis = max(max_dis, pos[0] ** 2 + pos[1] ** 2)
		return max_dis


class Solution:
	coordinates = [[0, 1], [1, 0], [0, -1], [-1, 0]]

	def robotSim(self, cmd: List[int], ob: List[List[int]]) -> int:
		obstruction = set((tuple(x) for x in ob))
		curr = 0
		x = 0
		y = 0
		res = 0
		for c in cmd:
			if c == -2:
				curr -= 1
				if curr < 0:
					curr = 3
			elif c == -1:
				curr = (curr + 1) % 4
			else:
				while c > 0:
					(x, y) = (x + self.coordinates[curr][0], y + self.coordinates[curr][1])
					if (x, y) in obstruction:
						x = x - self.coordinates[curr][0]
						y = y - self.coordinates[curr][1]
						break
					c -= 1
			res = max(res, x * x + y * y)
		return res


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
		d_id = 0
		obs = set()
		for o in obstacles:
			obs.add(tuple(o))
		x = 0
		y = 0
		best = 0
		for i in range(len(commands)):
			if commands[i] == -1:
				d_id = (d_id + 1) % 4
			elif commands[i] == -2:
				d_id = (d_id - 1) % 4
			else:
				while commands[i] > 0:
					if (x + directions[d_id][0], y + directions[d_id][1]) not in obs:
						x += directions[d_id][0]
						y += directions[d_id][1]
						best = max(best, x ** 2 + y ** 2)
					else:
						break
					commands[i] -= 1
		return best


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		obs = set(map(tuple, obstacles))
		cur_pos = (0, 0)
		d = 0
		m = 0
		cur_steps = 0
		for (cmd_idx, cmd) in enumerate(commands):
			if cmd < 0:
				cur_pos = self.new_pos(obs, d, cur_steps, cur_pos)
				m = max(m, cur_pos[0] ** 2 + cur_pos[1] ** 2)
				cur_steps = 0
				if cmd == -2:
					d = (d - 1) % 4
				elif cmd == -1:
					d = (d + 1) % 4
			else:
				cur_steps += cmd
		cur_pos = self.new_pos(obs, d, cur_steps, cur_pos)
		m = max(m, cur_pos[0] ** 2 + cur_pos[1] ** 2)
		return m

	def new_pos(self, obs, d, cur_steps, cur_pos):
		if cur_steps == 0:
			return cur_pos
		if d == 0:
			idx = 1
			incr = 1
		elif d == 1:
			idx = 0
			incr = 1
		elif d == 2:
			idx = 1
			incr = -1
		elif d == 3:
			idx = 0
			incr = -1
		while cur_steps > 0:
			if idx == 0:
				next_pos = (cur_pos[0] + incr, cur_pos[1])
			else:
				next_pos = (cur_pos[0], cur_pos[1] + incr)
			if next_pos in obs:
				break
			cur_pos = next_pos
			cur_steps -= 1
		return cur_pos


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		pos = [0, 0]
		deg = 90
		ans = 0
		obstaclesSet = set(map(tuple, obstacles))
		for command in commands:
			if command == -1:
				deg = (deg + 270) % 360
			elif command == -2:
				deg = (deg + 90) % 360
			else:
				if deg == 0:
					i = 0
					while i < command and (not (pos[0] + 1, pos[1]) in obstaclesSet):
						pos[0] += 1
						i += 1
				if deg == 90:
					i = 0
					while i < command and (not (pos[0], pos[1] + 1) in obstaclesSet):
						pos[1] += 1
						i += 1
				if deg == 180:
					i = 0
					while i < command and (not (pos[0] - 1, pos[1]) in obstaclesSet):
						pos[0] -= 1
						i += 1
				if deg == 270:
					i = 0
					while i < command and (not (pos[0], pos[1] - 1) in obstaclesSet):
						pos[1] -= 1
						i += 1
				ans = max(ans, pos[0] ** 2 + pos[1] ** 2)
		return ans


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
		curr = [0, 0]
		ori = 0
		obstacles = {tuple(obs) for obs in obstacles}
		maxx = 0
		for cmd in commands:
			if cmd == -2:
				ori = (ori - 1) % 4
			elif cmd == -1:
				ori = (ori + 1) % 4
			else:
				for _ in range(cmd):
					nexxt = [curr[0] + directions[ori][0], curr[1] + directions[ori][1]]
					if tuple(nexxt) not in obstacles:
						curr = nexxt
						maxx = max(maxx, curr[0] ** 2 + curr[1] ** 2)
		return maxx


class Solution:

	def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
		x = y = 0
		dx = 0
		dy = 1
		ans = 0
		o_dict = {}
		for obstacle in obstacles:
			o_dict[tuple(obstacle)] = True
		for command in commands:
			if command == -2:
				(dx, dy) = (-dy, dx)
			elif command == -1:
				(dy, dx) = (-dx, dy)
			else:
				for k in range(command):
					if (x + dx, y + dy) not in o_dict.keys():
						x += dx
						y += dy
						ans = max(ans, x ** 2 + y ** 2)
					else:
						break
		return ans