/**************************************
* eggache? egg hurt?
* support: + - * / % ^ ( )
*-------------------------------------
* original
* E -> E+T|E-T|T
* T -> T*F|T/F|T%F|F
* F -> N^F|N
* N -> (E)|-VAL|+VAL|VAL
*-------------------------------------
* remove left recursive
* E -> TE'
* E'-> +TE'|-TE'|e
* T -> FT'
* T'-> *FT'|/FT'|%FT'|e
* F -> NF'
* F'-> ^F|e
* N -> (E)|-VAL|+VAL|VAL
* ------------------------------------
* char set [0-9]|.|e|+|-|*|/|%|^|(|)
* VAL := [0-9]+(\.[0-9]+)?(e(+|-)?[0-9]+)?
* ************************************/
#include <stdio.h>
#include <math.h>
#define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof(*a))
typedef enum {
LLS_NUM,
LLS_ADD,
LLS_SUB,
LLS_MUL,
LLS_DIV,
LLS_MOD,
LLS_POW,
LLS_LBR,
LLS_RBR,
LLS_END,
LLS_ERR,
} LLSTATE;
typedef enum {
LLE_OK,
LLE_INVALID_CHAR,
LLE_BK_NOT_MATCH,
LLE_NOT_A_NUM,
LLE_NOT_OPERATOR,
} LLERROR;
#define LL_VAL_DEFVAL 0
typedef double LL_VAL;
typedef struct LL_state {
const char* expr;
LL_VAL val;
int read;
LLSTATE state;
int errcode;
} LL_state;
LL_VAL LL_E( LL_state* self );
LL_VAL LL_T( LL_state* self );
LL_VAL LL_F( LL_state* self );
LL_VAL LL_NUM( LL_state* self ) {
LL_VAL ret;
int len;
sscanf( &self
->expr
[self
->read
], "%lf%n", &ret, &len ); // %lf !! I'm lazy
self->read += len;
return ret;
}
LLSTATE LL_PARSE( LL_state* self ) {
char c = self->expr[self->read];
while ( c == ' ' ) //ignore space
c = self->expr[++self->read];
if ( c >= '0' && c <= '9' ) {
self->val = LL_NUM( self );
self->state = LLS_NUM;
} else {
++self->read;
if ( c == '+' ) {
self->state = LLS_ADD;
} else if ( c == '-' ) {
self->state = LLS_SUB;
} else if ( c == '*' ) {
self->state = LLS_MUL;
} else if ( c == '/' ) {
self->state = LLS_DIV;
} else if ( c == '%' ) {
self->state = LLS_MOD;
} else if ( c == '^' ) {
self->state = LLS_POW;
} else if ( c == '(' ) {
self->state = LLS_LBR;
} else if ( c == ')' ) {
self->state = LLS_RBR;
} else if ( c == '\0' ) {
self->state = LLS_END;
} else {
self->errcode = LLE_INVALID_CHAR;
self->state = LLS_ERR;
}
}
return self->state;
}
LL_VAL LL_N( LL_state* self ) { // F -> (E)|-VAL|+VAL|VAL
LL_VAL ret = LL_VAL_DEFVAL;
int lbr_pos = self->read;
if ( self->state == LLS_ERR ) return ret;
switch ( self->state ) {
case LLS_LBR:
LL_PARSE( self );
ret = LL_E( self );
if ( self->state != LLS_RBR ) {
if ( self->errcode == LLE_OK ) {
self->errcode = LLE_BK_NOT_MATCH;
self->read = lbr_pos;
}
self->state = LLS_ERR;
return ret;
}
break;
case LLS_ADD:
case LLS_SUB:
if ( 1 ) {
LLSTATE s = self->state;
LL_PARSE( self );
if ( self->state != LLS_NUM ) {
self->errcode = LLE_NOT_A_NUM;
self->state = LLS_ERR;
return ret;
}
ret = ( s == LLS_ADD ? self->val : -self->val ) ;
}
break;
case LLS_NUM:
ret = self->val;
break;
default:
self->errcode = LLE_NOT_A_NUM;
self->state = LLS_ERR;
return ret;
}
LL_PARSE( self );
return ret;
}
LL_VAL LL_F_( LL_state* self ) { // F'-> ^F|e
LL_VAL val = self->val;
if ( self->state == LLS_ERR ) return val;
switch ( self->state ) {
case LLS_POW:
LL_PARSE( self );
return pow( val
, LL_F
( self
) ); case LLS_ADD:
case LLS_SUB:
case LLS_MUL:
case LLS_DIV:
case LLS_MOD:
case LLS_RBR:
case LLS_END:
case LLS_ERR:
return val;
default:
self->errcode = LLE_NOT_OPERATOR;
self->state = LLS_ERR;
return val;
}
}
LL_VAL LL_F( LL_state* self ) { // F -> NF'
self->val = LL_N( self );
return LL_F_( self );
}
LL_VAL LL_T_( LL_state* self ) { // T'-> *FT'|/FT'|%FT'|e
LL_VAL val = self->val;
if ( self->state == LLS_ERR ) return val;
switch ( self->state ) {
case LLS_MUL:
LL_PARSE( self );
self->val = val * LL_F( self );
return LL_T_( self );
case LLS_DIV:
LL_PARSE( self );
self->val = val / LL_F( self );
return LL_T_( self );
case LLS_MOD:
LL_PARSE( self );
self->val = fmod( val, LL_F( self ) );
return LL_T_( self );
case LLS_ADD:
case LLS_SUB:
case LLS_RBR:
case LLS_END:
case LLS_ERR:
return val;
default:
self->errcode = LLE_NOT_OPERATOR;
self->state = LLS_ERR;
return val;
}
}
LL_VAL LL_T( LL_state* self ) { // T -> FT'
self->val = LL_F( self );
return LL_T_( self );
}
LL_VAL LL_E_( LL_state* self ) { // E'-> +TE'|-TE'|e
LL_VAL val = self->val;
if ( self->state == LLS_ERR ) return val;
switch ( self->state ) {
case LLS_ADD:
LL_PARSE( self );
self->val = val + LL_T( self );
return LL_E_( self );
case LLS_SUB:
LL_PARSE( self );
self->val = val - LL_T( self );
return LL_E_( self );
case LLS_RBR:
case LLS_END:
case LLS_ERR:
return val;
default:
self->errcode = LLE_NOT_OPERATOR;
self->state = LLS_ERR;
return val;
}
}
LL_VAL LL_E( LL_state* self ) { // E -> TE'
self->val = LL_T( self );
return LL_E_( self );
}
int LL_calc( const char* expr, LL_VAL* val, int* pos ) {
LL_state self = {expr, *val};
LL_PARSE( &self );
*val = LL_E( &self );
*pos = self.read;
if ( self.errcode == LLE_OK && self.state != LLS_END ) {
self.errcode = LLE_BK_NOT_MATCH;
}
return self.errcode;
}
const char* LL_get_err_string( int errcode ) {
static const char* errstr[] = {
"",
"invalid character",
"bracket does not match",
"not a number",
"need operator",
};
if ( errcode < 0 || errcode > ARRAY_SIZE( errstr ) ) {
errcode = 0;
}
return errstr[errcode];
}
int main() {
char str[1024];
LL_VAL v;
int cnt_out = 0;
int r, pos;
r = LL_calc( str, &v, &pos );
printf( "out[%d]: " , ++cnt_out
); if ( r == LLE_OK ) {
printf( "%s= %.10g\n", str
, v
); } else {
printf( "error code %d: %s\n", r
, LL_get_err_string
( r
) ); }
}
return 0;
}
LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGVnZ2FjaGU/IGVnZyBodXJ0PwogKiBzdXBwb3J0OiArIC0gKiAvICUgXiAoICkKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIG9yaWdpbmFsCiAqIEUgLT4gRStUfEUtVHxUCiAqIFQgLT4gVCpGfFQvRnxUJUZ8RgogKiBGIC0+IE5eRnxOCiAqIE4gLT4gKEUpfC1WQUx8K1ZBTHxWQUwKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIHJlbW92ZSBsZWZ0IHJlY3Vyc2l2ZQogKiBFIC0+IFRFJwogKiBFJy0+ICtURSd8LVRFJ3xlCiAqIFQgLT4gRlQnCiAqIFQnLT4gKkZUJ3wvRlQnfCVGVCd8ZQogKiBGIC0+IE5GJwogKiBGJy0+IF5GfGUKICogTiAtPiAoRSl8LVZBTHwrVkFMfFZBTAogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogY2hhciBzZXQgWzAtOV18LnxlfCt8LXwqfC98JXxefCh8KQogKiBWQUwgOj0gWzAtOV0rKFwuWzAtOV0rKT8oZSgrfC0pP1swLTldKyk/CiAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8bWF0aC5oPgoKI2RlZmluZSBBUlJBWV9TSVpFKGEpIChpbnQpKHNpemVvZihhKS9zaXplb2YoKmEpKQp0eXBlZGVmIGVudW0gewogICAgTExTX05VTSwKICAgIExMU19BREQsCiAgICBMTFNfU1VCLAogICAgTExTX01VTCwKICAgIExMU19ESVYsCiAgICBMTFNfTU9ELAogICAgTExTX1BPVywKICAgIExMU19MQlIsCiAgICBMTFNfUkJSLAogICAgTExTX0VORCwKICAgIExMU19FUlIsCn0gTExTVEFURTsKCnR5cGVkZWYgZW51bSB7CiAgICBMTEVfT0ssCiAgICBMTEVfSU5WQUxJRF9DSEFSLAogICAgTExFX0JLX05PVF9NQVRDSCwKICAgIExMRV9OT1RfQV9OVU0sCiAgICBMTEVfTk9UX09QRVJBVE9SLAp9IExMRVJST1I7CgojZGVmaW5lIExMX1ZBTF9ERUZWQUwgMAp0eXBlZGVmIGRvdWJsZSBMTF9WQUw7Cgp0eXBlZGVmIHN0cnVjdCBMTF9zdGF0ZSB7CiAgICBjb25zdCBjaGFyKiBleHByOwogICAgTExfVkFMIHZhbDsKICAgIGludCByZWFkOwogICAgTExTVEFURSBzdGF0ZTsKICAgIGludCBlcnJjb2RlOwp9IExMX3N0YXRlOwoKTExfVkFMIExMX0UoIExMX3N0YXRlKiBzZWxmICk7CkxMX1ZBTCBMTF9UKCBMTF9zdGF0ZSogc2VsZiApOwpMTF9WQUwgTExfRiggTExfc3RhdGUqIHNlbGYgKTsKCkxMX1ZBTCBMTF9OVU0oIExMX3N0YXRlKiBzZWxmICkgewogICAgTExfVkFMIHJldDsKICAgIGludCBsZW47CiAgICBzc2NhbmYoICZzZWxmLT5leHByW3NlbGYtPnJlYWRdLAogICAgICAgICAgICAiJWxmJW4iLCAmcmV0LCAmbGVuICk7IC8vICVsZiAhISBJJ20gbGF6eQogICAgc2VsZi0+cmVhZCArPSBsZW47CiAgICByZXR1cm4gcmV0Owp9CgpMTFNUQVRFIExMX1BBUlNFKCBMTF9zdGF0ZSogc2VsZiApIHsKICAgIGNoYXIgYyA9IHNlbGYtPmV4cHJbc2VsZi0+cmVhZF07CiAgICB3aGlsZSAoIGMgPT0gJyAnICkgLy9pZ25vcmUgc3BhY2UKICAgICAgICBjID0gc2VsZi0+ZXhwclsrK3NlbGYtPnJlYWRdOwogICAgaWYgKCBjID49ICcwJyAmJiBjIDw9ICc5JyApIHsKICAgICAgICBzZWxmLT52YWwgPSBMTF9OVU0oIHNlbGYgKTsKICAgICAgICBzZWxmLT5zdGF0ZSA9IExMU19OVU07CiAgICB9IGVsc2UgewogICAgICAgICsrc2VsZi0+cmVhZDsKICAgICAgICBpZiAoIGMgPT0gJysnICkgewogICAgICAgICAgICBzZWxmLT5zdGF0ZSA9IExMU19BREQ7CiAgICAgICAgfSBlbHNlIGlmICggYyA9PSAnLScgKSB7CiAgICAgICAgICAgIHNlbGYtPnN0YXRlID0gTExTX1NVQjsKICAgICAgICB9IGVsc2UgaWYgKCBjID09ICcqJyApIHsKICAgICAgICAgICAgc2VsZi0+c3RhdGUgPSBMTFNfTVVMOwogICAgICAgIH0gZWxzZSBpZiAoIGMgPT0gJy8nICkgewogICAgICAgICAgICBzZWxmLT5zdGF0ZSA9IExMU19ESVY7CiAgICAgICAgfSBlbHNlIGlmICggYyA9PSAnJScgKSB7CiAgICAgICAgICAgIHNlbGYtPnN0YXRlID0gTExTX01PRDsKICAgICAgICB9IGVsc2UgaWYgKCBjID09ICdeJyApIHsKICAgICAgICAgICAgc2VsZi0+c3RhdGUgPSBMTFNfUE9XOwogICAgICAgIH0gZWxzZSBpZiAoIGMgPT0gJygnICkgewogICAgICAgICAgICBzZWxmLT5zdGF0ZSA9IExMU19MQlI7CiAgICAgICAgfSBlbHNlIGlmICggYyA9PSAnKScgKSB7CiAgICAgICAgICAgIHNlbGYtPnN0YXRlID0gTExTX1JCUjsKICAgICAgICB9IGVsc2UgaWYgKCBjID09ICdcMCcgKSB7CiAgICAgICAgICAgIHNlbGYtPnN0YXRlID0gTExTX0VORDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZWxmLT5lcnJjb2RlID0gTExFX0lOVkFMSURfQ0hBUjsKICAgICAgICAgICAgc2VsZi0+c3RhdGUgPSBMTFNfRVJSOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBzZWxmLT5zdGF0ZTsKfQoKTExfVkFMIExMX04oIExMX3N0YXRlKiBzZWxmICkgeyAvLyBGIC0+IChFKXwtVkFMfCtWQUx8VkFMCiAgICBMTF9WQUwgcmV0ID0gTExfVkFMX0RFRlZBTDsKICAgIGludCBsYnJfcG9zID0gc2VsZi0+cmVhZDsKICAgIGlmICggc2VsZi0+c3RhdGUgPT0gTExTX0VSUiApIHJldHVybiByZXQ7CiAgICBzd2l0Y2ggKCBzZWxmLT5zdGF0ZSApIHsKICAgIGNhc2UgTExTX0xCUjoKICAgICAgICBMTF9QQVJTRSggc2VsZiApOwogICAgICAgIHJldCA9IExMX0UoIHNlbGYgKTsKICAgICAgICBpZiAoIHNlbGYtPnN0YXRlICE9IExMU19SQlIgKSB7CiAgICAgICAgICAgIGlmICggc2VsZi0+ZXJyY29kZSA9PSBMTEVfT0sgKSB7CiAgICAgICAgICAgICAgICBzZWxmLT5lcnJjb2RlID0gTExFX0JLX05PVF9NQVRDSDsKICAgICAgICAgICAgICAgIHNlbGYtPnJlYWQgPSBsYnJfcG9zOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYtPnN0YXRlID0gTExTX0VSUjsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIExMU19BREQ6CiAgICBjYXNlIExMU19TVUI6CiAgICAgICAgaWYgKCAxICkgewogICAgICAgICAgICBMTFNUQVRFIHMgPSBzZWxmLT5zdGF0ZTsKICAgICAgICAgICAgTExfUEFSU0UoIHNlbGYgKTsKICAgICAgICAgICAgaWYgKCBzZWxmLT5zdGF0ZSAhPSBMTFNfTlVNICkgewogICAgICAgICAgICAgICAgc2VsZi0+ZXJyY29kZSA9IExMRV9OT1RfQV9OVU07CiAgICAgICAgICAgICAgICBzZWxmLT5zdGF0ZSA9IExMU19FUlI7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldCA9ICggcyA9PSBMTFNfQUREID8gc2VsZi0+dmFsIDogLXNlbGYtPnZhbCApIDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIExMU19OVU06CiAgICAgICAgcmV0ID0gc2VsZi0+dmFsOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBzZWxmLT5lcnJjb2RlID0gTExFX05PVF9BX05VTTsKICAgICAgICBzZWxmLT5zdGF0ZSA9IExMU19FUlI7CiAgICAgICAgcmV0dXJuIHJldDsKICAgIH0KICAgIExMX1BBUlNFKCBzZWxmICk7CiAgICByZXR1cm4gcmV0Owp9CgpMTF9WQUwgTExfRl8oIExMX3N0YXRlKiBzZWxmICkgeyAvLyBGJy0+IF5GfGUKICAgIExMX1ZBTCB2YWwgPSBzZWxmLT52YWw7CiAgICBpZiAoIHNlbGYtPnN0YXRlID09IExMU19FUlIgKSByZXR1cm4gdmFsOwogICAgc3dpdGNoICggc2VsZi0+c3RhdGUgKSB7CiAgICBjYXNlIExMU19QT1c6CiAgICAgICAgTExfUEFSU0UoIHNlbGYgKTsKICAgICAgICByZXR1cm4gcG93KCB2YWwsIExMX0YoIHNlbGYgKSApOwogICAgY2FzZSBMTFNfQUREOgogICAgY2FzZSBMTFNfU1VCOgogICAgY2FzZSBMTFNfTVVMOgogICAgY2FzZSBMTFNfRElWOgogICAgY2FzZSBMTFNfTU9EOgogICAgY2FzZSBMTFNfUkJSOgogICAgY2FzZSBMTFNfRU5EOgogICAgY2FzZSBMTFNfRVJSOgogICAgICAgIHJldHVybiB2YWw7CiAgICBkZWZhdWx0OgogICAgICAgIHNlbGYtPmVycmNvZGUgPSBMTEVfTk9UX09QRVJBVE9SOwogICAgICAgIHNlbGYtPnN0YXRlID0gTExTX0VSUjsKICAgICAgICByZXR1cm4gdmFsOwogICAgfQp9CgpMTF9WQUwgTExfRiggTExfc3RhdGUqIHNlbGYgKSB7IC8vIEYgLT4gTkYnCiAgICBzZWxmLT52YWwgPSBMTF9OKCBzZWxmICk7CiAgICByZXR1cm4gTExfRl8oIHNlbGYgKTsKfQoKTExfVkFMIExMX1RfKCBMTF9zdGF0ZSogc2VsZiApIHsgLy8gVCctPiAqRlQnfC9GVCd8JUZUJ3xlCiAgICBMTF9WQUwgdmFsID0gc2VsZi0+dmFsOwogICAgaWYgKCBzZWxmLT5zdGF0ZSA9PSBMTFNfRVJSICkgcmV0dXJuIHZhbDsKICAgIHN3aXRjaCAoIHNlbGYtPnN0YXRlICkgewogICAgY2FzZSBMTFNfTVVMOgogICAgICAgIExMX1BBUlNFKCBzZWxmICk7CiAgICAgICAgc2VsZi0+dmFsID0gdmFsICogTExfRiggc2VsZiApOwogICAgICAgIHJldHVybiBMTF9UXyggc2VsZiApOwogICAgY2FzZSBMTFNfRElWOgogICAgICAgIExMX1BBUlNFKCBzZWxmICk7CiAgICAgICAgc2VsZi0+dmFsID0gdmFsIC8gTExfRiggc2VsZiApOwogICAgICAgIHJldHVybiBMTF9UXyggc2VsZiApOwogICAgY2FzZSBMTFNfTU9EOgogICAgICAgIExMX1BBUlNFKCBzZWxmICk7CiAgICAgICAgc2VsZi0+dmFsID0gZm1vZCggdmFsLCBMTF9GKCBzZWxmICkgKTsKICAgICAgICByZXR1cm4gTExfVF8oIHNlbGYgKTsKICAgIGNhc2UgTExTX0FERDoKICAgIGNhc2UgTExTX1NVQjoKICAgIGNhc2UgTExTX1JCUjoKICAgIGNhc2UgTExTX0VORDoKICAgIGNhc2UgTExTX0VSUjoKICAgICAgICByZXR1cm4gdmFsOwogICAgZGVmYXVsdDoKICAgICAgICBzZWxmLT5lcnJjb2RlID0gTExFX05PVF9PUEVSQVRPUjsKICAgICAgICBzZWxmLT5zdGF0ZSA9IExMU19FUlI7CiAgICAgICAgcmV0dXJuIHZhbDsKICAgIH0KfQoKTExfVkFMIExMX1QoIExMX3N0YXRlKiBzZWxmICkgeyAvLyBUIC0+IEZUJwogICAgc2VsZi0+dmFsID0gTExfRiggc2VsZiApOwogICAgcmV0dXJuIExMX1RfKCBzZWxmICk7Cn0KCkxMX1ZBTCBMTF9FXyggTExfc3RhdGUqIHNlbGYgKSB7IC8vIEUnLT4gK1RFJ3wtVEUnfGUKICAgIExMX1ZBTCB2YWwgPSBzZWxmLT52YWw7CiAgICBpZiAoIHNlbGYtPnN0YXRlID09IExMU19FUlIgKSByZXR1cm4gdmFsOwogICAgc3dpdGNoICggc2VsZi0+c3RhdGUgKSB7CiAgICBjYXNlIExMU19BREQ6CiAgICAgICAgTExfUEFSU0UoIHNlbGYgKTsKICAgICAgICBzZWxmLT52YWwgPSB2YWwgKyBMTF9UKCBzZWxmICk7CiAgICAgICAgcmV0dXJuIExMX0VfKCBzZWxmICk7CiAgICBjYXNlIExMU19TVUI6CiAgICAgICAgTExfUEFSU0UoIHNlbGYgKTsKICAgICAgICBzZWxmLT52YWwgPSB2YWwgLSBMTF9UKCBzZWxmICk7CiAgICAgICAgcmV0dXJuIExMX0VfKCBzZWxmICk7CiAgICBjYXNlIExMU19SQlI6CiAgICBjYXNlIExMU19FTkQ6CiAgICBjYXNlIExMU19FUlI6CiAgICAgICAgcmV0dXJuIHZhbDsKICAgIGRlZmF1bHQ6CiAgICAgICAgc2VsZi0+ZXJyY29kZSA9IExMRV9OT1RfT1BFUkFUT1I7CiAgICAgICAgc2VsZi0+c3RhdGUgPSBMTFNfRVJSOwogICAgICAgIHJldHVybiB2YWw7CiAgICB9Cn0KCkxMX1ZBTCBMTF9FKCBMTF9zdGF0ZSogc2VsZiApIHsgLy8gRSAtPiBURScKICAgIHNlbGYtPnZhbCA9IExMX1QoIHNlbGYgKTsKICAgIHJldHVybiBMTF9FXyggc2VsZiApOwp9CgppbnQgTExfY2FsYyggY29uc3QgY2hhciogZXhwciwgTExfVkFMKiB2YWwsIGludCogcG9zICkgewogICAgTExfc3RhdGUgc2VsZiA9IHtleHByLCAqdmFsfTsKICAgIExMX1BBUlNFKCAmc2VsZiApOwogICAgKnZhbCA9IExMX0UoICZzZWxmICk7CiAgICAqcG9zID0gc2VsZi5yZWFkOwogICAgaWYgKCBzZWxmLmVycmNvZGUgPT0gTExFX09LICYmIHNlbGYuc3RhdGUgIT0gTExTX0VORCApIHsKICAgICAgICBzZWxmLmVycmNvZGUgPSBMTEVfQktfTk9UX01BVENIOwogICAgfQogICAgcmV0dXJuIHNlbGYuZXJyY29kZTsKfQoKY29uc3QgY2hhciogTExfZ2V0X2Vycl9zdHJpbmcoIGludCBlcnJjb2RlICkgewogICAgc3RhdGljIGNvbnN0IGNoYXIqIGVycnN0cltdID0gewogICAgICAgICIiLAogICAgICAgICJpbnZhbGlkIGNoYXJhY3RlciIsCiAgICAgICAgImJyYWNrZXQgZG9lcyBub3QgbWF0Y2giLAogICAgICAgICJub3QgYSBudW1iZXIiLAogICAgICAgICJuZWVkIG9wZXJhdG9yIiwKICAgIH07CiAgICBpZiAoIGVycmNvZGUgPCAwIHx8IGVycmNvZGUgPiBBUlJBWV9TSVpFKCBlcnJzdHIgKSApIHsKICAgICAgICBlcnJjb2RlID0gMDsKICAgIH0KICAgIHJldHVybiBlcnJzdHJbZXJyY29kZV07Cn0KCmludCBtYWluKCkgewogICAgY2hhciBzdHJbMTAyNF07CiAgICBMTF9WQUwgdjsKICAgIGludCBjbnRfb3V0ID0gMDsKICAgIHdoaWxlICggZ2V0cyggc3RyICkgKSB7CiAgICAgICAgaW50IHIsIHBvczsKICAgICAgICByID0gTExfY2FsYyggc3RyLCAmdiwgJnBvcyApOwogICAgICAgIHByaW50ZiggIm91dFslZF06ICIgLCArK2NudF9vdXQgKTsKICAgICAgICBpZiAoIHIgPT0gTExFX09LICkgewogICAgICAgICAgICBwcmludGYoICIlcz0gJS4xMGdcbiIsIHN0ciwgdiApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByaW50ZiggImVycm9yIGNvZGUgJWQ6ICVzXG4iLCByLCBMTF9nZXRfZXJyX3N0cmluZyggciApICk7CiAgICAgICAgICAgIHByaW50ZiggIiVzXG4iLCBzdHIgKTsKICAgICAgICAgICAgcHJpbnRmKCAiJSpzXG4iLCBwb3MsICJeIiApOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9Cg==