C++ Program to Find Minimum circular rotations to obtain a given numeric string by avoiding a set of strings


In this article, we will find the minimum circular rotations that are needed to obtain a given numeric string, target, by avoiding a given set of strings. The target strings and the strings in the set of string both have a size of N. The initial string will be a string containing all zeroes and the length of the input string will also be N.

In the approach discussed in this article, we will use a queue data structure and a set data structure. The queue data structure will hold the strings that we are currently at, i.e., the numeric strings that we have reached so far. The set data structure will hold all the blocked strings, and all the strings that we have already reached before. This is done to avoid repetition, so that we don’t visit the same strings again and again and get stuck inside an endless loop. At each iteration, we will make all the possible moves and add the new strings that were made into the queue. The first time we make the target string, we break out of the loop, and return the answer.

Problem Statement

Given a numeric string, target, of size N and a list of strings, each of size N, we need to find the minimum number of circular rotations we need to make in order to convert the initial string into the target string. The initial string will be a string of size N, containing only zeroes.

In a single circular rotation, we can choose any index between 0 to N-1 and increase or decrease the numeric value at that index in the initial string.

Note − If the value of a particular index is 0 and we perform the decrease operation on this index, its value will get converted to 9. Similarly, if the value of a particular index in 9, and we perform the increase operation on it, its value will be converted to 0.

Sample Examples

Input

Target = “22”, avoid = {“10”, “11”, “12”}

Output

6

Explanation

We can follow the below order to get the target string:

“00” -> “01” -> “02” -> “03” -> “13” -> “23” -> “22”

Input

target = “55”, avoid = {“01”, “10”, “09”, “90”}

Output

-1

Explanation

From our initial string that is “00”, if we make a single circular rotation, we can make four strings which are “01”, “10”, “09”, “90”. And since all these strings are in the avoid array, we cannot make any string except “00”.

Hence the output is –1.

Input

target = “111”, avoid = {“001”, “010”, “100”}

Output

5

Explanation

We can follow the following order −

“000” -> “900” -> “910” -> “911” -> “011” -> “111”

Approach

In this approach, we will use a queue data structure and a set data structure. The queue data structure will be used to store all the possible strings that we can make after doing K circular rotation operations. The set data structure will store all the strings we want to avoid, and it will also store all the strings that we have already visited before, this will help in reducing repetition. We will insert the initial string in the queue. With each iteration, we pop out all of the current elements in the queue by using a for loop. Then for each of the strings, we find out all of the possible strings we can make by doing a single circular rotation operation on the string. If the string is already in the set, we continue else we add it to the queue and we also add it to the set. We loop till we get the target, or the queue becomes empty.

Algorithm

  • Step 1 − Make a set data structure.

  • Step 1.1 − Insert all the elements in the avoid array into the set data structure.

  • Step 1.2 − If the initial or the target string is in the avoid array, return -1.

  • Step 2 − Make a queue data structure and push the initial string in the queue.

  • Step 2.1 − Also, insert the string into the set.

  • Step 3 − Loop till the queue becomes empty:

  • Step 3.1 − In each iteration, store the current size of the queue in an array and make a for loop to access the queue elements.

  • Step 3.2 − In each iteration of the for loop, get the front element in the queue and pop it from the queue.

  • Step 3.3 − If the current string is equal to the target string, return the result.

  • Step 3.4 − Find all the strings that can be made by using the current string.

  • Step 3.5 − For each string, if the string is not already inside the set, push the string to the queue and insert the string into the set.

  • Step 3.6 − After completing the for loop, if we haven’t found the target string, add 1 to the result variable.

  • Step 4 − If the queue becomes empty, the target string cannot be made, so return -1.

Example

#include <bits/stdc++.h>
using namespace std;
int minimum_count_of_circular_operations(string target, vector<string> &avoid, string initial){
   set<string> to_avoid;
   for(auto it:avoid){
      if(it==initial || it==target)return -1;
      to_avoid.insert(it);
   }
   int res = 0;
   queue<string> curr_strings;
   curr_strings.push(initial);
   to_avoid.insert(initial);
   while(!curr_strings.empty()){
      int x = curr_strings.size();
      for(int i=0;i<x;i++){
         string temp = curr_strings.front();
         curr_strings.pop();
         if(temp==target)return res;
         for(int j=0;j<temp.size();j++){
            char increased = temp[j]+1 ,decreased=temp[j]-1, curr_ch=temp[j];
            if(temp[j]=='9')increased='0';
            if(temp[j]=='0')decreased='9';
            temp[j] = increased;
            if(!to_avoid.count(temp)){
               to_avoid.insert(temp);
               curr_strings.push(temp);
            }
            temp[j] = decreased;
            if(!to_avoid.count(temp)){
               to_avoid.insert(temp);
               curr_strings.push(temp);
            }
            temp[j] = curr_ch;
         }
      }
      res++;
   }
   return -1;
}
int main(){
   string target = "111";
   vector<string> avoid = {"001", "010", "100"};
   string initial = "000";    cout<<minimum_count_of_circular_operations(target,avoid,initial)<<endl;
   return 0;
}

Output

5

Time complexity – O(N^3), where N is the length of the strings.

Space complexity – O(N)

Updated on: 01-Nov-2023

23 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements