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
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).
C'est pourquoi 4 exécutions consécutives le décalent simplement d'un vecteur sans rotation.
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.
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;
}
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";
}
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.)
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'
#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;
}
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 )