#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
char NFA_FILE[ MAX_LEN] ;
char buffer[ MAX_LEN] ;
int zz = 0 ;
// Structure to store DFA states and their
// status ( i.e new entry or already present)
struct DFA {
char * states;
int count;
} dfa;
int last_index = 0 ;
FILE * fp;
int symbols;
/* reset the hash map*/
void reset( int ar[ ] , int size) {
int i;
// reset all the values of
// the mapping array to zero
for ( i = 0 ; i < size; i++ ) {
ar[ i] = 0 ;
}
}
// Check which States are present in the e-closure
/* map the states of NFA to a hash set*/
void check( int ar[ ] , char S[ ] ) {
int i, j;
// To parse the individual states of NFA
for ( i = 0 ; i < len; i++ ) {
// Set hash map for the position
// of the states which is found
j = ( ( int ) ( S[ i] ) - 65 ) ;
ar[ j] ++;
}
}
// To find new Closure States
void state( int ar[ ] , int size, char S[ ] ) {
int j, k = 0 ;
// Combine multiple states of NFA
// to create new states of DFA
for ( j = 0 ; j < size; j++ ) {
if ( ar[ j] != 0 )
S[ k++ ] = ( char ) ( 65 + j) ;
}
// mark the end of the state
S[ k] = '\0 ' ;
}
// To pick the next closure from closure set
int closure( int ar[ ] , int size) {
int i;
// check new closure is present or not
for ( i = 0 ; i < size; i++ ) {
if ( ar[ i] == 1 )
return i;
}
return ( 100 ) ;
}
// Check new DFA states can be
// entered in DFA table or not
int indexing( struct DFA * dfa) {
int i;
for ( i = 0 ; i < last_index; i++ ) {
if ( dfa[ i] .count == 0 )
return 1 ;
}
return - 1 ;
}
/* To Display epsilon closure*/
void Display_closure( int states, int closure_ar[ ] ,
char * closure_table[ ] ,
char * NFA_TABLE[ ] [ symbols + 1 ] ,
char * DFA_TABLE[ ] [ symbols] ) {
int i;
for ( i = 0 ; i < states; i++ ) {
reset( closure_ar, states) ;
closure_ar[ i] = 2 ;
// to neglect blank entry
if ( strcmp ( & NFA_TABLE
[ i
] [ symbols
] , "-" ) != 0 ) {
// copy the NFA transition state to buffer
strcpy ( buffer
, & NFA_TABLE
[ i
] [ symbols
] ) ; check( closure_ar, buffer) ;
int z = closure( closure_ar, states) ;
// till closure get completely saturated
while ( z != 100 )
{
if ( strcmp ( & NFA_TABLE
[ z
] [ symbols
] , "-" ) != 0 ) { strcpy ( buffer
, & NFA_TABLE
[ z
] [ symbols
] ) ;
// call the check function
check( closure_ar, buffer) ;
}
closure_ar[ z] ++;
z = closure( closure_ar, states) ;
}
}
// print the e closure for every states of NFA
printf ( "\n e-Closure (%c) :\t " , ( char ) ( 65 + i
) ) ;
bzero( ( void * ) buffer, MAX_LEN) ;
state( closure_ar, states, buffer) ;
strcpy ( & closure_table
[ i
] , buffer
) ; printf ( "%s\n " , & closure_table
[ i
] ) ; }
}
/* To check New States in DFA */
int new_states( struct DFA * dfa, char S[ ] ) {
int i;
// To check the current state is already
// being used as a DFA state or not in
// DFA transition table
for ( i = 0 ; i < last_index; i++ ) {
if ( strcmp ( & dfa
[ i
] .
states , S
) == 0 ) return 0 ;
}
// push the new
strcpy ( & dfa
[ last_index
++ ] .
states , S
) ;
// set the count for new states entered
// to zero
dfa[ last_index - 1 ] .count = 0 ;
return 1 ;
}
// Transition function from NFA to DFA
// (generally union of closure operation )
void trans( char S[ ] , int M, char * clsr_t[ ] , int st,
char * NFT[ ] [ symbols + 1 ] , char TB[ ] ) {
int i, j, k, g;
int arr[ st] ;
int sz;
reset( arr, st) ;
char temp[ MAX_LEN] , temp2[ MAX_LEN] ;
char * buff;
// Transition function from NFA to DFA
for ( i = 0 ; i < len; i++ ) {
j = ( ( int ) ( S[ i] - 65 ) ) ;
g = 0 ;
while ( g < sz) {
k = ( ( int ) ( temp[ g] - 65 ) ) ;
check( arr, temp2) ;
g++;
}
}
}
bzero( ( void * ) temp, MAX_LEN) ;
state( arr, st, temp) ;
if ( temp[ 0 ] != '\0 ' ) {
} else
}
/* Display DFA transition state table*/
void Display_DFA( int last_index, struct DFA * dfa_states,
char * DFA_TABLE[ ] [ symbols] ) {
int i, j;
printf ( "\n \n ********************************************************\n \n " ) ; printf ( "\t \t DFA TRANSITION STATE TABLE \t \t \n \n " ) ; printf ( "\n STATES OF DFA :\t \t " ) ;
for ( i = 1 ; i < last_index; i++ )
printf ( "%s, " , & dfa_states
[ i
] .
states ) ; printf ( "\n GIVEN SYMBOLS FOR DFA: \t " ) ;
for ( i = 0 ; i < symbols; i++ )
for ( i = 0 ; i < symbols; i++ )
// display the DFA transition state table
printf ( "--------+-----------------------\n " ) ; for ( i = 0 ; i < zz; i++ ) {
printf ( "%s\t " , & dfa_states
[ i
+ 1 ] .
states ) ; for ( j = 0 ; j < symbols; j++ ) {
printf ( "|%s \t " , & DFA_TABLE
[ i
] [ j
] ) ; }
}
}
// Driver Code
int main( ) {
int i, j, states;
char T_buf[ MAX_LEN] ;
// creating an array dfa structures
struct DFA
* dfa_states
= malloc ( MAX_LEN
* ( sizeof ( dfa
) ) ) ; states = 6 , symbols = 2 ;
printf ( "\n STATES OF NFA :\t \t " ) ; for ( i = 0 ; i < states; i++ )
printf ( "%c, " , ( char ) ( 65 + i
) ) ; printf ( "\n GIVEN SYMBOLS FOR NFA: \t " ) ;
for ( i = 0 ; i < symbols; i++ )
char * NFA_TABLE[ states] [ symbols + 1 ] ;
// Hard coded input for NFA table
char * DFA_TABLE[ MAX_LEN] [ symbols] ;
strcpy ( & NFA_TABLE
[ 0 ] [ 0 ] , "FC" ) ; strcpy ( & NFA_TABLE
[ 0 ] [ 1 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 0 ] [ 2 ] , "BF" ) ; strcpy ( & NFA_TABLE
[ 1 ] [ 0 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 1 ] [ 1 ] , "C" ) ; strcpy ( & NFA_TABLE
[ 1 ] [ 2 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 2 ] [ 0 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 2 ] [ 1 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 2 ] [ 2 ] , "D" ) ; strcpy ( & NFA_TABLE
[ 3 ] [ 0 ] , "E" ) ; strcpy ( & NFA_TABLE
[ 3 ] [ 1 ] , "A" ) ; strcpy ( & NFA_TABLE
[ 3 ] [ 2 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 4 ] [ 0 ] , "A" ) ; strcpy ( & NFA_TABLE
[ 4 ] [ 1 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 4 ] [ 2 ] , "BF" ) ; strcpy ( & NFA_TABLE
[ 5 ] [ 0 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 5 ] [ 1 ] , "-" ) ; strcpy ( & NFA_TABLE
[ 5 ] [ 2 ] , "-" ) ; printf ( "\n NFA STATE TRANSITION TABLE \n \n \n " ) ;
for ( i = 0 ; i < symbols; i++ )
// Displaying the matrix of NFA transition table
printf ( "--------+------------------------------------\n " ) ; for ( i = 0 ; i < states; i++ ) {
printf ( "%c\t " , ( char ) ( 65 + i
) ) ;
for ( j = 0 ; j <= symbols; j++ ) {
printf ( "|%s \t " , & NFA_TABLE
[ i
] [ j
] ) ; }
}
int closure_ar[ states] ;
char * closure_table[ states] ;
Display_closure( states, closure_ar, closure_table, NFA_TABLE, DFA_TABLE) ;
strcpy ( & dfa_states
[ last_index
++ ] .
states , "-" ) ;
dfa_states[ last_index - 1 ] .count = 1 ;
bzero( ( void * ) buffer, MAX_LEN) ;
strcpy ( buffer
, & closure_table
[ 0 ] ) ; strcpy ( & dfa_states
[ last_index
++ ] .
states , buffer
) ;
int Sm = 1 , ind = 1 ;
int start_index = 1 ;
// Filling up the DFA table with transition values
// Till new states can be entered in DFA table
while ( ind != - 1 ) {
dfa_states[ start_index] .count = 1 ;
Sm = 0 ;
for ( i = 0 ; i < symbols; i++ ) {
trans( buffer, i, closure_table, states, NFA_TABLE, T_buf) ;
// storing the new DFA state in buffer
strcpy ( & DFA_TABLE
[ zz
] [ i
] , T_buf
) ;
// parameter to control new states
Sm = Sm + new_states( dfa_states, T_buf) ;
}
ind = indexing( dfa_states) ;
if ( ind != - 1 )
strcpy ( buffer
, & dfa_states
[ ++ start_index
] .
states ) ; zz++;
}
// display the DFA TABLE
Display_DFA( last_index, dfa_states, DFA_TABLE) ;
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojZGVmaW5lIE1BWF9MRU4gMTAwCiAKY2hhciBORkFfRklMRVtNQVhfTEVOXTsKY2hhciBidWZmZXJbTUFYX0xFTl07CmludCB6eiA9IDA7CiAKLy8gU3RydWN0dXJlIHRvIHN0b3JlIERGQSBzdGF0ZXMgYW5kIHRoZWlyCi8vIHN0YXR1cyAoIGkuZSBuZXcgZW50cnkgb3IgYWxyZWFkeSBwcmVzZW50KQpzdHJ1Y3QgREZBIHsKICBjaGFyICpzdGF0ZXM7CiAgaW50IGNvdW50Owp9IGRmYTsKIAppbnQgbGFzdF9pbmRleCA9IDA7CkZJTEUgKmZwOwppbnQgc3ltYm9sczsKIAovKiByZXNldCB0aGUgaGFzaCBtYXAqLwp2b2lkIHJlc2V0KGludCBhcltdLCBpbnQgc2l6ZSkgewogIGludCBpOwogCiAgLy8gcmVzZXQgYWxsIHRoZSB2YWx1ZXMgb2YKICAvLyB0aGUgbWFwcGluZyBhcnJheSB0byB6ZXJvCiAgZm9yIChpID0gMDsgaSA8IHNpemU7IGkrKykgewogICAgYXJbaV0gPSAwOwogIH0KfQogCi8vIENoZWNrIHdoaWNoIFN0YXRlcyBhcmUgcHJlc2VudCBpbiB0aGUgZS1jbG9zdXJlCiAKLyogbWFwIHRoZSBzdGF0ZXMgb2YgTkZBIHRvIGEgaGFzaCBzZXQqLwp2b2lkIGNoZWNrKGludCBhcltdLCBjaGFyIFNbXSkgewogIGludCBpLCBqOwogCiAgLy8gVG8gcGFyc2UgdGhlIGluZGl2aWR1YWwgc3RhdGVzIG9mIE5GQQogIGludCBsZW4gPSBzdHJsZW4oUyk7CiAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAKICAgIC8vIFNldCBoYXNoIG1hcCBmb3IgdGhlIHBvc2l0aW9uCiAgICAvLyBvZiB0aGUgc3RhdGVzIHdoaWNoIGlzIGZvdW5kCiAgICBqID0gKChpbnQpKFNbaV0pIC0gNjUpOwogICAgYXJbal0rKzsKICB9Cn0KIAovLyBUbyBmaW5kIG5ldyBDbG9zdXJlIFN0YXRlcwp2b2lkIHN0YXRlKGludCBhcltdLCBpbnQgc2l6ZSwgY2hhciBTW10pIHsKICBpbnQgaiwgayA9IDA7CiAKICAvLyBDb21iaW5lIG11bHRpcGxlIHN0YXRlcyBvZiBORkEKICAvLyB0byBjcmVhdGUgbmV3IHN0YXRlcyBvZiBERkEKICBmb3IgKGogPSAwOyBqIDwgc2l6ZTsgaisrKSB7CiAgICBpZiAoYXJbal0gIT0gMCkKICAgICAgU1trKytdID0gKGNoYXIpKDY1ICsgaik7CiAgfQogCiAgLy8gbWFyayB0aGUgZW5kIG9mIHRoZSBzdGF0ZQogIFNba10gPSAnXDAnOwp9CiAKLy8gVG8gcGljayB0aGUgbmV4dCBjbG9zdXJlIGZyb20gY2xvc3VyZSBzZXQKaW50IGNsb3N1cmUoaW50IGFyW10sIGludCBzaXplKSB7CiAgaW50IGk7CiAKICAvLyBjaGVjayBuZXcgY2xvc3VyZSBpcyBwcmVzZW50IG9yIG5vdAogIGZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKICAgIGlmIChhcltpXSA9PSAxKQogICAgICByZXR1cm4gaTsKICB9CiAgcmV0dXJuICgxMDApOwp9CiAKLy8gQ2hlY2sgbmV3IERGQSBzdGF0ZXMgY2FuIGJlCi8vIGVudGVyZWQgaW4gREZBIHRhYmxlIG9yIG5vdAppbnQgaW5kZXhpbmcoc3RydWN0IERGQSAqZGZhKSB7CiAgaW50IGk7CiAKICBmb3IgKGkgPSAwOyBpIDwgbGFzdF9pbmRleDsgaSsrKSB7CiAgICBpZiAoZGZhW2ldLmNvdW50ID09IDApCiAgICAgIHJldHVybiAxOwogIH0KICByZXR1cm4gLTE7Cn0KIAovKiBUbyBEaXNwbGF5IGVwc2lsb24gY2xvc3VyZSovCnZvaWQgRGlzcGxheV9jbG9zdXJlKGludCBzdGF0ZXMsIGludCBjbG9zdXJlX2FyW10sCiAgICAgICAgICAgICAgICAgICAgIGNoYXIgKmNsb3N1cmVfdGFibGVbXSwKICAgICAgICAgICAgICAgICAgICAgY2hhciAqTkZBX1RBQkxFW11bc3ltYm9scyArIDFdLAogICAgICAgICAgICAgICAgICAgICBjaGFyICpERkFfVEFCTEVbXVtzeW1ib2xzXSkgewogIGludCBpOwogIGZvciAoaSA9IDA7IGkgPCBzdGF0ZXM7IGkrKykgewogICAgcmVzZXQoY2xvc3VyZV9hciwgc3RhdGVzKTsKICAgIGNsb3N1cmVfYXJbaV0gPSAyOwogCiAgICAvLyB0byBuZWdsZWN0IGJsYW5rIGVudHJ5CiAgICBpZiAoc3RyY21wKCZORkFfVEFCTEVbaV1bc3ltYm9sc10sICItIikgIT0gMCkgewogCiAgICAgIC8vIGNvcHkgdGhlIE5GQSB0cmFuc2l0aW9uIHN0YXRlIHRvIGJ1ZmZlcgogICAgICBzdHJjcHkoYnVmZmVyLCAmTkZBX1RBQkxFW2ldW3N5bWJvbHNdKTsKICAgICAgY2hlY2soY2xvc3VyZV9hciwgYnVmZmVyKTsKICAgICAgaW50IHogPSBjbG9zdXJlKGNsb3N1cmVfYXIsIHN0YXRlcyk7CiAKICAgICAgLy8gdGlsbCBjbG9zdXJlIGdldCBjb21wbGV0ZWx5IHNhdHVyYXRlZAogICAgICB3aGlsZSAoeiAhPSAxMDApCiAgICAgIHsKICAgICAgICBpZiAoc3RyY21wKCZORkFfVEFCTEVbel1bc3ltYm9sc10sICItIikgIT0gMCkgewogICAgICAgICAgc3RyY3B5KGJ1ZmZlciwgJk5GQV9UQUJMRVt6XVtzeW1ib2xzXSk7CiAKICAgICAgICAgIC8vIGNhbGwgdGhlIGNoZWNrIGZ1bmN0aW9uCiAgICAgICAgICBjaGVjayhjbG9zdXJlX2FyLCBidWZmZXIpOwogICAgICAgIH0KICAgICAgICBjbG9zdXJlX2FyW3pdKys7CiAgICAgICAgeiA9IGNsb3N1cmUoY2xvc3VyZV9hciwgc3RhdGVzKTsKICAgICAgfQogICAgfQogCiAgICAvLyBwcmludCB0aGUgZSBjbG9zdXJlIGZvciBldmVyeSBzdGF0ZXMgb2YgTkZBCiAgICBwcmludGYoIlxuIGUtQ2xvc3VyZSAoJWMpIDpcdCIsIChjaGFyKSg2NSArIGkpKTsKIAogICAgYnplcm8oKHZvaWQgKilidWZmZXIsIE1BWF9MRU4pOwogICAgc3RhdGUoY2xvc3VyZV9hciwgc3RhdGVzLCBidWZmZXIpOwogICAgc3RyY3B5KCZjbG9zdXJlX3RhYmxlW2ldLCBidWZmZXIpOwogICAgcHJpbnRmKCIlc1xuIiwgJmNsb3N1cmVfdGFibGVbaV0pOwogIH0KfQogCi8qIFRvIGNoZWNrIE5ldyBTdGF0ZXMgaW4gREZBICovCmludCBuZXdfc3RhdGVzKHN0cnVjdCBERkEgKmRmYSwgY2hhciBTW10pIHsKIAogIGludCBpOwogCiAgLy8gVG8gY2hlY2sgdGhlIGN1cnJlbnQgc3RhdGUgaXMgYWxyZWFkeQogIC8vIGJlaW5nIHVzZWQgYXMgYSBERkEgc3RhdGUgb3Igbm90IGluCiAgLy8gREZBIHRyYW5zaXRpb24gdGFibGUKICBmb3IgKGkgPSAwOyBpIDwgbGFzdF9pbmRleDsgaSsrKSB7CiAgICBpZiAoc3RyY21wKCZkZmFbaV0uc3RhdGVzLCBTKSA9PSAwKQogICAgICByZXR1cm4gMDsKICB9CiAKICAvLyBwdXNoIHRoZSBuZXcKICBzdHJjcHkoJmRmYVtsYXN0X2luZGV4KytdLnN0YXRlcywgUyk7CiAKICAvLyBzZXQgdGhlIGNvdW50IGZvciBuZXcgc3RhdGVzIGVudGVyZWQKICAvLyB0byB6ZXJvCiAgZGZhW2xhc3RfaW5kZXggLSAxXS5jb3VudCA9IDA7CiAgcmV0dXJuIDE7Cn0KIAovLyBUcmFuc2l0aW9uIGZ1bmN0aW9uIGZyb20gTkZBIHRvIERGQQovLyAoZ2VuZXJhbGx5IHVuaW9uIG9mIGNsb3N1cmUgb3BlcmF0aW9uICkKdm9pZCB0cmFucyhjaGFyIFNbXSwgaW50IE0sIGNoYXIgKmNsc3JfdFtdLCBpbnQgc3QsCiAgICAgICAgICAgICAgIGNoYXIgKk5GVFtdW3N5bWJvbHMgKyAxXSwgY2hhciBUQltdKSB7CiAgaW50IGxlbiA9IHN0cmxlbihTKTsKICBpbnQgaSwgaiwgaywgZzsKICBpbnQgYXJyW3N0XTsKICBpbnQgc3o7CiAgcmVzZXQoYXJyLCBzdCk7CiAgY2hhciB0ZW1wW01BWF9MRU5dLCB0ZW1wMltNQVhfTEVOXTsKICBjaGFyICpidWZmOwogCiAgLy8gVHJhbnNpdGlvbiBmdW5jdGlvbiBmcm9tIE5GQSB0byBERkEKICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKIAogICAgaiA9ICgoaW50KShTW2ldIC0gNjUpKTsKICAgIHN0cmNweSh0ZW1wLCAmTkZUW2pdW01dKTsKIAogICAgaWYgKHN0cmNtcCh0ZW1wLCAiLSIpICE9IDApIHsKICAgICAgc3ogPSBzdHJsZW4odGVtcCk7CiAgICAgIGcgPSAwOwogCiAgICAgIHdoaWxlIChnIDwgc3opIHsKICAgICAgICBrID0gKChpbnQpKHRlbXBbZ10gLSA2NSkpOwogICAgICAgIHN0cmNweSh0ZW1wMiwgJmNsc3JfdFtrXSk7CiAgICAgICAgY2hlY2soYXJyLCB0ZW1wMik7CiAgICAgICAgZysrOwogICAgICB9CiAgICB9CiAgfQogCiAgYnplcm8oKHZvaWQgKil0ZW1wLCBNQVhfTEVOKTsKICBzdGF0ZShhcnIsIHN0LCB0ZW1wKTsKICBpZiAodGVtcFswXSAhPSAnXDAnKSB7CiAgICBzdHJjcHkoVEIsIHRlbXApOwogIH0gZWxzZQogICAgc3RyY3B5KFRCLCAiLSIpOwp9CiAKLyogRGlzcGxheSBERkEgdHJhbnNpdGlvbiBzdGF0ZSB0YWJsZSovCnZvaWQgRGlzcGxheV9ERkEoaW50IGxhc3RfaW5kZXgsIHN0cnVjdCBERkEgKmRmYV9zdGF0ZXMsCiAgICAgICAgICAgICAgICAgY2hhciAqREZBX1RBQkxFW11bc3ltYm9sc10pIHsKICBpbnQgaSwgajsKICBwcmludGYoIlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4iKTsKICBwcmludGYoIlx0XHQgREZBIFRSQU5TSVRJT04gU1RBVEUgVEFCTEUgXHRcdCBcblxuIik7CiAgcHJpbnRmKCJcbiBTVEFURVMgT0YgREZBIDpcdFx0Iik7CiAKICBmb3IgKGkgPSAxOyBpIDwgbGFzdF9pbmRleDsgaSsrKQogICAgcHJpbnRmKCIlcywgIiwgJmRmYV9zdGF0ZXNbaV0uc3RhdGVzKTsKICBwcmludGYoIlxuIik7CiAgcHJpbnRmKCJcbiBHSVZFTiBTWU1CT0xTIEZPUiBERkE6IFx0Iik7CiAKICBmb3IgKGkgPSAwOyBpIDwgc3ltYm9sczsgaSsrKQogICAgcHJpbnRmKCIlZCwgIiwgaSk7CiAgcHJpbnRmKCJcblxuIik7CiAgcHJpbnRmKCJTVEFURVNcdCIpOwogCiAgZm9yIChpID0gMDsgaSA8IHN5bWJvbHM7IGkrKykKICAgIHByaW50ZigifCVkXHQiLCBpKTsKICBwcmludGYoIlxuIik7CiAKICAvLyBkaXNwbGF5IHRoZSBERkEgdHJhbnNpdGlvbiBzdGF0ZSB0YWJsZQogIHByaW50ZigiLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOwogIGZvciAoaSA9IDA7IGkgPCB6ejsgaSsrKSB7CiAgICBwcmludGYoIiVzXHQiLCAmZGZhX3N0YXRlc1tpICsgMV0uc3RhdGVzKTsKICAgIGZvciAoaiA9IDA7IGogPCBzeW1ib2xzOyBqKyspIHsKICAgICAgcHJpbnRmKCJ8JXMgXHQiLCAmREZBX1RBQkxFW2ldW2pdKTsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKICB9Cn0KIAovLyBEcml2ZXIgQ29kZQppbnQgbWFpbigpIHsKICBpbnQgaSwgaiwgc3RhdGVzOwogIGNoYXIgVF9idWZbTUFYX0xFTl07CiAKICAvLyBjcmVhdGluZyBhbiBhcnJheSBkZmEgc3RydWN0dXJlcwogIHN0cnVjdCBERkEgKmRmYV9zdGF0ZXMgPSBtYWxsb2MoTUFYX0xFTiAqIChzaXplb2YoZGZhKSkpOwogIHN0YXRlcyA9IDYsIHN5bWJvbHMgPSAyOwogCiAgcHJpbnRmKCJcbiBTVEFURVMgT0YgTkZBIDpcdFx0Iik7CiAgZm9yIChpID0gMDsgaSA8IHN0YXRlczsgaSsrKQogCiAgICBwcmludGYoIiVjLCAiLCAoY2hhcikoNjUgKyBpKSk7CiAgcHJpbnRmKCJcbiIpOwogIHByaW50ZigiXG4gR0lWRU4gU1lNQk9MUyBGT1IgTkZBOiBcdCIpOwogCiAgZm9yIChpID0gMDsgaSA8IHN5bWJvbHM7IGkrKykKIAogICAgcHJpbnRmKCIlZCwgIiwgaSk7CiAgcHJpbnRmKCJlcHMiKTsKICBwcmludGYoIlxuXG4iKTsKICBjaGFyICpORkFfVEFCTEVbc3RhdGVzXVtzeW1ib2xzICsgMV07CiAKICAvLyBIYXJkIGNvZGVkIGlucHV0IGZvciBORkEgdGFibGUKICBjaGFyICpERkFfVEFCTEVbTUFYX0xFTl1bc3ltYm9sc107CiAgc3RyY3B5KCZORkFfVEFCTEVbMF1bMF0sICJGQyIpOwogIHN0cmNweSgmTkZBX1RBQkxFWzBdWzFdLCAiLSIpOwogIHN0cmNweSgmTkZBX1RBQkxFWzBdWzJdLCAiQkYiKTsKICBzdHJjcHkoJk5GQV9UQUJMRVsxXVswXSwgIi0iKTsKICBzdHJjcHkoJk5GQV9UQUJMRVsxXVsxXSwgIkMiKTsKICBzdHJjcHkoJk5GQV9UQUJMRVsxXVsyXSwgIi0iKTsKICBzdHJjcHkoJk5GQV9UQUJMRVsyXVswXSwgIi0iKTsKICBzdHJjcHkoJk5GQV9UQUJMRVsyXVsxXSwgIi0iKTsKICBzdHJjcHkoJk5GQV9UQUJMRVsyXVsyXSwgIkQiKTsKICBzdHJjcHkoJk5GQV9UQUJMRVszXVswXSwgIkUiKTsKICBzdHJjcHkoJk5GQV9UQUJMRVszXVsxXSwgIkEiKTsKICBzdHJjcHkoJk5GQV9UQUJMRVszXVsyXSwgIi0iKTsKICBzdHJjcHkoJk5GQV9UQUJMRVs0XVswXSwgIkEiKTsKICBzdHJjcHkoJk5GQV9UQUJMRVs0XVsxXSwgIi0iKTsKICBzdHJjcHkoJk5GQV9UQUJMRVs0XVsyXSwgIkJGIik7CiAgc3RyY3B5KCZORkFfVEFCTEVbNV1bMF0sICItIik7CiAgc3RyY3B5KCZORkFfVEFCTEVbNV1bMV0sICItIik7CiAgc3RyY3B5KCZORkFfVEFCTEVbNV1bMl0sICItIik7CiAgcHJpbnRmKCJcbiBORkEgU1RBVEUgVFJBTlNJVElPTiBUQUJMRSBcblxuXG4iKTsKICBwcmludGYoIlNUQVRFU1x0Iik7CiAKICBmb3IgKGkgPSAwOyBpIDwgc3ltYm9sczsgaSsrKQogICAgcHJpbnRmKCJ8JWRcdCIsIGkpOwogIHByaW50ZigiZXBzXG4iKTsKIAogIC8vIERpc3BsYXlpbmcgdGhlIG1hdHJpeCBvZiBORkEgdHJhbnNpdGlvbiB0YWJsZQogIHByaW50ZigiLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKICBmb3IgKGkgPSAwOyBpIDwgc3RhdGVzOyBpKyspIHsKICAgIHByaW50ZigiJWNcdCIsIChjaGFyKSg2NSArIGkpKTsKIAogICAgZm9yIChqID0gMDsgaiA8PSBzeW1ib2xzOyBqKyspIHsKICAgICAgcHJpbnRmKCJ8JXMgXHQiLCAmTkZBX1RBQkxFW2ldW2pdKTsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKICB9CiAgaW50IGNsb3N1cmVfYXJbc3RhdGVzXTsKICBjaGFyICpjbG9zdXJlX3RhYmxlW3N0YXRlc107CiAKICBEaXNwbGF5X2Nsb3N1cmUoc3RhdGVzLCBjbG9zdXJlX2FyLCBjbG9zdXJlX3RhYmxlLCBORkFfVEFCTEUsIERGQV9UQUJMRSk7CiAgc3RyY3B5KCZkZmFfc3RhdGVzW2xhc3RfaW5kZXgrK10uc3RhdGVzLCAiLSIpOwogCiAgZGZhX3N0YXRlc1tsYXN0X2luZGV4IC0gMV0uY291bnQgPSAxOwogIGJ6ZXJvKCh2b2lkICopYnVmZmVyLCBNQVhfTEVOKTsKIAogIHN0cmNweShidWZmZXIsICZjbG9zdXJlX3RhYmxlWzBdKTsKICBzdHJjcHkoJmRmYV9zdGF0ZXNbbGFzdF9pbmRleCsrXS5zdGF0ZXMsIGJ1ZmZlcik7CiAKICBpbnQgU20gPSAxLCBpbmQgPSAxOwogIGludCBzdGFydF9pbmRleCA9IDE7CiAKICAvLyBGaWxsaW5nIHVwIHRoZSBERkEgdGFibGUgd2l0aCB0cmFuc2l0aW9uIHZhbHVlcwogIC8vIFRpbGwgbmV3IHN0YXRlcyBjYW4gYmUgZW50ZXJlZCBpbiBERkEgdGFibGUKICB3aGlsZSAoaW5kICE9IC0xKSB7CiAgICBkZmFfc3RhdGVzW3N0YXJ0X2luZGV4XS5jb3VudCA9IDE7CiAgICBTbSA9IDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgc3ltYm9sczsgaSsrKSB7CiAKICAgICAgdHJhbnMoYnVmZmVyLCBpLCBjbG9zdXJlX3RhYmxlLCBzdGF0ZXMsIE5GQV9UQUJMRSwgVF9idWYpOwogCiAgICAgIC8vIHN0b3JpbmcgdGhlIG5ldyBERkEgc3RhdGUgaW4gYnVmZmVyCiAgICAgIHN0cmNweSgmREZBX1RBQkxFW3p6XVtpXSwgVF9idWYpOwogCiAgICAgIC8vIHBhcmFtZXRlciB0byBjb250cm9sIG5ldyBzdGF0ZXMKICAgICAgU20gPSBTbSArIG5ld19zdGF0ZXMoZGZhX3N0YXRlcywgVF9idWYpOwogICAgfQogICAgaW5kID0gaW5kZXhpbmcoZGZhX3N0YXRlcyk7CiAgICBpZiAoaW5kICE9IC0xKQogICAgICBzdHJjcHkoYnVmZmVyLCAmZGZhX3N0YXRlc1srK3N0YXJ0X2luZGV4XS5zdGF0ZXMpOwogICAgenorKzsKICB9CiAgLy8gZGlzcGxheSB0aGUgREZBIFRBQkxFCiAgRGlzcGxheV9ERkEobGFzdF9pbmRleCwgZGZhX3N0YXRlcywgREZBX1RBQkxFKTsKIAogIHJldHVybiAwOwp9