# Miscelleneous Problems 15 ## Bits and Bytes ### Problem Statement You are given a binary string **S**. You process it through a series of operations starting from the left where: 1) In the first operation, you remove the first bit of the number and append it to the right. 2) In the second operation, you remove the first 2 bits of the processed string one by one and append them to the right. 3) In the third operation, you now remove the first 3 bits of the new string one by one and append them to the right. 4) In the ith operation, you remove the first i bits of the new string one by one and append them to the right. You have to find the minimum number of operations it takes to get back the original string. Number of operations cannot be 0. **Constraints:** ``` 1 <= length of S <= 10^5 ``` **Input:** ``` S : Binary string ``` **Output:** ``` Minimum number of operations to get back the original string. ``` **Example:** ``` Input: S: 111 Output: 1 In the first operation, the leftmost bit (1) gets appended to the end of the string, and you get the same string as the original, hence answer is 1. Input: S: 101 Output: 2 In the first operation, the leftmost bit (1) gets appended to the end of the string, and you get the string 011. In the second operation, the 2 leftmost bits get appended to the end (011 => 110 => 101), we get the same string as the original, hence answer is 2. ``` ### Brute Force - For every i from 1 to $\infty$, We can rotate the string by i digits and check if the new string is same as the original string. - Time Complexity, We may run into an infinity loop. - Suppose we can be sure that we will get our result in $O(n)$. For every i we will need $O(n)$ time. So, the total time will be $O(n^2)$. ### Hints - We can see that by $i^{th}$ operation we will have rotated $\frac{i*(i+1)}{2}$ times. Let's call this $T_i$. - If for some $i$, $T_i$ is divisible by $len(s)$, we can say we will definetely get our string back. - For $i = 2* len(s)-1$, $T_i$ will obviously be divisible by $len(s)$. - So, we can run a loop from $1$ to $2* len(s) -1$ on $i$. And check if $T_i$ will be divisible by $len(s)$ or not. - This will run in $O(n)$ time. - Will it give the smallest such i? - The string may have a pattern repeating over and over again. For example : $s=101101101$, answer will be $2$. - Can we find the length of the shortest repeating sequence? We can use KMP algorithm to do that. - What will be the lps of above string? Answer: $LPS = [001123456]$. - If $len(s)-LPS[len(s)-1]$ divides $len(s)$, $len(s)-LPS[len(s)-1]$ is the length of the repeating sequence. - Now, we have to match $T_i$ with length of repeating pattern if there is a repeating pattern. ### Code ```C++ typedef long long ll; ll minLEN(string s,ll lps[]){ lps[0]=0; ll len=0; ll p=1; while(p &B, string C) { ll n,use; n=A;ll arr[n+1]; // cin>>use; for(ll i=1;i<=n;i++) { arr[i]=B[i-1]; } string s,ans; s=C; ll pref[n]; pref[1]=s[0]-'0'; for(ll i=2;i buffer){ k-=buffer; continue; } if(i == f) return to_string(i) + function_two(rem, k); return to_string(i) + function_two(to_string(9*(temp/10)), k); } } /* function_one(n,k) computes the first digit of the kth required number. function_one and function_two are separate as 1st digit can't be zero whereas rest of the digits can be zero. */ string function_one(string s, int k){ int l = s.size(); //length of the number int f = s[0]-'0'; //first digit of the number int temp = stoi(string(l,'1')); // 1111111... l digits //Base case, only 1 digit number if(l==1) return to_string(k); //Utility string, used below in the for loop string rem = s.substr(1); //find the number of numbers say //num starting from x (x <= i). //if k > num, first digit is not i, //else first digit is i. //Note that i here starts from 1. for(int i=1; i<10; i++){ //Here we calculate the number of //numbers starting from i. //There will be multiple cases //to handle which becomes clear //after a little thinking. if(i == f) temp/=10; int buffer = temp; if(i == f) buffer += stoi(rem) + 1; if(k > buffer){ k-=buffer; continue; } if(i == f) return to_string(i) + function_two(rem, k); return to_string(i) + function_two(to_string(9*(temp/10)), k); } } vector Solution::solve(int A,const vector &B){ string str = to_string(A); int m = B.size(); vector ans(m); //function_one(n,k) give kth //number in the sorted order of strings ["1", "2", ..., "n"] for(int i=0; i