Count distinct regular bracket sequences which are not N periodic


In this article, we're going to delve into an intriguing problem from the realm of combinatorics and string processing: "Counting distinct regular bracket sequences which are not N periodic". This problem involves generating distinct valid bracket sequences and then filtering out sequences that are N-periodic. We'll discuss the problem, provide a C++ code implementation of a brute-force approach, and explain a test case.

Understanding the Problem Statement

Given an integer N, the task is to count the distinct regular bracket sequences of length 2N which are not N-periodic. A sequence is N-periodic if it can be represented as a string S repeated M times, where the length of S is N and M > 1.

A regular bracket sequence is a string that can be transformed into a correct arithmetic expression by inserting characters '1' and '+' between the original characters. For example, the sequence "(())" is regular, while ")(" and "(()" are not.

Approach

Due to the complexity of the problem, a direct mathematical solution might not be feasible. Instead, we need to use a programming approach to generate the bracket sequences and count the ones that meet our criteria.

We will use a recursive function to generate all possible bracket sequences of length 2N. While generating the sequences, we'll keep track of two important parameters: the balance of the brackets (the number of open brackets should never be less than the number of closed brackets) and the number of open brackets (should not exceed N).

To filter out N-periodic sequences, we'll check each generated sequence. If the sequence is the repetition of a smaller sequence of length N, we'll exclude it from our count.

C++ Implementation

Here's a brute-force approach in C++ to solve the problem. This approach generates all possible bracket sequences and checks each one to see if it is N-periodic, incrementing the count if it is not. This solution is suitable for small inputs, as it has exponential time complexity and does not scale well for larger inputs.

Example

Here are the programs that implements the above algorithm −

#include <stdio.h>
#include <string.h>

// Function to check if string is N periodic
int isPeriodic(char *s, int N) {
   char sub[N + 1];
   strncpy(sub, s, N);
   sub[N] = '\0';
   for (int i = N; i < strlen(s); i += N) {
      if (strncmp(sub, s + i, N) != 0) return 0;
   }
   return 1;
}

// Function to generate all bracket sequences
void generateBrackets(char *s, int open, int close, int N, int *count) {
   // If sequence is complete
   if (strlen(s) == 2 * N) {
      if (!isPeriodic(s, N)) (*count)++;
      return;
   }
   
   // Add an open bracket if we have some left
   if (open < N) {
      char newS[2 * N + 1];
      strcpy(newS, s);
      strcat(newS, "(");
      generateBrackets(newS, open + 1, close, N, count);
   }
   
   // Add a close bracket if it doesn't make the sequence invalid
   if (close < open) {
      char newS[2 * N + 1];
      strcpy(newS, s);
      strcat(newS, ")");
      generateBrackets(newS, open, close + 1, N, count);
   }
}

int main() {
   int N = 3;
   int count = 0;
   generateBrackets("", 0, 0, N, &count);
   printf("Count of sequences: %d\n", count);
   return 0;
}

Output

Count of sequences: 5
#include <bits/stdc++.h>
using namespace std;

// Function to check if string is N periodic
bool isPeriodic(string s, int N) {
   string sub = s.substr(0, N);
   for (int i = N; i < s.size(); i += N) {
      if (sub != s.substr(i, N)) return false;
   }
   return true;
}

// Function to generate all bracket sequences
void generateBrackets(string s, int open, int close, int N, int &count) {
   // If sequence is complete
   if (s.size() == 2*N) {
      if (!isPeriodic(s, N)) count++;
      return;
   }
   
   // Add an open bracket if we have some left
   if (open < N) generateBrackets(s + "(", open + 1, close, N, count);
   
   // Add a close bracket if it doesn't make the sequence invalid
   if (close < open) generateBrackets(s + ")", open, close + 1, N, count);
}

int main() {
   int N = 3;
   int count = 0;
   generateBrackets("", 0, 0, N, count);
   cout << "Count of sequences: " << count;
   return 0;
}

Output

Count of sequences: 5
public class Main {
   
   // Function to check if a string is N periodic
   static boolean isPeriodic(String s, int N) {
      String sub = s.substring(0, N);
      for (int i = N; i < s.length(); i += N) {
         if (!sub.equals(s.substring(i, i + N))) {
            return false;
         }
      }
      return true;
   }

   // Function to generate all bracket sequences
   static void generateBrackets(String s, int open, int close, int N, int[] count) {
      // If the sequence is complete
      if (s.length() == 2 * N) {
         if (!isPeriodic(s, N)) {
            count[0]++;
         }
         return;
      }

      // Add an open bracket if we have some left
      if (open < N) {
         generateBrackets(s + "(", open + 1, close, N, count);
      }

      // Add a close bracket if it doesn't make the sequence invalid
      if (close < open) {
         generateBrackets(s + ")", open, close + 1, N, count);
      }
   }

   public static void main(String[] args) {
      int N = 3;
      int[] count = {0}; // Using an array to simulate a mutable integer in Java
      generateBrackets("", 0, 0, N, count);
      System.out.println("Count of sequences: " + count[0]);
   }
}

Output

Count of sequences: 5
# Function to check if string is N periodic
def isPeriodic(s, N):
   sub = s[:N]
   for i in range(N, len(s), N):
      if sub != s[i:i+N]:
         return False
   return True

# Function to generate all bracket sequences
def generateBrackets(s, open, close, N, count):
   # If sequence is complete
   if len(s) == 2 * N:
      if not isPeriodic(s, N):
         count[0] += 1
      return
   
   # Add an open bracket if we have some left
   if open < N:
      generateBrackets(s + "(", open + 1, close, N, count)
   
   # Add a close bracket if it doesn't make the sequence invalid
   if close < open:
      generateBrackets(s + ")", open, close + 1, N, count)

N = 3
count = [0]
generateBrackets("", 0, 0, N, count)
print("Count of sequences:", count[0])

Output

Count of sequences: 5

Test Case

Let's consider a test case with N = 3. This code will generate all 5 distinct regular bracket sequences of length 6 that are not 3-periodic: ((())), (()()), (())(), ()(()), ()()().

Conclusion

This article presented a brute-force approach to solve the problem of counting distinct regular bracket sequences that are not N-periodic. While this approach can handle small inputs, it is important to note that the problem has exponential complexity due to the need to generate and check all possible bracket sequences, which makes it unsuitable for large inputs.

Updated on: 16-Oct-2023

170 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements