Open In App

Convert string S1 to S2 by moving B to right and A to left without crossover

Last Updated : 08 Nov, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given strings s1 and s2 consisting of ‘A’, ‘B’ and ‘#’, where: 

  • ‘#’ represents an empty cell
  • ‘A’ represents robots that can move in the left direction and
  • ‘B’ represents robots that can move in the right direction

The task is to check if s1 can be converted to s2 by movement of the robots.

Examples:

Input: s1 = “#B#A#”, s2 = “##BA#”
Output: Yes
Explanation: In one step ‘B’ moves one position to the right.
So the string becomes “##BA#” which is same as the final s2 string

Input: s1 = “#B#A#”, s2 = “#A#B#”  
Output: No
Explanation: As the robots cannot cross each other.

Recommended Practice

Approach: The idea to solve the problem is based on the following observation:

The robots can reach the final position when the strings satisfy the condition:

  • If the empty spaces ‘#’ are removed from string then both the strings should be identical as no crossing of A and B are allowed.
  • After removing the ‘#’ from both the strings, if positions of A is lesser in s2 than in s1 and positions of ‘B’ is greater in s2 than in s1.

Follow the steps mentioned below to implement the above observation:

  • Iterate the array from the start:
    • Remove the empty spaces (‘#’) from both the strings.
    • Store the position of A and B in both the strings
  • If the modified strings s1 and s2 are exactly the same then they can reach the final state when:
    • Position of ‘A’ in s1 is greater than or equal to the position of ‘A’ in s2 and the position of ‘B’ in s1 is less than or equal to the position of ‘B’ in s2.
  • In all other cases, the robots cannot reach the final positions mentioned in s2.

Below is the implementation for the above approach.

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if robots can move
string moveRobots(string s1, string s2)
{
 
    // Strings to save s1 and s2 without '#'
    string a, b;
    for (int i = 0; i < s1.size(); i++)
        if (s1[i] != '#')
            a += s1[i];
    for (int i = 0; i < s2.size(); i++)
        if (s2[i] != '#')
            b += s2[i];
 
 
    // Condition 1: strings s1 and s2
    // without empty spaces should be
    // exactly same
    if (a == b) {
        int n = a.size();
 
        // v1 and v2 will store the
        // positions of 'A' or 'B'
        // in s1 and s2 respectively
        vector<int> v1;
        vector<int> v2;
        for (int i = 0; i < s1.size(); i++) {
            if (s1[i] != '#')
                v1.push_back(i);
        }
        for (int i = 0; i < s2.size(); i++)
            if (s2[i] != '#')
                v2.push_back(i);
 
        // Condition 2:
        // Position of 'A' in s1 should be
        // greater than or equal to
        // Position of 'A' in s2 and
        // Position of 'B' in s1 should be
        // less than or equal to
        // Position of 'B' in s2
        if (a[0] == 'A' and v1[0] < v2[0])
            return "No";
        if (a[0] == 'B' and v1[0] > v2[0])
            return "No";
        for (int i = 1; i < n; i++) {
            if (a[i] == 'A') {
                if (v1[i] < v2[i])
                    return "No";
            }
            else {
                if (v1[i] > v2[i])
                    return "No";
            }
        }
        return "Yes";
    }
    return "No";
}
 
// Driver code
int main()
{
    string s1 = "#B#A#";
    string s2 = "##BA#";
    cout << moveRobots(s1, s2) << endl;
    return 0;
}


Java




// Java code for the above approach:
import java.util.*;
class GFG {
 
  // Function to check if robots can move
  static String moveRobots(String s1, String s2)
  {
 
    // Strings to save s1 and s2 without '#'
    String a = "", b = "";
    for (int i = 0; i < s1.length(); i++)
      if (s1.charAt(i) != '#')
        a += s1.charAt(i);
    for (int i = 0; i < s2.length(); i++)
      if (s2.charAt(i) != '#')
        b += s2.charAt(i);
 
    // Condition 1: strings s1 and s2
    // without empty spaces should be
    // exactly same
    if (a.equals(b)) {
      int n = a.length();
 
      // v1 and v2 will store the
      // positions of 'A' or 'B'
      // in s1 and s2 respectively
      ArrayList<Integer> v1
        = new ArrayList<Integer>();
      ArrayList<Integer> v2
        = new ArrayList<Integer>();
      for (int i = 0; i < s1.length(); i++) {
        if (s1.charAt(i) != '#')
          v1.add(i);
      }
      for (int i = 0; i < s2.length(); i++)
        if (s2.charAt(i) != '#')
          v2.add(i);
 
 
      // Condition 2:
      // Position of 'A' in s1 should be
      // greater than or equal to
      // Position of 'A' in s2 and
      // Position of 'B' in s1 should be
      // less than or equal to
      // Position of 'B' in s2
      if (a.charAt(0) == 'A'
          && (int)v1.get(0) < (int)v2.get(0))
        return "No";
      if (a.charAt(0) == 'B'
          && (int)v1.get(0) > (int)v2.get(0))
        return "No";
      for (int i = 1; i < n; i++) {
        if (a.charAt(i) == 'A') {
          if ((int)v1.get(i) < (int)v2.get(i))
            return "No";
        }
        else {
          if ((int)v1.get(i) > (int)v2.get(i))
            return "No";
        }
      }
      return "Yes";
    }
    return "No";
  }
 
  // Driver code
  public static void main(String[] args)
  {
    String s1 = "#B#A#";
    String s2 = "##BA#";
    System.out.println(moveRobots(s1, s2));
  }
}
 
// This code is contributed by ukasp.


Python3




# python3 code for the above approach:
 
# Function to check if robots can move
def moveRobots(s1, s2):
 
    # Strings to save s1 and s2 without '#'
    a, b = "", ""
    for i in range(0, len(s1)):
        if (s1[i] != '#'):
            a += s1[i]
    for i in range(0, len(s2)):
        if (s2[i] != '#'):
            b += s2[i]
 
    # Condition 1: strings s1 and s2
    # without empty spaces should be
    # exactly same
    if (a == b):
        n = len(a)
 
        # v1 and v2 will store the
        # positions of 'A' or 'B'
        # in s1 and s2 respectively
        v1 = []
        v2 = []
        for i in range(0, len(s1)):
            if (s1[i] != '#'):
                v1.append(i)
 
        for i in range(0, len(s2)):
            if (s2[i] != '#'):
                v2.append(i)
 
        # Condition 2:
        # Position of 'A' in s1 should be
        # greater than or equal to
        # Position of 'A' in s2 and
        # Position of 'B' in s1 should be
        # less than or equal to
        # Position of 'B' in s2
        if (a[0] == 'A' and v1[0] < v2[0]):
            return "No"
        if (a[0] == 'B' and v1[0] > v2[0]):
            return "No"
        for i in range(1, n):
            if (a[i] == 'A'):
                if (v1[i] < v2[i]):
                    return "No"
 
            else:
                if (v1[i] > v2[i]):
                    return "No"
 
        return "Yes"
 
    return "No"
 
# Driver code
if __name__ == "__main__":
 
    s1 = "#B#A#"
    s2 = "##BA#"
    print(moveRobots(s1, s2))
 
# This code is contributed by rakeshsahni


C#




// C# code for the above approach:
using System;
using System.Collections;
 
class GFG
{
 
  // Function to check if robots can move
  static string moveRobots(string s1, string s2)
  {
 
    // Strings to save s1 and s2 without '#'
    string a = "", b = "";
    for (int i = 0; i < s1.Length; i++)
      if (s1[i] != '#')
        a += s1[i];
    for (int i = 0; i < s2.Length; i++)
      if (s2[i] != '#')
        b += s2[i];
 
    // Condition 1: strings s1 and s2
    // without empty spaces should be
    // exactly same
    if (a == b) {
      int n = a.Length;
 
      // v1 and v2 will store the
      // positions of 'A' or 'B'
      // in s1 and s2 respectively
      ArrayList v1 = new ArrayList();
      ArrayList v2 = new ArrayList();
      for (int i = 0; i < s1.Length; i++) {
        if (s1[i] != '#')
          v1.Add(i);
      }
      for (int i = 0; i < s2.Length; i++)
        if (s2[i] != '#')
          v2.Add(i);
 
      // Condition 2:
      // Position of 'A' in s1 should be
      // greater than or equal to
      // Position of 'A' in s2 and
      // Position of 'B' in s1 should be
      // less than or equal to
      // Position of 'B' in s2
      if (a[0] == 'A' && (int)v1[0] < (int)v2[0])
        return "No";
      if (a[0] == 'B' && (int)v1[0] > (int)v2[0])
        return "No";
      for (int i = 1; i < n; i++) {
        if (a[i] == 'A') {
          if ((int)v1[i] < (int)v2[i])
            return "No";
        }
        else {
          if ((int)v1[i] > (int)v2[i])
            return "No";
        }
      }
      return "Yes";
    }
    return "No";
  }
 
  // Driver code
  public static void Main()
  {
    string s1 = "#B#A#";
    string s2 = "##BA#";
    Console.Write(moveRobots(s1, s2));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
    // JavaScript code for the above approach:
 
    // Function to check if robots can move
    const moveRobots = (s1, s2) => {
 
        // Strings to save s1 and s2 without '#'
        let a, b;
        for (let i = 0; i < s1.length; i++)
            if (s1[i] != '#')
                a += s1[i];
        for (let i = 0; i < s2.length; i++)
            if (s2[i] != '#')
                b += s2[i];
 
        // Condition 1: strings s1 and s2
        // without empty spaces should be
        // exactly same
        if (a == b) {
            let n = a.length;
 
            // v1 and v2 will store the
            // positions of 'A' or 'B'
            // in s1 and s2 respectively
            let v1 = [];
            let v2 = [];
            for (let i = 0; i < s1.length; i++) {
                if (s1[i] != '#')
                    v1.push(i);
            }
            for (let i = 0; i < s2.length; i++)
                if (s2[i] != '#')
                    v2.push(i);
 
            // Condition 2:
            // Position of 'A' in s1 should be
            // greater than or equal to
            // Position of 'A' in s2 and
            // Position of 'B' in s1 should be
            // less than or equal to
            // Position of 'B' in s2
            if (a[0] == 'A' && v1[0] < v2[0])
                return "No";
            if (a[0] == 'B' && v1[0] > v2[0])
                return "No";
            for (let i = 1; i < n; i++) {
                if (a[i] == 'A') {
                    if (v1[i] < v2[i])
                        return "No";
                }
                else {
                    if (v1[i] > v2[i])
                        return "No";
                }
            }
            return "Yes";
        }
        return "No";
    }
 
    // Driver code
 
    let s1 = "#B#A#";
    let s2 = "##BA#";
    document.write(moveRobots(s1, s2));
 
// This code is contributed by rakeshsahni
 
</script>


Output

Yes

Time Complexity: O(N)
Auxiliary Space: O(N)

Method 2 :- Optimized Solution 

Approach: The idea to solve the problem is based on the following observation:

Step 1 :- Take a pointer (say i) at the first string and another pointer (say j) for the second string.

Step 2 :- Increment the pointer of the both the string until you found any of the BOTS.

Step 2 , CASE 1 :- If the BOTS pointed by the respective pointers are not same then in that case the answer is NO.

Reason :- Let us consider two string namely S1 =  ##A##B# and S2 = ##B##A#

In order to achieve the state represented by S2 , It is sure that during this transition the BOTS have crossed each other then only it can achieve the state. But according to question BOTS should not cross each other and hence the answer will be NO.

Hence if S1[i] == ‘A’ and S2[j] == ‘B’ , then in this case return NO.

Step 2, CASE 2 :- If the two BOTS pointed by the two pointers are same and Let’s say A is the bot that is encountered then it should be in the following case :-

Reason :- Let us consider two string namely S1 =  ##A##B# and S2 = ###A#B#

We can see that in order to achieve the state represented by the S2 A has to move right BUT According to question A can only move left so we can’t achieve this state.

Hence if S1[i] == ‘A’ and S2[j] == ‘A’ and i<j , then in this case return NO.

Step 2, CASE 3 :- If the two BOTS pointed by the two pointers are same and Let’s say B is the bot that is encountered then it should be in the following case :-

Reason :- Let us consider two string namely S1 =  ##A##B# and S2 = ##AB###

We can see that in order to achieve the state represented by the S2 B has to move left BUT According to question B can only move right so we can’t achieve this state.

Hence if S1[i] == ‘B’ and S2[j] == ‘B’ and i>j , then in this case return NO.

For the other cases it is possible to achieve the state represented by S2.

Below is the implementation of the above approach :- 

C++




// cpp program to check if we can transit from state
// represented by S1 to state represented by State S2
#include <bits/stdc++.h>
using namespace std;
 
void moveRobots(string s1, string s2)
{
    int i = 0, j = 0, n = s1.size();
    while (i < n && j < n) {
        if (s1[i] == '#')
            i++;
        else if (s2[j] == '#')
            j++;
        // Step 2 CASE 1
        else if (s1[i] != s2[j])
            cout << "No";
        // Step 2 CASE 2
        else if (s1[i] == 'A' && i < j)
            cout << "No";
        // Step 2 CASE 3
        else if (s1[i] == 'B' && i > j)
            cout << "No";
        else {
            i++;
            j++;
        }
    }
    cout << "Yes";
}
 
int main()
{
    string s1 = "#B#A#", s2 = "##BA#";
    moveRobots(s1, s2);
    return 0;
}
 
// This code is contributed by Aditya Kumar (adityakumar129)


C




// c program to check if we can transit from state
// represented by S1 to state represented by State S2
#include <stdio.h>
#include <string.h>
 
void moveRobots(char s1[], char s2[])
{
    int i = 0, j = 0, n = strlen(s1);
    while (i < n && j < n) {
        if (s1[i] == '#')
            i++;
        else if (s2[j] == '#')
            j++;
        // Step 2 CASE 1
        else if (s1[i] != s2[j])
            printf("No");
        // Step 2 CASE 2
        else if (s1[i] == 'A' && i < j)
            printf("No");
        // Step 2 CASE 3
        else if (s1[i] == 'B' && i > j)
            printf("No");
        else {
            i++;
            j++;
        }
    }
    printf("Yes");
}
 
int main()
{
    char s1[] = "#B#A#";
    char s2[] = "##BA#";
    moveRobots(s1, s2);
    return 0;
}
 
// This code is contributed by Aditya Kumar (adityakumar129)


Java




// java program to check if we can transit from state
// represented by S1 to state represented by State S2
import java.io.*;
import java.util.*;
 
class BOTS {
    public static void moveRobots(String s1, String s2)
    {
        int i = 0, j = 0;
        int n = s1.length();
        while (i < n && j < n) {
            if (s1.charAt(i) == '#')
                i++;
            else if (s2.charAt(j) == '#')
                j++;
            // Step 2 CASE 1
            else if (s1.charAt(i) != s2.charAt(j))
                System.out.println("No");
            // Step 2 CASE 2
            else if (s1.charAt(i) == 'A' && i < j)
                System.out.println("No");
            // Step 2 CASE 3
            else if (s1.charAt(i) == 'B' && i > j)
                System.out.println("No");
            else {
                i++;
                j++;
            }
        }
        System.out.println("Yes");
    }
}
 
class GFG {
    public static void main(String args[])
    {
        String s1 = "#B#A#";
        String s2 = "##BA#";
 
        BOTS obj = new BOTS();
        obj.moveRobots(s1, s2);
    }
}
 
// This code is contributed by Aditya Kumar (adityakumar129)


Python




# Python program to check if we can transit from state
# represented by S1 to state represented by State S2
 
def moveRobots(s1, s2) :
    i = 0
    j = 0
    n = len(s1)
    while i < n and j < n :
        if s1[i] == '#' :
            i+=1
        elif s2[j] == '#' :
            j+=1
        # Step 2 CASE 1
        elif s1[i] != s2[j] :
            print("No")
        # Step 2 CASE 2
        elif s1[i] == 'A' and i < j :
            print("No")
        # Step 2 CASE 3
        elif s1[i] == 'B' and i > j :
            print("No")
        else :
            i+=1
            j+=1
    print("Yes")
 
# Driver Code
if __name__ == '__main__':
    s1 = "#B#A#"
    s2 = "##BA#"
    moveRobots(s1, s2)
 
# This code has been contributed by Sachin Sahara (sachin801)


Javascript




<script>
    // Javascript program to check if we can transit from state
    // represented by S1 to state represented by State S2
  
    const moveRobots = (s1, s2) => {
  
        let i=0, j=0, n=s1.length;
         
        while(i<n && j<n){
            if(s1[i]=='#')
                i++;
            else if(s2[j]=='#')
                j++;
            // Step 2 CASE 1
            else if (s1[i] != s2[j])
                document.write("No");
            // Step 2 CASE 2
            else if (s1[i] == 'A' && i < j)
                document.write("No");
            // Step 2 CASE 3
            else if (s1[i] == 'B' && i > j)
                document.write("No");
            else{
                i++;
                j++;
            }
        }
         
        document.write("Yes");
    }
  
    // Driver code
  
    let s1 = "#B#A#";
    let s2 = "##BA#";
    moveRobots(s1, s2);
  
// This code is contributed by adityapatil12
  
</script>


C#




// C# program to implement above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG
{
     
    // Driver code
    public static void Main(string[] args){
 
        String s1 = "#B#A#";
        String s2 = "##BA#";
 
        BOTS obj = new BOTS();
        obj.moveRobots(s1, s2);
 
    }
}
 
public class BOTS {
    public void moveRobots(String s1, String s2)
    {
        int i = 0, j = 0;
        int n = s1.Length;
        while (i < n && j < n) {
            if (s1[i] == '#')
                i++;
            else if (s2[j] == '#')
                j++;
            // Step 2 CASE 1
            else if (s1[i] != s2[j])
                Console.WriteLine("No");
            // Step 2 CASE 2
            else if (s1[i] == 'A' && i < j)
                Console.WriteLine("No");
            // Step 2 CASE 3
            else if (s1[i] == 'B' && i > j)
                Console.WriteLine("No");
            else {
                i++;
                j++;
            }
        }
        Console.WriteLine("Yes");
    }
}


Output

Yes

Time Complexity: O(N)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads