Find first K characters in Nth term of the Thue-Morse sequence

Given two integers N and K, the task is to print the first K bits of the Nth term of the Thue-Morse sequence. The Thue-Morse sequence is a binary sequence. It starts with a β€œ0” as its first term. And then after the next term is generated by replacing β€œ0” with β€œ01” and β€œ1” with β€œ10”.

Examples:

Input: N = 3, K = 2
Output: 01
Explanation: The 1st term is β€œ0”.
The 2nd term is obtained by replacing β€œ0” with β€œ01” i.e. 2nd term is β€œ01”.
The 3rd term in the sequence is obtained by replacing β€œ0” with β€œ01” and β€œ1” with β€œ10”.
So the 3rd term becomes β€œ0110”. Hence, the 1st 2 characters of the 3rd term is β€œ01”.

Input: N = 4, K = 7
Output: 0110100

 

Approach: The basic approach to solve this problem is to generate the Nth term of the sequence and print the first K characters of that term. This can be done using the algorithm discussed here.

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

Efficient Approach: The above approach can be optimized by observing that the ith term is the concatenation of (i – 1)th term and the inverse of (i – 1)th term where inverse means changing the polarity of all bits in a binary integer. Hence, xth term, Ai[x] = Ai-1[x – 1] if (x < 2i-1), otherwise Ai[x] = !Ai-1[x – 2i-1]. Therefore, using this relation, a recursive function can be created to calculate the value of each bit in the Nth term.

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Recursive function to find the
// value of the kth bit in Nth term
int findDig(int N, long K,  int curr)
{
   
  // Base Case
  if (N == 0) {
    return curr;
  }
 
  // Stores the middle index
  long middle = (long)pow(2, N) / 2;
 
  // If K lies in 1st part
  if (K <= middle) {
 
    // Recursive Call
    return findDig(N - 1, K, curr);
  }
 
  // If K lies in 2nd part
  // having inverted value
  else {
    if (curr == 0) {
      curr = 1;
    }
    else {
      curr = 0;
    }
 
    // Recursive Call
    return findDig(N - 1,
                   K - middle, curr);
  }
}
 
// Function to find first K characters
// in Nth term of Thue-Morse sequence
void firstKTerms(int N, int K)
{
   
  // Loop to iterate all K bits
  for (int i = 1; i <= K; ++i)
  {
 
    // Print value of ith bit
    cout << (findDig(N, i, 0));
  }
}
 
// Driver Code
int main() {
 
  int N = 4;
  int K = 7;
 
  firstKTerms(N, K);
  return 0;
}
 
// This code is contributed by hrithikgarg03188.


Java




// Java Implementation of the above approach
import java.io.*;
import java.util.*;
class GFG {
 
    // Recursive function to find the
    // value of the kth bit in Nth term
    public static int findDig(int N, long K,
                              int curr)
    {
        // Base Case
        if (N == 0) {
            return curr;
        }
 
        // Stores the middle index
        long middle = (long)Math.pow(2, N) / 2;
 
        // If K lies in 1st part
        if (K <= middle) {
 
            // Recursive Call
            return findDig(N - 1, K, curr);
        }
 
        // If K lies in 2nd part
        // having inverted value
        else {
            if (curr == 0) {
                curr = 1;
            }
            else {
                curr = 0;
            }
 
            // Recursive Call
            return findDig(N - 1,
                           K - middle, curr);
        }
    }
 
    // Function to find first K characters
    // in Nth term of Thue-Morse sequence
    public static void firstKTerms(int N, int K)
    {
        // Loop to iterate all K bits
        for (int i = 1; i <= K; ++i) {
 
            // Print value of ith bit
            System.out.print(findDig(N, i, 0));
        }
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int N = 4;
        int K = 7;
 
        firstKTerms(N, K);
    }
}


Python3




# Recursive function to find the
# value of the kth bit in Nth term
def findDig(N, K, curr):
 
    # Base Case
    if (N == 0):
        return curr
 
    # Stores the middle index
    middle = pow(2, N) // 2
 
    # If K lies in 1st part
    if (K <= middle):
 
        # Recursive Call
        return findDig(N - 1, K, curr)
 
    # If K lies in 2nd part
    # having inverted value
    else:
        if (curr == 0):
            curr = 1
 
        else:
            curr = 0
 
        # Recursive Call
        return findDig(N - 1, K - middle, curr)
 
# Function to find first K characters
# in Nth term of Thue-Morse sequence
def firstKTerms(N, K):
 
    # Loop to iterate all K bits
    for i in range(1, K+1):
 
     # Print value of ith bit
        print(findDig(N, i, 0), end="")
 
# Driver Code
if __name__ == "__main__":
 
    N = 4
    K = 7
 
    firstKTerms(N, K)
 
    # This code is contributed by rakeshsahni


C#




// C# Implementation of the above approach
using System;
class GFG
{
 
  // Recursive function to find the
  // value of the kth bit in Nth term
  public static int findDig(int N, long K, int curr)
  {
     
    // Base Case
    if (N == 0)
    {
      return curr;
    }
 
    // Stores the middle index
    long middle = (long)Math.Pow(2, N) / 2;
 
    // If K lies in 1st part
    if (K <= middle)
    {
 
      // Recursive Call
      return findDig(N - 1, K, curr);
    }
 
    // If K lies in 2nd part
    // having inverted value
    else
    {
      if (curr == 0)
      {
        curr = 1;
      }
      else
      {
        curr = 0;
      }
 
      // Recursive Call
      return findDig(N - 1,
                     K - middle, curr);
    }
  }
 
  // Function to find first K characters
  // in Nth term of Thue-Morse sequence
  public static void firstKTerms(int N, int K)
  {
     
    // Loop to iterate all K bits
    for (int i = 1; i <= K; ++i)
    {
 
      // Print value of ith bit
      Console.Write(findDig(N, i, 0));
    }
  }
 
  // Driver Code
  public static void Main()
  {
    int N = 4;
    int K = 7;
 
    firstKTerms(N, K);
  }
}
 
// This code is contributed by saurabh_jaiswal.


Javascript




<script>
       // JavaScript code for the above approach
 
       // Recursive function to find the
       // value of the kth bit in Nth term
       function findDig(N, K, curr)
       {
           // Base Case
           if (N == 0) {
               return curr;
           }
 
           // Stores the middle index
           let middle = Math.floor(Math.pow(2, N) / 2);
 
           // If K lies in 1st part
           if (K <= middle) {
 
               // Recursive Call
               return findDig(N - 1, K, curr);
           }
 
           // If K lies in 2nd part
           // having inverted value
           else {
               if (curr == 0) {
                   curr = 1;
               }
               else {
                   curr = 0;
               }
 
               // Recursive Call
               return findDig(N - 1,
                   K - middle, curr);
           }
       }
 
       // Function to find first K characters
       // in Nth term of Thue-Morse sequence
       function firstKTerms(N, K) {
           // Loop to iterate all K bits
           for (let i = 1; i <= K; ++i) {
 
               // Print value of ith bit
               document.write(findDig(N, i, 0));
           }
       }
 
       // Driver Code
       let N = 4;
       let K = 7;
 
       firstKTerms(N, K);
 
        // This code is contributed by Potta Lokesh
   </script>


 
 

Output

0110100

 

Time Complexity: O(K*log N)
Auxiliary Space: O(1)