Table of Contents

## Problem Statement

“ Boolean Parenthesization Problem ” states that we are given a sequence of true and false, and some boolean operators( AND, OR, XOR) in between them. We need to find the number of ways to parenthesize the given sequence such that the entire sequence results in TRUE. In the given Boolean Parenthesization problem, we will refer True using “T” and False using “F”.

## Example

Symbol Sequence = {T,T} Operator Sequence = {|}

1

Explanation: This is a trivial example, which is shown here just to get you started with what the problem is all about. So, there is just a single way of parenthesizing the sequence.which is (Y | T).

Symbol Sequence = {T, F, F} Operator Sequence = {^, |}

2

Explanation: Here we can parenthesize our given symbol sequence is two ways. The two ways are (T ^ (F | F) ) and ((T ^ F) | F).

## Approach for Boolean Parenthesization Problem

“Boolean Parenthesization Problem” states that we need to find the number of ways to parenthesize the symbol sequence using given operators such that the sequence evaluates it into true. So, for this, we will create two 2D arrays one for storing the number of ways to parenthesize a segment of sequence from i to j resulting in true. Similarly, another 2D array denotes the same but the segment results in false. While solving we need to solve the subproblems multiple times. So we try to utilize Dynamic Programming for solving this problem.

The problem is similar to the Matrix Chain Multiplication Problem, where first we solve smaller subproblems(i,e, smaller segments). And combining the result, we find the answer to the initial problem. Since we are using a Dynamic Programming approach, we must have some base cases, The base cases here are segments of length = 1. So, we will fill the T matrix and F matrix accordingly. When we solve for larger subproblems by combining smaller ones. We will follow certain rules which are the following.

## Code

### C++ code for Boolean Parenthesization Problem

#include<bits/stdc++.h> using namespace std; int waysToParenthesize(string symbolSequence, string operatorSequence) { int n = symbolSequence.size(); int T[n][n], F[n][n]; memset(T, 0 ,sizeof T); memset(F, 0, sizeof F); //base case for(int i=0;i<n;i++) if(symbolSequence[i] == 'T') T[i][i] = 1, F[i][i] = 0; else T[i][i] = 0, F[i][i] = 1; // Now solve the subproblems in bottom up manner for(int len=2;len<=n;len++) { for(int i=0;i<=n-len;i++) { int j = i+len-1; T[i][j] = F[i][j] = 0; //Index of placing brackets for(int k=i;k<j;k++) { int waysik = T[i][k] + F[i][k]; int wayskj = T[k+1][j] + F[k+1][j]; if(operatorSequence[k] == '&') { T[i][j] += T[i][k]*T[k+1][j]; F[i][j] += (waysik*wayskj - T[i][k]*T[k+1][j]); } else if(operatorSequence[k] == '|') { F[i][j] += F[i][k]*F[k+1][j]; T[i][j] += (waysik*wayskj - F[i][k]*F[k+1][j]); } else if(operatorSequence[k] == '^') { T[i][j] += F[i][k]*T[k+1][j] + T[i][k]*F[k+1][j]; F[i][j] += T[i][k]*T[k+1][j] + F[i][k]*F[k+1][j]; } } } } return T[0][n-1]; } int main() { string symbolSequence=""; string operatorSequence=""; cin>>symbolSequence>>operatorSequence; cout<<waysToParenthesize(symbolSequence, operatorSequence)<<endl; }

TTFT |&^

4

### Java Code for Boolean Parenthesization Problem

import java.util.*; class Main{ static int waysToParenthesize(String symbolSequence, String operatorSequence) { int n = symbolSequence.length(); int T[][] = new int[n][n]; int F[][] = new int[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ T[i][j] = 0; F[i][j] = 0; } } //base case for(int i=0;i<n;i++){ if(symbolSequence.charAt(i) == 'T'){ T[i][i] = 1; F[i][i] = 0; } else{ T[i][i] = 0; F[i][i] = 1; } } // Now solve the subproblems in bottom up manner for(int len=2;len<=n;len++) { for(int i=0;i<=n-len;i++) { int j = i+len-1; T[i][j] = 0; F[i][j] = 0; //Index of placing brackets for(int k=i;k<j;k++) { int waysik = T[i][k] + F[i][k]; int wayskj = T[k+1][j] + F[k+1][j]; if(operatorSequence.charAt(k) == '&') { T[i][j] += T[i][k]*T[k+1][j]; F[i][j] += (waysik*wayskj - T[i][k]*T[k+1][j]); } else if(operatorSequence.charAt(k) == '|') { F[i][j] += F[i][k]*F[k+1][j]; T[i][j] += (waysik*wayskj - F[i][k]*F[k+1][j]); } else if(operatorSequence.charAt(k) == '^') { T[i][j] += F[i][k]*T[k+1][j] + T[i][k]*F[k+1][j]; F[i][j] += T[i][k]*T[k+1][j] + F[i][k]*F[k+1][j]; } } } } return T[0][n-1]; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); String symbolSequence = sc.next(); String operatorSequence = sc.next(); int ans = waysToParenthesize(symbolSequence, operatorSequence); System.out.println(ans); } }

TTFT |&^

4

## Complexity Analysis

### Time Complexity: O(N^3)

Similar to what we see in the Matrix Chain Multiplication problem. Since the problem is quite similar to that one, the time complexity is also the same.

### Space Complexity: O(N^2)

Here we had used 2 2D Dp arrays one for storing the number of ways to parenthesize a sub-segment such that it results in true. And the other for False. Thus giving us a polynomial space complexity of O(N^2).