Check if it is possible to reach any point on the circumference of a given circle from origin


The circumference of a circle can be defined as the outer boundary of the circle. It is the perimeter of a circle. Each point around a circle follows certain properties as follows −

  • Point (x,y) lying inside the circle such that, $\mathrm{x^2 + y^2 < R^2}$

  • Point (x,y) lying on the circle such that, $\mathrm{x^2 + y^2 = R^2}$

  • Point (x,y) lying outside the circle such that, $\mathrm{x^2 + y^2 > R^2}$

where R = radius of the circle.

Problem Statement

Given a string S representing a sequence of moves (L, R, U, D) and an integer R representing the radius of the circle. Check if it is possible to reach any point of the circumference of the circle with radius R from the origin by choosing any subsequence of moves from S. Operations of each move are depicted below,

  • L = decrement x-coordinate

  • R = increment x-coordinate

  • U = increment y-coordinate

  • D = decrement y-coordinate

Sample Example 1

Input

S = “RURDLR”
R = 2

Output

Yes

Explanation

Choosing the subsequence “RR” −

Initially, (0, 0) + R −> (1, 0) + R −> (2, 0).

Possible to reach circumference as, 22 + 02 = 4 = R2

Sample Example 2

Input

S = “UUUUU”
R = 6

Output

No

Explanation

Choosing the largest subsequence “UUUUU” −

Initially, (0, 0) + U −> (0, 1) + U −> (0, 2) + U −> (0, 3) + U −> (0, 4) + U −> (0, 5).

Not possible to reach the circumference as, 02 + 52 = 25 R2

Approach 1: Brute Force

Solution for the problem is to find all the possible subsequences of string S and then check for each subsequence if it can be reached the circumference. These conditions are checked by maintaining a counter for x and y where x is decremented on each L and increment on each R. Similarly, y is decremented on each D and incremented on each U. Then checking if x2 + y2 = R2 to check if the final point is on the circumference or not.

Pseudocode

procedure subsequence (S, sub, vec):
   if S is empty
      add sub to vec
      return
   end if
   subsequence(S.substring(1), sub + S[0], vec)
   subsequence(S.substring(1), sub, vec)
end procedure

procedure checkSeq (S, R)
   x = 0
   y = 0
   for move in S do
      if move == 'L' then
         x = x - 1
      else if move == 'R' then
         x = x + 1
      else if move == 'U' then
         y = y + 1
      else if move == 'D' then
         y = y - 1
      end if
      if x^2 + y^2 = R^2 then
         return true
      end if
   end for
   return false
end procedure

procedure reachCircumference (S, R):
   v = []      
   subsequence(S, "", v)
   for str in v:
      if checkSeq(str, R)
      return "yes"
      end if
   return "no"
end procedure

Example: C++ Implementation

In the following program, create all the possible subsequences of string S and check if they reach the circumference of the circle.

#include <bits/stdc++.h>
using namespace std;

// Function to create all the possible subsequence of string S
void subsequence(string S, string sub, vector<string> &vec){

   // Base Case
   if (S.empty()) {
      vec.push_back(sub);
      return;
   }
   
   // Subsequence including the character
   subsequence(S.substr(1), sub + S[0], vec);
   
   // Subsequence excluding the character
   subsequence(S.substr(1), sub, vec);
}

// Function to check if a given sequence of steps lead to the circumference of the circle with radius R
bool checkSeq(string S, int R){

   // Initialising centre of circle as (0, 0)
   int x = 0, y = 0;
   for (char move : S) {
      if (move == 'L') {
         x -= 1;
      } else if (move == 'R') {
         x += 1;
      } else if (move == 'U') {
         y += 1;
      } else if (move == 'D') {
         y -= 1;
      }
      
      // Check to find if (x, y) lie on circumference using the circle equation
      if (x*x + y*y == R*R) {
         return true;
      }
   }
   return false;
}

// function to check if any subsequence of string S leads to any point on the circumference of the circle
string reachCircumference(string S, int R){
   vector <string> v;
   string sub = "";
   
   // Storing all subsequence in vector v
   subsequence(S, sub, v);
   
   // Checking the condition for each subsequence
   for (auto str: v) {
      if(checkSeq(str, R)) {
         return "yes";
         break;
      }
   }
   return "no";
}

// Driver Code
int main(){
   string S = "RURDLR";
   int R = 2;
   cout << reachCircumference(S, R) << endl;
   return 0;
}

Output

yes

Approach 2: Optimized Approach

An efficient approach to the problem is to check if any pair of x and y upon using (L, R, U or D) has the sum of squares of x and y equal to the square of the radius.

First, we count the maximum occurrence of each step and check if anyone is equal to R. if not then we check if any number of pairs of either L or R and U or D can lead to a distance equal to R from the origin.

Pseudocode

procedure reachCircumference (S, R)
   cL = 0
   cR = 0
   cD = 0
   cU = 0
   for move in S do
if move == 'L' then
x = x - 1
else if move == 'R' then
x = x + 1
else if move == 'U' then
y = y + 1
else if move == 'D' then
y = y - 1
end if
if x^2 + y^2 = R^2 then
return true
end if
end for
   if max(max(cL, cR), max(cD, cU)) >= R
      return “yes”
   maxLR = max(cL, cR)
maxUD = max(cU, cD)
Initialise unordered map mp
sq = R * R
for i = 1 till i * i = sq
   if sq - i*i is not in the map
      if maxLR>= mp[sq - i * i] and maxUD >= i
         return “yes”
      end if
      if maxLR >= i && maxUD >= mp[sq - i * i]
         return “yes”
      end if
   end if
end for
return “no”
end procedure

Below is the C++ Implementation,

In the following program, we use a map to check for any subsequence that leads to the circumference of the circle.

#include <bits/stdc++.h>
using namespace std;

// Function to check if any subsequence of string S leads to any point on the circumference of the circle
string reachCircumference (string S, int R){

   // Counting total occurrenceof each L, R, U, D
   int cL = 0, cR = 0, cD = 0, cU = 0;
   for (char move : S) {
      if (move == 'L') {
         cL++;
      } else if (move == 'R') {
         cR++;
      } else if (move == 'U') {
         cU++;
      } else if (move == 'D') {
         cD++;
      }
   }
   
   // Checking for a path to circumference using only one type of move
   if (max(max(cL, cR), max(cD, cU)) >= R) {
      return "yes";
   }
   int maxLR = max(cL, cR), maxUD = max(cU, cD);
   unordered_map<int, int> mp;
   int sq = R * R;
   for (int i = 1; i * i <= sq; i++) {
      mp[i * i] = i;
      if (mp.find(sq - i * i) != mp.end()) {
      
         // Checking if it is possible to reach (± mp[r_square - i*i], ± i)
         if (maxLR>= mp[sq - i * i] && maxUD >= i)
            return "yes";
            
         // Checking if it is possible to reach (±i, ±mp[r_square-i*i])
         if (maxLR >= i && maxUD >= mp[sq - i * i])
            return "yes";
      }
   }
   return "no";
}

// Driver Code
int main(){
   string S = "RURDLR";
   int R = 5;
   cout << reachCircumference(S, R) << endl;
   return 0;
}

Output

no

Conclusion

In conclusion, to find if it possible to rach the circumferenc of a circle centered at origin using a subsequence of steps in string S, any of the above approaches can be used. The second approach is a faster method but uses additional space while the first approach the brute force approach is not very efficient but easy to understand.

Updated on: 25-Jul-2023

34 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements