GeeksforGeeks App
Open App
Browser
Continue

# Minimum circular rotations to obtain a given numeric string by avoiding a set of given strings

Given a numeric string target of length N and a set of numeric strings blocked, each of length N, the task is to find the minimum number of circular rotations required to convert an initial string consisting of only 0‘s to target by avoiding any of the strings present in blocked at any step. If not possible, print -1.
Note: A single rotation involves increasing or decreasing a value at particular index by 1 unit. As rotations are circular, 0 can be converted to 9 or a 9 can be converted to 0.
Examples:

Input: target = “7531”, blocked = {“1543”, “7434”, “7300”, “7321”, “2427” }
Output: 12
Explanation: “0000” -> “9000” -> “8000” -> “7000” -> “7100” -> “7200” -> “7210” -> “7310” -> “7410” -> “7510” -> “7520” -> “7530” -> “7531”
Input: target = “4231”, blocked = { “1243”, “4444”, “1256”, “5321”, “2222” }
Output: 10

Approach: In order to solve this problem, we are using the following BFS approach:

• Create a string start of length N consisting of only 0’s. Push it to queue. The queue is created to store the next valid combination possible by increasing or decreasing a character by an unit.
• Create an unordered set avoid, and add all the blocked strings in it.
• If start or target is present in avoid, the required target cannot be reached.
• Pop start from queue and traverse all the characters of start. Increase and decrease each character by an unit keeping the remaining constant and check if the string is present in avoid. If not and the new combination is not equal to target, push it to the queue and insert into avoid to prevent repeating the same combination in future.
• Once the entire length of start is traversed, repeat the above steps for the next level, which are the valid strings obtained from start and are currently present in the queue.
• Keep repeating the above steps until target is reached or there are no further combinations left and the queue has become empty.
• At any instant, if the string formed is equal to target, return the value of count which keeps a count of the number of levels of BFS traversals. The value of count is the minimum number of circular rotations required.
• If no further state can be obtained and the queue is empty, print “Not Possible”.

Below is the implementation of the above logic:

## C++

 `// C++ Program to count the minimum``// number of circular rotations required``// to obtain a given numeric strings``// avoiding a set of blocked strings` `#include ``using` `namespace` `std;` `int` `minCircularRotations(``    ``string target,``    ``vector& blocked,``    ``int` `N)``{``    ``string start = ``""``;``    ``for` `(``int` `i = 0; i < N; i++) {``        ``start += ``'0'``;``    ``}` `    ``unordered_set avoid;` `    ``for` `(``int` `i = 0; i < blocked.size(); i++)``        ``avoid.insert(blocked[i]);` `    ``// If the starting string needs``    ``// to be avoided``    ``if` `(avoid.find(start) != avoid.end())``        ``return` `-1;` `    ``// If the final string needs``    ``// to be avoided``    ``if` `(avoid.find(target) != avoid.end())``        ``return` `-1;` `    ``queue qu;``    ``qu.push(start);` `    ``// Variable to store count of rotations``    ``int` `count = 0;` `    ``// BFS Approach``    ``while` `(!qu.empty()) {` `        ``count++;` `        ``// Store the current size``        ``// of the queue``        ``int` `size = qu.size();` `        ``for` `(``int` `j = 0; j < size; j++) {` `            ``string st = qu.front();``            ``qu.pop();` `            ``// Traverse the string``            ``for` `(``int` `i = 0; i < N; i++) {` `                ``char` `ch = st[i];` `                ``// Increase the``                ``// current character``                ``st[i]++;` `                ``// Circular rotation``                ``if` `(st[i] > ``'9'``)``                    ``st[i] = ``'0'``;` `                ``// If target is reached``                ``if` `(st == target)``                    ``return` `count;` `                ``// If the string formed``                ``// is not one to be avoided``                ``if` `(avoid.find(st)``                    ``== avoid.end())``                    ``qu.push(st);` `                ``// Add it to the list of``                ``// strings to be avoided``                ``// to prevent visiting``                ``// already visited states``                ``avoid.insert(st);` `                ``// Decrease the current``                ``// value by 1 and repeat``                ``// the similar checkings``                ``st[i] = ch - 1;` `                ``if` `(st[i] < ``'0'``)``                    ``st[i] = ``'9'``;``                ``if` `(st == target)``                    ``return` `count;``                ``if` `(avoid.find(st)``                    ``== avoid.end())``                    ``qu.push(st);``                ``avoid.insert(st);` `                ``// Restore the original``                ``// character``                ``st[i] = ch;``            ``}``        ``}``    ``}` `    ``return` `-1;``}` `// Driver code``int` `main()``{``    ``int` `N = 4;``    ``string target = ``"7531"``;``    ``vector blocked``        ``= { ``"1543"``,``            ``"7434"``,``            ``"7300"``,``            ``"7321"``,``            ``"2427"` `};` `    ``cout << minCircularRotations(``                ``target,``                ``blocked, N)``         ``<< endl;` `    ``return` `0;``}`

## Java

 `// Java Program to count the minimum``// number of circular rotations required``// to obtain a given numeric Strings``// avoiding a set of blocked Strings``import` `java.util.ArrayList;``import` `java.util.Arrays;``import` `java.util.HashSet;``import` `java.util.LinkedList;``import` `java.util.Queue;` `class` `GFG``{``  ``static` `int` `minCircularRotations(String target,``                                  ``ArrayList blocked,``                                  ``int` `N)``  ``{``    ``String start = ``""``;``    ``for` `(``int` `i = ``0``; i < N; i++)``    ``{``      ``start += ``'0'``;``    ``}` `    ``HashSet avoid = ``new` `HashSet<>();``    ``for` `(``int` `i = ``0``; i < blocked.size(); i++)``      ``avoid.add(blocked.get(i));` `    ``// If the starting String needs // to be avoided``    ``if` `(avoid.contains(start))``      ``return` `-``1``;` `    ``// If the final String needs // to be avoided``    ``if` `(avoid.contains(target))``      ``return` `-``1``;``    ``Queue qu = ``new` `LinkedList<>();``    ``qu.add(start);` `    ``// Variable to store count of rotations``    ``int` `count = ``0``;` `    ``// BFS Approach``    ``while` `(!qu.isEmpty())``    ``{``      ``count++;` `      ``// Store the current size // of the queue``      ``int` `size = qu.size();``      ``for` `(``int` `j = ``0``; j < size; j++)``      ``{``        ``StringBuilder st = ``new` `StringBuilder(qu.poll());` `        ``// Traverse the String``        ``for` `(``int` `i = ``0``; i < N; i++)``        ``{``          ``char` `ch = st.charAt(i);` `          ``// Increase the // current character``          ``st.setCharAt(i, (``char``) (st.charAt(i) + ``1``));` `          ``// Circular rotation``          ``if` `(st.charAt(i) > ``'9'``)``            ``st.setCharAt(i, ``'0'``);` `          ``// If target is reached``          ``if` `(st.toString().equals(target))``            ``return` `count;` `          ``// If the String formed``          ``// is not one to be avoided``          ``if` `(!avoid.contains(st.toString()))``            ``qu.add(st.toString());` `          ``// Add it to the list of``          ``// Strings to be avoided``          ``// to prevent visiting``          ``// already visited states``          ``avoid.add(st.toString());` `          ``// Decrease the current``          ``// value by 1 and repeat``          ``// the similar checkings``          ``st.setCharAt(i, (``char``) (ch - ``1``));``          ``if` `(st.charAt(i) < ``'0'``)``            ``st.setCharAt(i, ``'9'``);``          ``if` `(st.toString().equals(target))``            ``return` `count;``          ``if` `(!avoid.contains(st.toString()))``            ``qu.add(st.toString());``          ``avoid.add(st.toString());` `          ``// Restore the original``          ``// character``          ``st.setCharAt(i, ch);``        ``}``      ``}``    ``}``    ``return` `-``1``;``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``4``;``    ``String target = ``"7531"``;``    ``ArrayList blocked =``      ``new` `ArrayList<>(Arrays.asList(``"1543"``,``                                    ``"7434"``,``                                    ``"7300"``,``                                    ``"7321"``,``                                    ``"2427"``));``    ``System.out.println(minCircularRotations(target, blocked, N));``  ``}``}` `// This code is contributed by sanjeev2552`

## Python3

 `# python Program to count the minimum``# number of circular rotations required``# to obtain a given numeric strings``# avoiding a set of blocked strings``def` `minCircularRotations(target, blocked, N):``    ``start ``=` `""``    ``for` `i ``in` `range``(N):``        ``start ``+``=` `'0'` `    ``avoid ``=` `set``()` `    ``for` `i ``in` `range``(``len``(blocked)):``        ``avoid.add(blocked[i])` `    ``# If the starting string needs``    ``# to be avoided``    ``if``(start ``in` `avoid):``        ``return` `-``1` `    ``# If the final string needs``    ``# to be avoided``    ``if``(target ``in` `avoid):``        ``return` `-``1` `    ``# Initializing a queue``    ``qu ``=` `[]``    ``qu.append(start)` `    ``# Variable to store count of rotations``    ``count ``=` `0` `    ``while``(``len``(qu) !``=` `0``):``        ``count ``+``=` `1` `        ``# Store the current size``        ``# of the queue``        ``size ``=` `len``(qu)` `        ``for` `j ``in` `range``(size):``            ``st ``=` `qu[``0``]``            ``qu.pop(``0``)` `            ``# Traverse the string``            ``for` `i ``in` `range``(N):``                ``ch ``=` `st[i]` `                ``# Increase the``                ``# current character``                ``list1 ``=` `list``(st)``                ``list1[i] ``=` `chr``(``ord``(ch) ``+` `1``)``                ``st ``=` `''.join(list1)` `                ``# Circular rotation``                ``if``(st[i] > ``'9'``):``                    ``list1 ``=` `list``(st)``                    ``list1[i] ``=` `'0'``                    ``st ``=` `''.join(list1)` `                ``# If target is reached``                ``if``(st ``=``=` `target):``                    ``return` `count` `                ``# If the string formed``                ``# is not one to be avoided``                ``if``(st ``not` `in` `avoid):``                    ``qu.append(st)` `                ``# Add it to the list of``                ``# strings to be avoided``                ``# to prevent visiting``                ``# already visited states``                ``avoid.add(st)` `                ``# Decrease the current``                ``# value by 1 and repeat``                ``# the similar checkings``                ``list1 ``=` `list``(st)``                ``list1[i] ``=` `chr``(``ord``(ch) ``-` `1``)``                ``st ``=` `''.join(list1)` `                ``if``(st[i] < ``'0'``):``                    ``list1 ``=` `list``(st)``                    ``list1[i] ``=` `'9'``                    ``st ``=` `''.join(list1)` `                ``if``(st ``=``=` `target):``                    ``return` `count` `                ``if``(st ``not` `in` `avoid):``                    ``qu.append(st)` `                ``avoid.add(st)` `                ``# Restore the original``                ``# character``                ``list1 ``=` `list``(st)``                ``list1[i] ``=` `ch``                ``st ``=` `''.join(list1)` `    ``return` `-``1` `# Driver code``N ``=` `4``target ``=` `"7531"``blocked ``=` `[``"1543"``, ``"7434"``, ``"7300"``, ``"7321"``, ``"2427"``]``print``(minCircularRotations(target, blocked, N))` `# This code is contributed by Aarti_Rathi`

## C#

 `// C# Program to count the minimum``// number of circular rotations required``// to obtain a given numeric strings``// avoiding a set of blocked strings``using` `System;``using` `System.Collections.Generic;``using` `System.Text;` `public` `class` `Test``{``  ``// Function to reorder elements of arr[] according``  ``// to index[]``  ``static` `int` `minCircularRotations(``string` `target, ``string``[] blocked, ``int` `N)``  ``{``    ``string` `start = ``""``;``    ``for` `(``int` `i = 0; i < N; i++) {``      ``start += ``'0'``;``    ``}` `    ``HashSet < ``string` `> avoid = ``new` `HashSet < ``string` `>();` `    ``for` `(``int` `i=0; i qu = ``new` `Queue<``string``>();``    ``qu.Enqueue(start);` `    ``// Variable to store count of rotations``    ``int` `count = 0;` `    ``// BFS Approach``    ``while` `(qu.Count != 0) {` `      ``count++;` `      ``// Store the current size``      ``// of the queue``      ``int` `size = qu.Count;` `      ``for` `(``int` `j = 0; j < size; j++) {` `        ``string` `st = qu.Peek();``        ``StringBuilder sb = ``new` `StringBuilder(st);``        ``qu.Dequeue();` `        ``// Traverse the string``        ``for` `(``int` `i = 0; i < N; i++) {` `          ``char` `ch = st[i];` `          ``// Increase the``          ``// current character``          ``char` `c=ch;``          ``sb[i] = ++c;``          ``st = sb.ToString();` `          ``// Circular rotation``          ``if` `(st[i] > ``'9'``)``          ``{``            ``sb[i] = ``'0'``;``            ``st = sb.ToString();``          ``}` `          ``// If target is reached``          ``if` `(st == target)``            ``return` `count;` `          ``// If the string formed``          ``// is not one to be avoided``          ``if` `(!avoid.Contains(st))``            ``qu.Enqueue(st);` `          ``// Add it to the list of``          ``// strings to be avoided``          ``// to prevent visiting``          ``// already visited states``          ``avoid.Add(st);` `          ``// Decrease the current``          ``// value by 1 and repeat``          ``// the similar checkings``          ``c=ch;``          ``sb[i] = --c;``          ``st = sb.ToString();` `          ``if` `(st[i] < ``'0'``)``          ``{``            ``sb[i] = ``'9'``;``            ``st = sb.ToString();``          ``}``          ``if` `(st == target)``            ``return` `count;``          ``if` `(!avoid.Contains(st))``            ``qu.Enqueue(st);``          ``avoid.Add(st);` `          ``// Restore the original``          ``// character``          ``sb[i] = ch;``          ``st = sb.ToString();``        ``}``      ``}``    ``}` `    ``return` `-1;``  ``}` `  ``// Driver Code``  ``static` `void` `Main()``  ``{``    ``int` `n=4;``    ``string` `target = ``"7531"``;``    ``string``[] blocked = ``new` `string``[]{ ``"1543"``,``                                    ``"7434"``,``                                    ``"7300"``,``                                    ``"7321"``,``                                    ``"2427"` `};`  `    ``Console.WriteLine(minCircularRotations(target,blocked, n));``  ``}``}` `// This code is contributed by Aditya_Kumar`

