web-dev-qa-db-fra.com

Vérifier s'il y a un cercle

On m'a posé cette question lors d'une interview avec Google… .. Nous avons reçu une chaîne composée de lettres - F, L, R. - quelle est l'instruction qu'un robot suit

F- avance d'un pas.

Tourner à gauche.

R- tourner à droite.

La longueur de la chaîne peut aller jusqu'à 2500 caractères.

La chaîne court elle-même des temps infinis. Nous devons savoir s’il existe un cercle de rayon r (r peut être n’importe quel nombre réel), de sorte que le robot ne quitte jamais le cercle . comment le vérifier pendant des temps infinis.Explication avec le code sera appréciée. S'il vous plaît aider. Merci d'avance

24
user3907480
  1. Chaque exécution (une exécution exécute toutes les commandes de la chaîne donnée une fois) change deux choses: la direction vers laquelle le robot regarde et sa position (c’est-à-dire que chaque exécution la décale d’un vecteur (la direction de ce vecteur dépend de sa direction initiale avant la course) et la fait pivoter). 
  2. Le nombre de directions possibles est 4. Ainsi, après avoir exécuté la simulation 4 fois, celle-ci apparaît dans le même sens que précédemment (chaque frottement le fait pivoter du même angle).

  3. C'est pourquoi 4 exécutions consécutives le décalent simplement d'un vecteur sans rotation.

  4. Ainsi, nous pouvons simplement exécuter la simulation 4 fois de suite et voir si elle s’est arrêtée au point initial. Si c'était le cas, nous pouvons trouver le cercle minimal contenant son chemin. Sinon, un tel cercle n'existe pas.

22
kraskevich

Vous exécuteriez 1 itération pour calculer la nouvelle position, par exemple newx, newy . Ensuite, vous calculeriez 4 autres itérations pour voir si le robot est de retour sur newx-newy. Si c'est le cas, le cercle existe, sinon.

Le rayon correspond à la distance maximale parcourue par le robot lors de son itération.

Implémentation du code - 

//North, South, East, West directions
#define N 0 
#define S 1
#define E 2
#define W 3

// Function to compute the new pos (x, y, dir) after completing one iteration of the string.
// It will also update the max radius.
void findNewPos(char *str, int *origdir, int *origx, int *origy, double *maxrad) {
  int i, len, x, y, dir; 

  dir = *origdir;
  x = *origx;
  y = *origy;

  len = strlen(str);
  i=0;

  //Iterate through each character
  while(i < len) {
    char c = str[i];

    switch(c) {
    case 'L': // Turn left
      switch(dir) {
      case N:
         x--;
         dir = W;
         break;
      case S:
         x++;
         dir = E;
         break;
      case E:
         y++;
         dir = N;
         break;
      case W:
         y--;
         dir = S;
         break;
      }
      break;

    case 'R': // Turn right
      switch(dir) {
      case N:
         x++;
         dir = E;
         break;
      case S:
         x--;
         dir = W;
         break;
      case E:
         y--;
         dir = S;
         break;
      case W:
         y++;
         dir = N;
         break;
      }
      break;

    case 'F': // Go forward
      switch(dir) {
      case N:
         y++;
         dir = N;
         break;
      case S:
         y--;
         dir = S;
         break;
      case E:
         x++;
         dir = E;
         break;
      case W:
         x--;
         dir = W;
         break;
      }
      break;
    }

    // Update max radius till now
    double rad = x*x + y*y;
    if(rad > *maxrad)
      *maxrad = rad;
    i++;
  }

  *origx = x;
  *origy = y;
  *origdir = dir;
}

// Function to compute the max radius of movement, if bounded
double findCircle(char *str) {
  int x=0, y=0, dir=N;
  int refx, refy;
  double radius = 0, maxrad = 0;

  // Starting from Origin(x=0, y=0), find new pos after single iteration
  findNewPos(str, &dir, &x, &y, &maxrad);

  refx = x;
  refy = y;

  // Find new positions after 4 more iterations
  findNewPos(str, &dir, &x, &y, &maxrad);
  findNewPos(str, &dir, &x, &y, &maxrad);
  findNewPos(str, &dir, &x, &y, &maxrad);
  findNewPos(str, &dir, &x, &y, &maxrad);

  // Are we back to position where we were after 1st iteration?
  if(x == refx && y == refy) {
    printf("Circle exists %f!\n", maxrad);
    radius = sqrt(maxrad);
  }
  else {
    printf("Circle does not exist!\n");
    radius = -1;
  }

  return radius;
}
2
sray
string doesCircleExists(string commands) {
    int dir=1; //1 is east; 2 north etc.
    pair<int,int> pos; 
    pos = make_pair(0,0);  //start at Origin
    for(int i=0;i<4;i++) {
    for(int i=0;i<commands.size(); i++)
    {
       if(commands[i]=='F')
       {
        if(dir==1) pos.first++;  if(dir==2) pos.second++; 
        if(dir==3) pos.first--; if(dir==0) pos.second--; 
       }
       if(commands[i]=='L') {dir++; dir = dir%4;}
       if(commands[i]=='R') {dir--; dir = dir%4;}
    }
    }
    if(pos.first==0 && pos.second==0 && dir=1) return "YES"; else return "NO";

}

0
user3675152

Exécutez la chaîne, voyez où se trouve le robot à la fin et dans quelle direction il regarde.

S'il est de retour à l'origine, prenez la distance maximale par rapport à l'origine qu'il avait lors de l'exécution et comparez à r.

Si ce n'est pas le cas à l'origine, vérifiez son orientation:

S'il a la même orientation qu'au début, il s'éloignera indéfiniment de l'Origine, de sorte que ce type n'existe pas.

S'il a une orientation différente de celle du début, il retournera à l'origine après 4 ou 2 itérations de la chaîne, selon qu'elle est orientée à gauche/à droite de son orientation d'origine ou à l'inverse de celle-ci. , respectivement. Maintenant, prenez la distance maximale qu'il avait après 2 exécutions de la chaîne. (De simples distinctions de cas montreront qu'il aura parcouru sa distance maximale après 2 exécutions, que la période soit de 2 ou 4 exécutions.)

0
G. Bach

Cela pourrait fonctionner:

def encircular(string):

    ini_pos = [0,0]
    position = [0,0]
    direction = 'N'
    directions = {'NL':'W','NR':'E','EL':'N','ER':'S','SL':'E','SR':'W','WL':'S','WR':'N'}
    forward = {'N':[0,1],'E':[1,0],'S':[0,-1],'W':[-1,0]}
    for i in range(4):
        for i in string:
            if i == 'F':
                position = [x+y for x,y in Zip(position,forward[direction])]
            else:
                #print(direction+i)
                direction = directions[direction+i]
                #print (direction)
    if ini_pos == position: return 'YES'
    else : return 'NO'
0
prudhvi Indana
#include <bits/stdc++.h>
using namespace std;
struct point
{
    int x;
    int y;
    int dir;
};
int mod4(int a)
{
    if(a%4 < 0)
        return (a%4 + 4);
    else
        return a%4;
}
int main()
{
    struct point p;
    p.x = 0;
    p.y = 0;
    p.dir = 0;
    string s;cin>>s;
    int j;
    for(int i=0;i<4*s.size();i++)
    {
        j = i%s.size();
        if(s[j] == 'F')
        {
            if(p.dir == 0)//north
                p.y++;
            if(p.dir == 1)//east
                p.x++;
            if(p.dir == 2)//south
                p.y--;
            if(p.dir == 3)//west
                p.x--;
        }
        if(s[j] == 'L')
        {
            p.dir--;
            p.dir = mod4(p.dir);
        }
        if(s[j] == 'R')
        {
            p.dir++;
            p.dir = mod4(p.dir);
        }
        //cout<<p.x<<" "<<p.y<<" "<<p.dir<<endl;
    }
    if(p.x == 0 && p.y ==0 && p.dir == 0)
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;   
}
0
algoridam
def robot_bot(string): 
    face= 0
    pos=[0,0]
    string= string.upper() 
    dirc={0:[1,0],90:[0,1],180:[-1,0],270:[0,-1],360:[1,0],-90:[0,-1],-180:[-1,0],-270:[0,1]}
    for ch in string:
        if ch == "R": face -= 90
        Elif ch == "L": face += 90
        if ch == "G":
            pos[0]+=dirc[face][0]
            pos[1]+=dirc[face][1]
        print(pos,face)
        if abs(face) == 360: face=0
    return(True if pos==[0,0] else False )
0
Amir Ahmady