it-swarm.com.de

Prüfen Sie, ob ein Kreis vorhanden ist

Ich wurde dies während eines Google-Interviews gefragt. Wir bekommen eine Zeichenfolge bestehend aus den Buchstaben F, L, R. - Auf welche Anweisung folgt ein Roboter

F- geht einen Schritt weiter.

L-Biegen Sie links ab.

R rechts abbiegen.

Die Stringlänge kann bis zu 2500 Zeichen betragen.

Die Zeichenfolge läuft unendlich oft. Wir müssen feststellen, ob ein Kreis mit einem Radius r (r kann eine reelle Zahl sein kann) vorhanden ist, sodass der Roboter den Kreis niemals verlässt ... Ich war an diesem Punkt hängen geblieben wie man es auf unendlich viele Zeiten überprüfen kann. Erklärung mit Code wird geschätzt. Bitte helfen Danke im Voraus

24
user3907480
  1. Jeder Durchlauf (ein Durchlauf führt alle Befehle der angegebenen Zeichenfolge einmal aus) ändert zwei Dinge: Die Richtung, in die der Roboter blickt, und seine Position (dh jeder Durchlauf verschiebt ihn um einen Vektor (die Richtung dieses Vektors hängt von seiner eigenen ab Anfangsrichtung vor dem Lauf) und dreht sie). 
  2. Die Anzahl der möglichen Richtungen beträgt 4. Nachdem die Simulation 4 Mal ausgeführt wurde, sieht sie in die gleiche Richtung wie ursprünglich (jeder Abrieb dreht sie um den gleichen Winkel).

  3. Deshalb verschieben 4 aufeinanderfolgende Läufe ihn ohne Drehung um einen Vektor.

  4. Daher können wir die Simulation einfach viermal hintereinander ausführen und sehen, ob sie am ursprünglichen Punkt angehalten hat. Wenn dies der Fall ist, können wir den minimalen Kreis ermitteln, der seinen Pfad enthält. Ansonsten existiert kein solcher Kreis.

22
kraskevich

Sie würden eine Iteration ausführen, um die neue Position zu berechnen, beispielsweise newx, newy . Dann würden Sie 4 weitere Iterationen berechnen, um zu sehen, ob der Roboter wieder bei newx-newy ist. Wenn ja, dann existiert der Kreis, sonst nicht.

Der Radius wäre die maximale Entfernung, die der Roboter in seiner Iteration gewagt hat.

Code-Implementierung - 

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

Führen Sie die Zeichenfolge aus, um zu sehen, wo sich der Roboter am Ende befindet und in welche Richtung er aussieht.

Wenn es sich wieder im Origin befindet, nehmen Sie die maximale Entfernung vom Origin während der Ausführung und vergleichen Sie es mit r.

Wenn es nicht wieder am Ursprung ist, überprüfen Sie seine Ausrichtung:

Wenn es dieselbe Ausrichtung hat wie am Anfang, wird es sich unbegrenzt vom Ursprung entfernen, so dass kein solches r existiert.

Wenn es eine andere Ausrichtung als zu Beginn hat, kehrt es nach 4 oder 2 Iterationen der Zeichenfolge zum Ursprung zurück, je nachdem, ob es links/rechts der ursprünglichen Ausrichtung oder umgekehrt liegt , beziehungsweise. Nehmen Sie jetzt die maximale Entfernung nach zwei Ausführungen der Saite. (Einfache Fallunterschiede zeigen, dass die maximale Entfernung nach 2 Ausführungen erreicht wurde, unabhängig davon, ob es sich um 2 oder 4 Ausführungen handelt.)

0
G. Bach

Das könnte funktionieren:

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