## Javascript

 `// JS Program to count the minimum``// number of circular rotations required``// to obtain a given numeric strings``// avoiding a set of blocked strings` `function` `minCircularRotations(``    ``target,``    ``blocked,``    ``N)``{``    ``let start = ``""``;``    ``for` `(``var` `i = 0; i < N; i++) {``        ``start += ``'0'``;``    ``}` `    ``let avoid = ``new` `Set();` `    ``for` `(``var` `i = 0; i < blocked.length; i++)``        ``avoid.add(blocked[i]);` `    ``// If the starting string needs``    ``// to be avoided``    ``if` `(avoid.has(start))``        ``return` `-1;` `    ``// If the final string needs``    ``// to be avoided``    ``if` `(avoid.has(target))``        ``return` `-1;` `    ``let qu = [];``    ``qu.push(start);` `    ``// Variable to store count of rotations``    ``let count = 0;` `    ``// BFS Approach``    ``while` `(qu.length > 0)``    ``{``        ``count++;` `        ``// Store the current size``        ``// of the queue``        ``let size = qu.length;``        ` `        ``for` `(``var` `j = 0; j < size; j++) {``            ` `            ``let st = qu.shift()``            ``st = Array.from(st)` `            ``// Traverse the string``            ``for` `(``var` `i = 0; i < N; i++) {``                ``let ch = parseInt(st[i]);` `                ``// Increase the``                ``// current character``                ``st[i] =  (ch + 1);` `                ``// Circular rotation``                ``if` `(st[i] > 9)``                    ``st[i] = 0;` `                ``// If target is reached``                ``if` `(st.join(``''``) == target)``                    ``return` `count;` `                ``// If the string formed``                ``// is not one to be avoided``                ``if` `(!avoid.has(st.join(``''``)))``                    ``qu.push(st.join(``""``));` `                ``// Add it to the list of``                ``// strings to be avoided``                ``// to prevent visiting``                ``// already visited states``                ``avoid.add(st.join(``""``));` `                ``// Decrease the current``                ``// value by 1 and repeat``                ``// the similar checkings``                ``st[i] =  (parseInt(ch) - 1);` `                ``if` `(st[i] < 0)``                    ``st[i] = 9;``                ` `                ``if` `(st.join(``''``) == target)``                    ``return` `count;``                ``if` `(!avoid.has(st.join(``''``)))``                    ``qu.push(st.join(``''``));``                ``avoid.add(st.join(``''``));` `                ``// Restore the original``                ``// character``                ``st[i] = ch;``            ``}``        ``}``    ``}` `    ``return` `-1;``}` `// Driver code``let N = 4;``let target = ``"7531"``;``let blocked  = [``            ``"1543"``,``            ``"7434"``,``            ``"7300"``,``            ``"7321"``,``            ``"2427"``            ``];` `console.log(minCircularRotations(``                ``target,``                ``blocked, N));``                ` `// This code is contributed by phasing17`

Output:

`12`

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

My Personal Notes arrow_drop_up