Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from dataclasses import dataclass, field 

2from typing import Tuple 

3 

4 

5@dataclass(frozen=True) 

6class Coordinates: 

7 x: int 

8 y: int 

9 left: str 

10 right: str 

11 

12 

13@dataclass 

14class Rover: 

15 x: int 

16 y: int 

17 direction: str 

18 obstacles: list[list[int]] = field(default_factory=list) 

19 

20 valid_commands = ("F", "B", "R", "L") 

21 

22 direction_map = { 

23 "NORTH": Coordinates(0, 1, "WEST", "EAST"), 

24 "EAST": Coordinates(1, 0, "NORTH", "SOUTH"), 

25 "SOUTH": Coordinates(0, -1, "EAST", "WEST"), 

26 "WEST": Coordinates(-1, 0, "SOUTH", "NORTH"), 

27 } 

28 

29 def is_valid_command(self, command: str) -> bool: 

30 for ch in command: 

31 if ch not in self.valid_commands: 

32 return False 

33 

34 return True 

35 

36 def is_obstacle(self, x: int, y: int) -> bool: 

37 return [x, y] in self.obstacles 

38 

39 def move(self, command: str): 

40 if not self.is_valid_command(command): 

41 raise ValueError("invalid command. The rover does not move") 

42 

43 for ch in command: 

44 x, y, direction = self._compute_new_coordinates(ch) 

45 if obstacle := self.is_obstacle(x, y): 

46 return self._new_coordinates_output(obstacle) 

47 

48 self._apply_new_coordinates(x, y, direction) 

49 

50 return self._new_coordinates_output() 

51 

52 def _new_coordinates_output(self, obstacle: bool = False): 

53 if obstacle: 

54 return self.x, self.y, self.direction, "STOPPED" 

55 return self.x, self.y, self.direction 

56 

57 def _compute_new_coordinates(self, command) -> Tuple[int, int, str]: 

58 x = self.x 

59 y = self.y 

60 direction = self.direction 

61 

62 if command == "B": 

63 x -= self.direction_map[self.direction].x 

64 y -= self.direction_map[self.direction].y 

65 if command == "F": 

66 x += self.direction_map[self.direction].x 

67 y += self.direction_map[self.direction].y 

68 if command == "R": 

69 direction = self.direction_map[self.direction].right 

70 if command == "L": 

71 direction = self.direction_map[self.direction].left 

72 

73 return x, y, direction 

74 

75 def _apply_new_coordinates(self, x, y, direction) -> None: 

76 self.x = x 

77 self.y = y 

78 self.direction = direction