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.

Difficulty: introductory

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 # NESW = 0123
        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 = [[0,1],[1,0],[0,-1],[-1,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:  #left
                di = (di - 1) % 4
            elif cmd == -1:  #right
                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:
        # 10:20am
        
        # DFS
        
        cur = [0, 0]
        directions = [[0,1],[1,0],[0,-1],[-1,0]]
        cur_direction = 0 # facing north
        max_distance = -1
        obstacles = {tuple(i) for i in obstacles}  # have to use this to avoid TLE
        for c in commands:
            if c > 0:
                while c > 0:
                    # move forward
                    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 # stop moving, go to next command
                    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
                
#         x, y = 0, 0   #current position of robot
#         dx, dy = 0, 1   #direction of robot
#         obs = {tuple(i) for i in obstacles}   #create set of obstacles for faster access
#         maxdist = 0   #store max distance after each command
        
#         for step in commands:
#             if 0 < step < 10:
#                 for i in range(step):
#                     x, y = x+dx, y+dy   #take each step individually
#                     if (x,y) in obs:   #take one step back if on an obstacle
#                         x, y = x-dx, y-dy
#                         break
#             elif step == -2:   #change direction | move left
#                 dx, dy = -dy, dx
#             elif step == -1:   #change direction | move right
#                 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:
        dx = [0, 1, 0, -1]
        dy = [1, 0, -1, 0]
        x = y = di = 0
        o_set = set(map(tuple, obstacles))
        res = 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]
                        res = max(res, x*x + y*y)
        return res


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,di=0,0,0
        dx=[0,1,0,-1]
        dy=[1,0,-1,0]
        obstacles=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 (dx[di]+x,dy[di]+y) not in obstacles:
                        x+=dx[di]
                        y+=dy[di]
                        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 cmd in commands:
            if cmd == -2:  #left
                di = (di - 1) % 4
            elif cmd == -1:  #right
                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]
                    else:
                        break
                ans = max(ans, x*x + y*y)

        return ans

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(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:  #left
                di = (di - 1) % 4
            elif cmd == -1:  #right
                di = (di + 1) % 4
            else:
                for k in range(0,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, 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
            else:
                if 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:
        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:
        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:
        
        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:
        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, 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
            else:
                if 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:
        
        # LC solution copy
        '''
        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: # left
                di = (di - 1) % 4
            elif cmd == -1: # right
                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
        '''
        
        
        
        
        
        
        # My attempt failed with incorrect answer for some large input, so above is LC copy, Fixed the mistake in code below,
        # Basically we are asked for maximum distance the robot went, not the distance to final destination.
        
        # -2: turn left 90 degrees
        # -1: turn right 90 deg
        # 1 <= x <= 9 forward x units
        
        #obstacle[i][0], obstacles[i][1] is an obstacle
        
        # Calculate euclidean distance from origin.
        
        #check obstacle at every move and apply the distance and turns he can perform.
        
        # cmd[i]
        # position[i] = position[i-1] + min(cmd[i], blocked())
        
        obstacleSet = set()
        
        for p in obstacles:
            obstacleSet.add(tuple(p))
        
        dirs = [1, 1, -1, -1] # must be 1 for west and north, -1 for east and south 
        
        axis = [0, 1] # must be 0 for east and west, 1 for north and south.
        
        position = [0,0]
        
        ax = 1 # Along Y axis 
        up = 0 # Facing north
        result = 0
        for cmd in commands:
            
            if cmd > 0:
                # scan for obstacle and limit move up to the obstacle
                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 # Left
            elif cmd == -1:
                ax = (ax + 1)%2
                up = (up + 1)%4 # Right
            
            #print(prev, \"->\", position, ax, up)
        
        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, 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:  #left
                di = (di - 1) % 4
            elif cmd == -1:  #right
                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
        obstacleSet = set(map(tuple, obstacles))
        ans = 0
        
        for command in commands:
            if command == -2:
                di = (di - 1) % 4  # left
            elif command == -1:
                di = (di + 1) % 4  # right
            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   #current position of robot
        dx, dy = 0, 1   #direction of robot
        obs = {tuple(i) for i in obstacles}   #create set of obstacles for faster access
        maxdist = 0   #store max distance after each command
        
        for step in commands:
            if 0 < step < 10:
                for i in range(step):
                    x, y = x+dx, y+dy   #take each step individually
                    if (x,y) in obs:   #take one step back if on an obstacle
                        x, y = x-dx, y-dy
                        break
            elif step == -2:   #change direction | move left
                dx, dy = -dy, dx
            elif step == -1:   #change direction | move right
                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
            else:
                if 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:
    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:
    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:
        obs = {tuple(i) for i in obstacles}
        x, y = 0, 0
        dx, dy = 0, 1
        maxdist = 0
        for i in commands:
            if 1 <= i <= 9:
                for j in range(i):
                    x, y = x+dx, y+dy
                    if (x,y) in obs:
                        x, y = x - dx, y-dy
                        break
            elif i == -2:
                dx, dy = -dy, dx
            elif i == -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:
        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:
        
        
        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
        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

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 cmd in commands:
            if cmd == -2:  #left
                di = (di - 1) % 4
            elif cmd == -1:  #right
                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