Given a machine in the formal language of N states and M pairs of output combinations in the form of 2D array arr[][]. Each row(say r) of arr[][] denotes the nodes from ‘A’ to ‘Z’ and each pair of a column(say (a, b)) denotes the change of state of node r to node a via state b. The task is to find the compatible and non-compatible edges of the formal language.
Note: Edge(A, B) is said to be compatible as all the next state and output are either equal or unspecified in A, B corresponding to each column.
Example:
Input: N = 6, M = 4,
arr[][] = { { ‘-‘, ‘-‘, ‘C’, ‘1’, ‘E’, ‘1’, ‘B’, ‘1’ },
{ ‘E’, ‘0’, ‘-‘, ‘-‘, ‘-‘, ‘-‘, ‘-‘, ‘-‘ },
{ ‘F’, ‘0’, ‘F’, ‘1’, ‘-‘, ‘-‘, ‘-‘, ‘-‘ },
{ ‘-‘, ‘-‘, ‘-‘, ‘-‘, ‘B’, ‘1’, ‘-‘, ‘-‘ },
{ ‘-‘, ‘-‘, ‘F’, ‘0’, ‘A’, ‘0’, ‘D’, ‘1’ },
{ ‘C’, ‘0’, ‘-‘, ‘-‘, ‘B’, ‘0’, ‘C’, ‘1’ } }
Output:
Not Compatible Edges
(A, E) (A, F) (B, F) (C, E) (D, E) (D, F)
Compatible Edges
(A, B)(A, C)(A, D)(B, C)(B, D)(B, E)(C, D)(C, F)(E, F)
Input: N = 4, M = 4,
arr[][] = { { ‘-‘, ‘-‘, ‘C’, ‘1’, ‘E’, ‘1’, ‘B’, ‘1’ },
{ ‘-‘, ‘-‘, ‘-‘, ‘-‘, ‘B’, ‘1’, ‘-‘, ‘-‘ },
{ ‘-‘, ‘-‘, ‘F’, ‘0’, ‘A’, ‘0’, ‘D’, ‘1’ },
{ ‘C’, ‘0’, ‘-‘, ‘-‘, ‘B’, ‘0’, ‘C’, ‘1’ } }
Output:
Not Compatible Edges
(A, C) (A, D) (B, C) (B, D)
Compatible Edges
(A, B)(C, D)
Approach:
- For all the possible combinations(say (a,b)) of the nodes, check if there is any possible path present in the formal language through any number of states as:
- If state via Node a is empty, then check for the next pair of nodes.
- If the current traversed state(say Node b) via Node a is not empty and if the output state via Node a to Node b is not the same then recursively check for a path from Node a to Node b.
- If the output state is the same, then it has a direct edge between Node a and Node b.
- If the path is found between any pair of nodes, then the pair of nodes is a part of a compatible node.
- Store the above pair of compatible nodes in a matrix Mat[][].
- Traverse the Mat[][] for all the possible pairs, and if that pair is present in Mat[][] then print it as a Compatible Nodes Else it is Not Compatible node.
Below is the implementation of the above approach:
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std;
const int M = 8;
// Function to find the compatible and // non-compatible for a given formal language void findEdges( char arr[][M], int n, int m)
{ // To store the compatible edges
char mat[1000][1000] = { 'x' };
// Loop over every pair of nodes in the
// given formal language
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
// Traverse through the output
// column and compare it between
// each set of pairs of nodes
for ( int k = 0; k < 2 * m; k += 2) {
// If the output is not
// specified then leave the
// edge unprocessed
if (arr[i][k + 1] == '-'
|| arr[j][k + 1] == '-' ) {
continue ;
}
// If the output of states
// doesn't match then not
// compatible.
if (arr[i][k + 1] != arr[j][k + 1]) {
// Mark the not compatible
// edges in the matrix with
// character 'v'
mat[i][j] = 'v' ;
mat[j][i] = 'v' ;
break ;
}
}
}
}
int nn = n;
// Loop over all node to find other non
// compatible edges
while (nn--) {
// Loop over every pair of nodes in
// the given formal language
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
int k;
for (k = 0; k < m; k += 2) {
// If the output is
// not specified then
// leave edge unprocessed
if (arr[i][k + 1] == '-'
|| arr[j][k + 1] == '-' ) {
continue ;
}
// If output is not equal
// then break as non-compatible
if (arr[i][k + 1] != arr[j][k + 1]) {
break ;
}
}
if (k < m) {
continue ;
}
for (k = 0; k < m; k += 2) {
// If next states are unspecified
// then continue
if (arr[i][k] == '-'
|| arr[j][k] == '-' ) {
continue ;
}
// If the states are not equal
if (arr[i][k] != arr[j][k]) {
int x = arr[i][k] - 'A' ;
int y = arr[j][k] - 'A' ;
// If the dependent edge
// is not compatible then
// this edge is also not
// compatible
if (mat[x][y] == 'v' ) {
mat[i][j] = 'v' ;
mat[j][i] = 'v' ;
break ;
}
}
}
}
}
}
// Output all Non-compatible Edges
printf ( "Not Compatible Edges \n" );
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
if (mat[i][j] == 'v' ) {
printf ( "(%c, %c) " , i + 65, j + 65);
}
}
}
printf ( "\n" );
// Output all Compatible Edges
printf ( "Compatible Edges \n" );
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
if (mat[i][j] != 'v' ) {
printf ( "(%c, %c)" , i + 65, j + 65);
}
}
}
} // Driver Code int main()
{ int n = 6, m = 4;
char arr[][8] = { { '-' , '-' , 'C' , '1' , 'E' , '1' , 'B' , '1' },
{ 'E' , '0' , '-' , '-' , '-' , '-' , '-' , '-' },
{ 'F' , '0' , 'F' , '1' , '-' , '-' , '-' , '-' },
{ '-' , '-' , '-' , '-' , 'B' , '1' , '-' , '-' },
{ '-' , '-' , 'F' , '0' , 'A' , '0' , 'D' , '1' },
{ 'C' , '0' , '-' , '-' , 'B' , '0' , 'C' , '1' } };
findEdges(arr, n, m);
return 0;
} |
// Java implementation of the above approach import java.util.*;
class GFG{
static int M = 8 ;
// Function to find the compatible and // non-compatible for a given formal language static void findEdges( char arr[][], int n, int m)
{ // To store the compatible edges
char [][]mat = new char [ 1000 ][ 1000 ];
// Loop over every pair of nodes in the
// given formal language
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
// Traverse through the output
// column and compare it between
// each set of pairs of nodes
for ( int k = 0 ; k < 2 * m; k += 2 )
{
// If the output is not
// specified then leave the
// edge unprocessed
if (arr[i][k + 1 ] == '-' ||
arr[j][k + 1 ] == '-' )
{
continue ;
}
// If the output of states
// doesn't match then not
// compatible.
if (arr[i][k + 1 ] != arr[j][k + 1 ])
{
// Mark the not compatible
// edges in the matrix with
// character 'v'
mat[i][j] = 'v' ;
mat[j][i] = 'v' ;
break ;
}
}
}
}
int nn = n;
// Loop over all node to find other non
// compatible edges
while (nn-- > 0 )
{
// Loop over every pair of nodes in
// the given formal language
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
int k;
for (k = 0 ; k < m; k += 2 )
{
// If the output is
// not specified then
// leave edge unprocessed
if (arr[i][k + 1 ] == '-' ||
arr[j][k + 1 ] == '-' )
{
continue ;
}
// If output is not equal
// then break as non-compatible
if (arr[i][k + 1 ] !=
arr[j][k + 1 ])
{
break ;
}
}
if (k < m)
{
continue ;
}
for (k = 0 ; k < m; k += 2 )
{
// If next states are unspecified
// then continue
if (arr[i][k] == '-' ||
arr[j][k] == '-' )
{
continue ;
}
// If the states are not equal
if (arr[i][k] != arr[j][k])
{
int x = arr[i][k] - 'A' ;
int y = arr[j][k] - 'A' ;
// If the dependent edge
// is not compatible then
// this edge is also not
// compatible
if (mat[x][y] == 'v' )
{
mat[i][j] = 'v' ;
mat[j][i] = 'v' ;
break ;
}
}
}
}
}
}
// Output all Non-compatible Edges
System.out.printf( "Not Compatible Edges \n" );
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
if (mat[i][j] == 'v' )
{
System.out.printf( "(%c, %c) " ,
i + 65 , j + 65 );
}
}
}
System.out.printf( "\n" );
// Output all Compatible Edges
System.out.printf( "Compatible Edges \n" );
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
if (mat[i][j] != 'v' )
{
System.out.printf( "(%c, %c)" ,
i + 65 , j + 65 );
}
}
}
} // Driver Code public static void main(String[] args)
{ int n = 6 , m = 4 ;
char arr[][] = { { '-' , '-' , 'C' , '1' ,
'E' , '1' , 'B' , '1' },
{ 'E' , '0' , '-' , '-' ,
'-' , '-' , '-' , '-' },
{ 'F' , '0' , 'F' , '1' ,
'-' , '-' , '-' , '-' },
{ '-' , '-' , '-' , '-' ,
'B' , '1' , '-' , '-' },
{ '-' , '-' , 'F' , '0' ,
'A' , '0' , 'D' , '1' },
{ 'C' , '0' , '-' , '-' ,
'B' , '0' , 'C' , '1' } };
findEdges(arr, n, m);
} } // This code is contributed by Amit Katiyar |
// C# implementation of // the above approach using System;
class GFG{
static int M = 8;
// Function to find the //compatible and non-compatible // for a given formal language static void findEdges( char [,]arr,
int n, int m)
{ // To store the compatible edges
char [,]mat = new char [1000, 1000];
// Loop over every pair of
// nodes in the given
// formal language
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
// Traverse through the output
// column and compare it between
// each set of pairs of nodes
for ( int k = 0; k < 2 * m; k += 2)
{
// If the output is not
// specified then leave the
// edge unprocessed
if (arr[i, k + 1] == '-' ||
arr[j, k + 1] == '-' )
{
continue ;
}
// If the output of states
// doesn't match then not
// compatible.
if (arr[i, k + 1] != arr[j, k + 1])
{
// Mark the not compatible
// edges in the matrix with
// character 'v'
mat[i, j] = 'v' ;
mat[j, i] = 'v' ;
break ;
}
}
}
}
int nn = n;
// Loop over all node to find other non
// compatible edges
while (nn-- > 0)
{
// Loop over every pair of nodes in
// the given formal language
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
int k;
for (k = 0; k < m; k += 2)
{
// If the output is
// not specified then
// leave edge unprocessed
if (arr[i, k + 1] == '-' ||
arr[j, k + 1] == '-' )
{
continue ;
}
// If output is not equal
// then break as non-compatible
if (arr[i, k + 1] !=
arr[j, k + 1])
{
break ;
}
}
if (k < m)
{
continue ;
}
for (k = 0; k < m; k += 2)
{
// If next states are unspecified
// then continue
if (arr[i, k] == '-' ||
arr[j, k] == '-' )
{
continue ;
}
// If the states are not equal
if (arr[i, k] != arr[j, k])
{
int x = arr[i, k] - 'A' ;
int y = arr[j, k] - 'A' ;
// If the dependent edge
// is not compatible then
// this edge is also not
// compatible
if (mat[x, y] == 'v' )
{
mat[i, j] = 'v' ;
mat[j, i] = 'v' ;
break ;
}
}
}
}
}
}
// Output all Non-compatible Edges
Console.Write( "Not Compatible Edges \n" );
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if (mat[i, j] == 'v' )
{
Console.Write( "({0}, {1}) " ,
( char )(i + 65),
( char )(j + 65));
}
}
}
Console.Write( "\n" );
// Output all Compatible Edges
Console.Write( "Compatible Edges \n" );
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if (mat[i, j] != 'v' )
{
Console.Write( "({0}, {1})" ,
( char )(i + 65),
( char )(j + 65));
}
}
}
} // Driver Code public static void Main(String[] args)
{ int n = 6, m = 4;
char [,]arr = {{ '-' , '-' , 'C' , '1' ,
'E' , '1' , 'B' , '1' },
{ 'E' , '0' , '-' , '-' ,
'-' , '-' , '-' , '-' },
{ 'F' , '0' , 'F' , '1' ,
'-' , '-' , '-' , '-' },
{ '-' , '-' , '-' , '-' ,
'B' , '1' , '-' , '-' },
{ '-' , '-' , 'F' , '0' ,
'A' , '0' , 'D' , '1' },
{ 'C' , '0' , '-' , '-' ,
'B' , '0' , 'C' , '1' }};
findEdges(arr, n, m);
} } // This code is contributed by 29AjayKumar |
<script> // javascript implementation of the above approach const M = 8; // Function to find the compatible and // non-compatible for a given formal language function findEdges(arr, n, m)
{ // To store the compatible edges
let mat = new Array(1000);
for (let i = 0; i < 1000; i++){
mat[i] = new Array(1000).fill( 'x' );
}
// Loop over every pair of nodes in the
// given formal language
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
// Traverse through the output
// column and compare it between
// each set of pairs of nodes
for (let k = 0; k < 2 * m; k += 2) {
// If the output is not
// specified then leave the
// edge unprocessed
if (arr[i][k + 1] == '-' || arr[j][k + 1] == '-' ) {
continue ;
}
// If the output of states
// doesn't match then not
// compatible.
if (arr[i][k + 1] != arr[j][k + 1]) {
// Mark the not compatible
// edges in the matrix with
// character 'v'
mat[i][j] = 'v ';
mat[j][i] = ' v ';
break;
}
}
}
}
let nn = n;
// Loop over all node to find other non
// compatible edges
while (nn--) {
// Loop over every pair of nodes in
// the given formal language
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
let k = 0;
for (k = 0; k < m; k += 2) {
// If the output is
// not specified then
// leave edge unprocessed
if (arr[i][k + 1] == ' - ' || arr[j][k + 1] == ' - ') {
continue;
}
// If output is not equal
// then break as non-compatible
if (arr[i][k + 1] != arr[j][k + 1]) {
break;
}
}
if (k < m) {
continue;
}
for (k = 0; k < m; k += 2) {
// If next states are unspecified
// then continue
if (arr[i][k] == ' - ' || arr[j][k] == ' - ') {
continue;
}
// If the states are not equal
if (arr[i][k] != arr[j][k]) {
let x = arr[i][k].charCodeAt(0) - 65;
let y = arr[j][k].charCodeAt(0) - 65;
// If the dependent edge
// is not compatible then
// this edge is also not
// compatible
if (mat[x][y] == ' v ') {
mat[i][j] = ' v ';
mat[j][i] = ' v ';
break;
}
}
}
}
}
}
// Output all Non-compatible Edges
console.log("Not Compatible Edges ");
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if (mat[i][j] == ' v ') {
document.write("(", String.fromCharCode(i + 65),",", String.fromCharCode(j + 65), ") ");
}
}
}
console.log();
// Output all Compatible Edges
console.log("Compatible Edges ");
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if (mat[i][j] != ' v ') {
document.write("(", String.fromCharCode(i + 65),",", String.fromCharCode(j + 65), ") ");
}
}
}
} // Driver Code let n = 6, m = 4; let arr = [ [ ' - ', ' - ', ' C ', ' 1 ', ' E ', ' 1 ', ' B ', ' 1 ' ],
[ ' E ', ' 0 ', ' - ', ' - ', ' - ', ' - ', ' - ', ' - ' ],
[ ' F ', ' 0 ', ' F ', ' 1 ', ' - ', ' - ', ' - ', ' - ' ],
[ ' - ', ' - ', ' - ', ' - ', ' B ', ' 1 ', ' - ', ' - ' ],
[ ' - ', ' - ', ' F ', ' 0 ', ' A ', ' 0 ', ' D ', ' 1 ' ],
[ ' C ', ' 0 ', ' - ', ' - ', ' B ', ' 0 ', ' C ', ' 1' ] ];
findEdges(arr, n, m); // The code is contributed by Gautam goel. </script> |
# Python implementation of the above approach M = 8
# Function to find the compatible and # non-compatible for a given formal language def findEdges(arr, n, m):
# To store the compatible edges
mat = [[ 0 for i in range ( 1000 )]
for j in range ( 1000 )]
# Loop over every pair of nodes in the
# given formal language
for i in range (n):
for j in range (i + 1 , n):
# Traverse through the output
# column and compare it between
# each set of pairs of nodes
for k in range ( 0 , 2 * m, 2 ):
# If the output is not
# specified then leave the
# edge unprocessed
if (arr[i][k + 1 ] = = '-' or
arr[j][k + 1 ] = = '-' ):
continue
# If the output of states
# doesn't match then not
# compatible.
if (arr[i][k + 1 ] ! = arr[j][k + 1 ]):
# Mark the not compatible
# edges in the matrix with
# character 'v'
mat[i][j] = 'v'
mat[j][i] = 'v'
break
nn = n
# Loop over all node to find other non
# compatible edges
while (nn > 0 ):
nn - = 1
# Loop over every pair of nodes in
# the given formal language
for i in range (n):
for j in range (i + 1 , n):
k = 0
for k in range (m):
# If the output is
# not specified then
# leave edge unprocessed
if (arr[i][k + 1 ] = = '-' or
arr[j][k + 1 ] = = '-' ):
continue
# If output is not equal
# then break as non-compatible
if (arr[i][k + 1 ] ! = arr[j][k + 1 ]):
break
if (k < m):
continue
for k in range (m):
# If next states are unspecified
# then continue
if (arr[i][k] = = '-' or
arr[j][k] = = '-' ):
continue
# If the states are not equal
if (arr[i][k] ! = arr[j][k]):
x = ord (arr[i][k]) - ord ( 'A' )
y = ord (arr[j][k]) - ord ( 'A' )
# If the dependent edge
# is not compatible then
# this edge is also not
# compatible
if (mat[x][y] = = 'v' ):
mat[i][j] = 'v'
mat[j][i] = 'v'
break
# Output all Non-compatible Edges
print ( "Not Compatible Edges" )
for i in range (n):
for j in range (i + 1 , n):
if (mat[i][j] = = 'v' ):
print ( "({}, {})" . format (
chr (i + 65 ),
chr (j + 65 )))
# Output all Compatible Edges
print ( "Compatible Edges" )
for i in range (n):
for j in range (i + 1 , n):
if (mat[i][j] ! = 'v' ):
print ( "({}, {})" . format (
chr (i + 65 ),
chr (j + 65 )))
# Driver Code if __name__ = = "__main__" :
n = 6
m = 4
arr = [ [ '-' , '-' , 'C' , '1' ,
'E' , '1' , 'B' , '1' ],
[ 'E' , '0' , '-' , '-' ,
'-' , '-' , '-' , '-' ],
[ 'F' , '0' , 'F' , '1' ,
'-' , '-' , '-' , '-' ],
[ '-' , '-' , '-' , '-' ,
'B' , '1' , '-' , '-' ],
[ '-' , '-' , 'F' , '0' ,
'A' , '0' , 'D' , '1' ],
[ 'C' , '0' , '-' , '-' ,
'B' , '0' , 'C' , '1' ]]
findEdges(arr, n, m)
|
Not Compatible Edges (A, E) (A, F) (B, F) (C, E) (D, E) (D, F) Compatible Edges (A, B)(A, C)(A, D)(B, C)(B, D)(B, E)(C, D)(C, F)(E, F)
Time Complexity: O(M*N3), where N is the number of states and M is the Output for every state.