#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 10
int contas_validas = 0;
int contas_invalidas = 0;
int movimentos_validos = 0;
int movimentos_invalidos =0;
typedef struct conta {
char saldo[1000000];
char limite_saldo[1000000];
char id[11];
} Conta;
typedef struct movimento {
int tipo_movimento;
int opcao;
} Movimento;
int validar_id(char* id){
if (id[3] == '-' && id[9] == '-' && id[11] == '\0'){
int i = 0;
for(i = 0; i < 11; i++){
if(i != 3 && i != 9){
return 0;
}
}
}
}
else{
return 0;
}
return 1;
}
int validar_id2 (char* id) {
int componente_a = ((id[0]-'0')+ (id[1]-'0')+(id[2]-'0'));
int componente_b = ((id[4]-'0')+ (id[5]-'0')+(id[6]-'0')+(id[7]-'0')+(id[8]-'0'));
int componente_c = (id[10]-'0');
int soma1 = componente_a;
int soma2 = componente_a + componente_b;
int resto = soma2 % soma1;
if (resto == componente_c) {
return 1;
}
else {
return 0;
}
}
int validar_saldo(char *str) {
fprintf(stderr
, "DEBUG: valor passado: [%s]\n", str
); if (*str == '-') str++;
if (!isdigit((unsigned char)*str
)) return 0; /* empty strings return false */ while (*str) {
if (!isdigit((unsigned char)*str
)) return 0; str++;
}
return 1;
}
int is_valid_n_chars(char * string, size_t size, char * chars) {
int sindex = 0, cindex = 0;
// ciclo de validação da string dada
while(sindex < size && string[sindex] != '\0') {
// pesquisa do caracter iterado na lista de caracteres válidos
for (cindex = 0;
chars[cindex] != '\0' && string[sindex] != chars[cindex];
cindex++) /* void */;
// verificação se o caracter foi encontrado
if (chars[cindex] == '\0')
return 0;
// incremento da iteração
sindex++;
}
// é válido se chegou ao fim da string com todos os caracteres validados
// (verificação de string[sindex] == '\0' mas sindex < size)
return sindex == size;
}
int is_valid_chars(char * string, char * chars) {
return is_valid_n_chars
(string
, strlen(string
), chars
); }
int is_valid_n_number(char * string, size_t size) {
return is_valid_n_chars(string, size, "0123456789");
}
int is_valid_number(char * string) {
return is_valid_n_number
(string
, strlen(string
)); }
int validar_movimento (char * mov){
if (mov[0] == 0){
}
else if (mov[0] == 1){
}
else if (mov[0] == 2){
}
else{
return 0;
}
return 0;
}
void transferencia ( Conta* a , char id[] , char id2[] , char valor[] ){
int i=0;
int j=0;
int valor1;
int valor2;
for ( i; i<contas_validas ; i++){
if(strcmp( a
[i
].
id , id
) == 0) break;
}
for ( j ; j<contas_validas ; j++){
if(strcmp( a
[j
].
id , id2
) == 0) break;
}
valor1
= atoi(a
[i
].
saldo); valor2
= atoi(a
[j
].
saldo);
snprintf( a
[i
].
saldo , sizeof(a
[i
].
saldo) , "%d" , valor1
); snprintf( a
[j
].
saldo , sizeof(a
[j
].
saldo) , "%d" , valor2
); }
void deposito ( Conta* a , char id[] , char valor[] ){
int valor1;
int i=0;
for ( i ; i<contas_validas ; i++ ){
if(strcmp( a
[i
].
id , id
) == 0) break;
}
valor1
= atoi(a
[i
].
saldo); snprintf( a
[i
].
saldo , sizeof(a
[i
].
saldo) , "%d" , valor1
); }
void levantamento ( Conta* a , char id[] , char valor[] ){
int valor1;
int i=0;
for ( i ; i<contas_validas ; i++ ){
if(strcmp( a
[i
].
id , id
) == 0) break;
}
valor1
= atoi(a
[i
].
saldo); snprintf( a
[i
].
saldo , sizeof(a
[i
].
saldo) , "%d" , valor1
); }
int valida_opcao_mov ( char a[])
{
if ( a[0] == '0' || a[0] == '1' || a[0] == '2')
return 1;
else
return 0;
}
void movimentos (Conta* guardar_conta)
{
FILE
* fp
= fopen ("movimentos.txt", "r");
if (fp != NULL)
{
char temp[255+1];
char * componentes;
int contador = 0;
char operacao[1];
char id_origem[11];
char id_destino[11];
char valor[1000000];
while (fgets(temp
, 255+1, fp
) != NULL
) {
contador = 0;
if (temp[last-1] == '\n')
temp[last-1] = '\0';
componentes
= strtok (temp
, " ");
while (componentes != NULL)
{
if (contador == 0 )
{
strcpy(operacao
, componentes
); valida_opcao_mov ( operacao );
}
else if(contador == 1)
{
strcpy( id_origem
, componentes
); }
else if(contador == 2)
{
if ( operacao[0] == '0')
strcpy(id_destino
, componentes
); if ( operacao[0] == '1' || operacao[0] == '2' )
strcpy( valor
, componentes
); }
else if( contador== 3)
{
if ( operacao[0] == '0')
strcpy( valor
, componentes
); else
{
printf( "Movimento invalido\n"); movimentos_invalidos++;
}
}
componentes
= strtok (NULL
, " "); contador++;
}
if ( operacao[0] == '0' )
transferencia( guardar_conta , id_origem , id_destino , valor);
if ( operacao[0] == '1' )
deposito ( guardar_conta , id_origem , valor );
if ( operacao[0] == '2' )
levantamento( guardar_conta , id_origem , valor );
}
}
}
void contas (Conta* a){
FILE
* fp
= fopen ("contas.txt", "r"); //"r" -> leitura (modo texto) ou "b" -> leitura (modo binario) FILE
* fp2
= fopen ("stats.txt", "w");
if (fp != NULL){
char tmpid[11];
char tmpsaldo[1000000];
char tmplimitecredito[1000000];
char contas[255+1];
char* temp_id[11+1];
char* componentes;
int contador = 0;
int val1;
int val2;
int val3;
printf ("As contas existentes no ficheiro sao:\n");
while (fgets(contas
, 255+1, fp
) != NULL
) {
printf ("\n-> %s\n\n", contas
); contador = 0;
if (contas[last-1] == '\n')
contas[last-1] = '\0';
componentes
= strtok (contas
, " ");
while (componentes != NULL)
{
if (contador == 0)
{
printf ("- ID = %s\n", componentes
); int valido = validar_id (componentes);
int valido2 = validar_id2 (componentes);
if (valido == 1 && valido2 == 1)
{
val1 = 1;
}
else
{
val1 = 0;
}
}
else if (contador == 1)
{
strcpy(tmpsaldo
, componentes
); int valido = validar_saldo(componentes);
if (valido == 1)
{
printf ("- Saldo: %s\n", componentes
); val2 = 1;
}
else
{
val2 = 0;
}
}
else if (contador == 2)
{
strcpy(tmplimitecredito
, componentes
); int valido = is_valid_number(componentes);
/* ATENÇÂO AO FACTO DE NÃO HAVER COMPONENTE) */
if (valido == 1)
{
printf ("- Limite de credito: %s\n", componentes
); val3 = 1;
}
else
{
printf ("Limite de credito invalido!\n"); val3 = 0;
}
}
componentes
= strtok (NULL
, " "); contador++;
}
if (val1 == 1 && val2 == 1 && val3 == 1)
{
strcpy(a
[contas_validas
].
id , tmpid
); strcpy(a
[contas_validas
].
saldo , tmpsaldo
); strcpy(a
[contas_validas
].
limite_saldo , tmplimitecredito
); contas_validas++;
if((contas_validas%MAX)==0)
{
Conta* ptr;
ptr
=(Conta
*)realloc(a
,sizeof(Conta
)*(contas_validas
+MAX
)); if(ptr!=NULL)
{
a=ptr;
ptr=NULL;
}
}
}
else if (val1 == 0 || val2 == 0 || val3 == 0)
{
contas_invalidas++;
}
}
printf ("\nNumero de contas validas: %d\n", contas_validas
); printf ("\nNumero de contas invalidas: %d\n", contas_invalidas
); }
else{
}
}
/*
int compara_conta (Conta * c1, Conta * c2) {
if (c1 -> saldo > c2 -> saldo)
return 1;
if (c1 -> saldo = c2 -> saldo)
return 0;
if (c1 -> saldo < c2 -> saldo)
return -1;
}
*/
int main() {
FILE
* fp
= fopen("contas-final.txt" , "w+"); Conta
* guardar_conta
=(Conta
*)malloc(sizeof(Conta
)*MAX
); contas(guardar_conta);
long int somatorioInicial = 0;
int i = 0;
for ( i ; i< contas_validas ; i++){
somatorioInicial
+= atoi(guardar_conta
[i
].
saldo); }
printf("\n%d", somatorioInicial
); /* ATENÇÂO AO COMENTÁRIO DE CIMA */ movimentos(guardar_conta);
int n;
for ( n=0 ; n<contas_validas ; n++){
fprintf(fp
, "%s %s %s\n" , guardar_conta
[n
].
id , guardar_conta
[n
].
saldo ,guardar_conta
[n
].
limite_saldo); }
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2RlZmluZSBNQVggMTAKCmludCBjb250YXNfdmFsaWRhcyA9IDA7CmludCBjb250YXNfaW52YWxpZGFzID0gMDsKaW50IG1vdmltZW50b3NfdmFsaWRvcyA9IDA7CmludCBtb3ZpbWVudG9zX2ludmFsaWRvcyA9MDsKCnR5cGVkZWYgc3RydWN0IGNvbnRhIHsKICAgIGNoYXIgc2FsZG9bMTAwMDAwMF07CiAgICBjaGFyIGxpbWl0ZV9zYWxkb1sxMDAwMDAwXTsKICAgIGNoYXIgaWRbMTFdOwp9IENvbnRhOwoKdHlwZWRlZiBzdHJ1Y3QgbW92aW1lbnRvIHsKICAgIGludCB0aXBvX21vdmltZW50bzsKICAgIGludCBvcGNhbzsKfSBNb3ZpbWVudG87CgppbnQgdmFsaWRhcl9pZChjaGFyKiBpZCl7CgogICAgaWYgKGlkWzNdID09ICctJyAmJiBpZFs5XSA9PSAnLScgJiYgaWRbMTFdID09ICdcMCcpewoKCQkJaW50IGkgPSAwOwoKCQkJZm9yKGkgPSAwOyBpIDwgMTE7IGkrKyl7CgkJCQlpZihpICE9IDMgJiYgaSAhPSA5KXsKCQkJCQlpZihpc2RpZ2l0KGlkW2ldKSA9PSAwKXsKCQkJCQkJcmV0dXJuIDA7CgkJCQkJfQoJCQkJfQoJCQl9Cgl9CgllbHNlewoJCXJldHVybiAwOwoJfQoJcmV0dXJuIDE7Cn0KCmludCB2YWxpZGFyX2lkMiAoY2hhciogaWQpIHsKCiAgICBpbnQgY29tcG9uZW50ZV9hID0gKChpZFswXS0nMCcpKyAoaWRbMV0tJzAnKSsoaWRbMl0tJzAnKSk7CiAgICBpbnQgY29tcG9uZW50ZV9iID0gKChpZFs0XS0nMCcpKyAoaWRbNV0tJzAnKSsoaWRbNl0tJzAnKSsoaWRbN10tJzAnKSsoaWRbOF0tJzAnKSk7CiAgICBpbnQgY29tcG9uZW50ZV9jID0gKGlkWzEwXS0nMCcpOwoKICAgIGludCBzb21hMSA9IGNvbXBvbmVudGVfYTsKICAgIGludCBzb21hMiA9IGNvbXBvbmVudGVfYSArIGNvbXBvbmVudGVfYjsKICAgIGludCByZXN0byA9IHNvbWEyICUgc29tYTE7CgogICAgaWYgKHJlc3RvID09IGNvbXBvbmVudGVfYykgewogICAgICAgIHJldHVybiAxOwogICAgfQoJZWxzZSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KCmludCB2YWxpZGFyX3NhbGRvKGNoYXIgKnN0cikgewoJZnByaW50ZihzdGRlcnIsICJERUJVRzogdmFsb3IgcGFzc2FkbzogWyVzXVxuIiwgc3RyKTsKICAgIGlmICgqc3RyID09ICctJykgc3RyKys7CiAgICBpZiAoIWlzZGlnaXQoKHVuc2lnbmVkIGNoYXIpKnN0cikpIHJldHVybiAwOyAvKiBlbXB0eSBzdHJpbmdzIHJldHVybiBmYWxzZSAqLwogICAgd2hpbGUgKCpzdHIpIHsKICAgICAgICBpZiAoIWlzZGlnaXQoKHVuc2lnbmVkIGNoYXIpKnN0cikpIHJldHVybiAwOwogICAgICAgIHN0cisrOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCmludCBpc192YWxpZF9uX2NoYXJzKGNoYXIgKiBzdHJpbmcsIHNpemVfdCBzaXplLCBjaGFyICogY2hhcnMpIHsKICBpbnQgc2luZGV4ID0gMCwgY2luZGV4ID0gMDsKCiAgLy8gY2ljbG8gZGUgdmFsaWRhw6fDo28gZGEgc3RyaW5nIGRhZGEKICB3aGlsZShzaW5kZXggPCBzaXplICYmIHN0cmluZ1tzaW5kZXhdICE9ICdcMCcpIHsKICAgIC8vIHBlc3F1aXNhIGRvIGNhcmFjdGVyIGl0ZXJhZG8gbmEgbGlzdGEgZGUgY2FyYWN0ZXJlcyB2w6FsaWRvcwogICAgZm9yIChjaW5kZXggPSAwOwogICAgICAgICBjaGFyc1tjaW5kZXhdICE9ICdcMCcgJiYgc3RyaW5nW3NpbmRleF0gIT0gY2hhcnNbY2luZGV4XTsKICAgICAgICAgY2luZGV4KyspIC8qIHZvaWQgKi87CgogICAgLy8gdmVyaWZpY2HDp8OjbyBzZSBvIGNhcmFjdGVyIGZvaSBlbmNvbnRyYWRvCiAgICBpZiAoY2hhcnNbY2luZGV4XSA9PSAnXDAnKQogICAgICByZXR1cm4gMDsKCiAgICAvLyBpbmNyZW1lbnRvIGRhIGl0ZXJhw6fDo28KICAgIHNpbmRleCsrOwogIH0KCiAgLy8gw6kgdsOhbGlkbyBzZSBjaGVnb3UgYW8gZmltIGRhIHN0cmluZyBjb20gdG9kb3Mgb3MgY2FyYWN0ZXJlcyB2YWxpZGFkb3MKICAvLyAodmVyaWZpY2HDp8OjbyBkZSBzdHJpbmdbc2luZGV4XSA9PSAnXDAnIG1hcyBzaW5kZXggPCBzaXplKQogIHJldHVybiBzaW5kZXggPT0gc2l6ZTsKfQoKaW50IGlzX3ZhbGlkX2NoYXJzKGNoYXIgKiBzdHJpbmcsIGNoYXIgKiBjaGFycykgewogIHJldHVybiBpc192YWxpZF9uX2NoYXJzKHN0cmluZywgc3RybGVuKHN0cmluZyksIGNoYXJzKTsKfQoKaW50IGlzX3ZhbGlkX25fbnVtYmVyKGNoYXIgKiBzdHJpbmcsIHNpemVfdCBzaXplKSB7CiAgcmV0dXJuIGlzX3ZhbGlkX25fY2hhcnMoc3RyaW5nLCBzaXplLCAiMDEyMzQ1Njc4OSIpOwp9CgppbnQgaXNfdmFsaWRfbnVtYmVyKGNoYXIgKiBzdHJpbmcpIHsKICByZXR1cm4gaXNfdmFsaWRfbl9udW1iZXIoc3RyaW5nLCBzdHJsZW4oc3RyaW5nKSk7Cn0KCmludCB2YWxpZGFyX21vdmltZW50byAoY2hhciAqIG1vdil7CiAgICBpZiAobW92WzBdID09IDApewogICAgICAgIHByaW50ZiAoIlRyYW5zZmVyZW5jaWEuXG4iKTsKICAgIH0KCWVsc2UgaWYgKG1vdlswXSA9PSAxKXsKICAgICAgICBwcmludGYgKCJEZXBvc2l0by5cbiIpOwogICAgfQoJZWxzZSBpZiAobW92WzBdID09IDIpewogICAgICAgIHByaW50ZiAoIkxldmFudGFtZW50by5cbiIpOwogICAgfQoJZWxzZXsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiAwOwp9Cgp2b2lkIHRyYW5zZmVyZW5jaWEgKCBDb250YSogIGEgLCBjaGFyIGlkW10gLCBjaGFyIGlkMltdICwgY2hhciB2YWxvcltdICl7CglpbnQgaT0wOwoJaW50IGo9MDsKCWludCB2YWxvcjE7CglpbnQgdmFsb3IyOwogCglmb3IgKCBpOyBpPGNvbnRhc192YWxpZGFzIDsgaSsrKXsKCQlpZihzdHJjbXAoIGFbaV0uaWQgLCBpZCApID09IDApCgkJCWJyZWFrOwoJfQogCglmb3IgKCBqIDsgajxjb250YXNfdmFsaWRhcyA7IGorKyl7CgkJaWYoc3RyY21wKCBhW2pdLmlkICwgaWQyKSA9PSAwKQoJCQlicmVhazsKCX0KIAoJdmFsb3IxID0gYXRvaShhW2ldLnNhbGRvKTsKCXZhbG9yMSAtPSBhdG9pKHZhbG9yKTsKCXZhbG9yMiA9IGF0b2koYVtqXS5zYWxkbyk7Cgl2YWxvcjIgKz0gYXRvaSh2YWxvcik7CiAKCXNucHJpbnRmKCBhW2ldLnNhbGRvICwgc2l6ZW9mKGFbaV0uc2FsZG8pICwgIiVkIiAsIHZhbG9yMSk7CglzbnByaW50ZiggYVtqXS5zYWxkbyAsIHNpemVvZihhW2pdLnNhbGRvKSAsICIlZCIgLCB2YWxvcjIpOwp9Cgp2b2lkIGRlcG9zaXRvICggQ29udGEqIGEgLCBjaGFyIGlkW10gLCBjaGFyIHZhbG9yW10gKXsKCWludCB2YWxvcjE7CglpbnQgaT0wOwoJCglmb3IgKCBpIDsgaTxjb250YXNfdmFsaWRhcyA7IGkrKyApewoJCWlmKHN0cmNtcCggYVtpXS5pZCAsIGlkICkgPT0gMCkKCQlicmVhazsKCX0KCgl2YWxvcjEgPSBhdG9pKGFbaV0uc2FsZG8pOwoJdmFsb3IxICs9IGF0b2kodmFsb3IpOwoJc25wcmludGYoIGFbaV0uc2FsZG8gLCBzaXplb2YoYVtpXS5zYWxkbykgLCAiJWQiICwgdmFsb3IxKTsKfQoKdm9pZCBsZXZhbnRhbWVudG8gKCBDb250YSogYSAsIGNoYXIgaWRbXSAsIGNoYXIgdmFsb3JbXSApewoJaW50IHZhbG9yMTsKCWludCBpPTA7CgoJZm9yICggaSA7IGk8Y29udGFzX3ZhbGlkYXMgOyBpKysgKXsKCQlpZihzdHJjbXAoIGFbaV0uaWQgLCBpZCApID09IDApCgkJCWJyZWFrOwoJfQoKCXZhbG9yMSA9IGF0b2koYVtpXS5zYWxkbyk7Cgl2YWxvcjEgLT0gYXRvaSh2YWxvcik7CglzbnByaW50ZiggYVtpXS5zYWxkbyAsIHNpemVvZihhW2ldLnNhbGRvKSAsICIlZCIgLCB2YWxvcjEpOwp9CgppbnQgdmFsaWRhX29wY2FvX21vdiAoIGNoYXIgYVtdKQp7CglpZiAoIGFbMF0gPT0gJzAnIHx8IGFbMF0gPT0gJzEnIHx8IGFbMF0gPT0gJzInKQoJCXJldHVybiAxOwoJZWxzZSAKCQlyZXR1cm4gMDsKfQoKdm9pZCBtb3ZpbWVudG9zIChDb250YSogZ3VhcmRhcl9jb250YSkKewoKICAgIEZJTEUgKiBmcCA9IGZvcGVuICgibW92aW1lbnRvcy50eHQiLCAiciIpOwoKICAgIGlmIChmcCAhPSBOVUxMKQoJewoKCQljaGFyIHRlbXBbMjU1KzFdOwogICAgICAgIGNoYXIgKiBjb21wb25lbnRlczsKICAgICAgICBpbnQgY29udGFkb3IgPSAwOwoJCWNoYXIgb3BlcmFjYW9bMV07CgkJY2hhciBpZF9vcmlnZW1bMTFdOwoJCWNoYXIgaWRfZGVzdGlub1sxMV07CgkJY2hhciB2YWxvclsxMDAwMDAwXTsKCiAgICAgICAgd2hpbGUgKGZnZXRzKHRlbXAsIDI1NSsxLCBmcCkgIT0gTlVMTCkKCQl7CgkJCXByaW50ZiAoIlxuLT4gJXNcblxuIiwgdGVtcCk7CgkJCWNvbnRhZG9yID0gMDsKCQkJCgkJCWludCBsYXN0ID0gc3RybGVuICh0ZW1wKTsKICAgICAgICAgICAgaWYgKHRlbXBbbGFzdC0xXSA9PSAnXG4nKQoJCQkJdGVtcFtsYXN0LTFdID0gJ1wwJzsKCQkJCQogICAgICAgICAgICBjb21wb25lbnRlcyA9IHN0cnRvayAodGVtcCwgIiAiKTsKCQkJCgkJCXdoaWxlIChjb21wb25lbnRlcyAhPSBOVUxMKQoJCQl7CgkJCQoJCQkJaWYgKGNvbnRhZG9yID09IDAgKQoJCQkJewoJCQkJCXN0cmNweShvcGVyYWNhbyAsIGNvbXBvbmVudGVzKTsKCQkJCQl2YWxpZGFfb3BjYW9fbW92ICggb3BlcmFjYW8gKTsKCQkJCX0KCQkJCWVsc2UgaWYoY29udGFkb3IgPT0gMSkKCQkJCXsKCQkJCQlzdHJjcHkoIGlkX29yaWdlbSAsIGNvbXBvbmVudGVzKTsKCQkJCX0KCQkJCWVsc2UgaWYoY29udGFkb3IgPT0gMikKCQkJCXsKCQkJCQlpZiAoIG9wZXJhY2FvWzBdID09ICcwJykKCQkJCQkJc3RyY3B5KGlkX2Rlc3Rpbm8gLCBjb21wb25lbnRlcyk7CgkJCQkJaWYgKCBvcGVyYWNhb1swXSA9PSAnMScgfHwgb3BlcmFjYW9bMF0gPT0gJzInICkKCQkJCQkJc3RyY3B5KCB2YWxvciAsIGNvbXBvbmVudGVzICk7CgkJCQl9CgkJCQllbHNlIGlmKCBjb250YWRvcj09IDMpCgkJCQkJewoJCQkJCQlpZiAoIG9wZXJhY2FvWzBdID09ICcwJykKCQkJCQkJCXN0cmNweSggdmFsb3IgLCBjb21wb25lbnRlcyApOwoJCQkJCQllbHNlCgkJCQkJCXsKCQkJCQkJCXByaW50ZiggIk1vdmltZW50byBpbnZhbGlkb1xuIik7CgkJCQkJCQltb3ZpbWVudG9zX2ludmFsaWRvcysrOwoJCQkJCQl9CgkJCQkJfQogICAgICAgIAoJCQkJY29tcG9uZW50ZXMgPSBzdHJ0b2sgKE5VTEwsICIgIik7CgkJCQljb250YWRvcisrOwoJCQl9CgkJCWlmICggb3BlcmFjYW9bMF0gPT0gJzAnICkKCQkJCXRyYW5zZmVyZW5jaWEoIGd1YXJkYXJfY29udGEgLCBpZF9vcmlnZW0gLCBpZF9kZXN0aW5vICwgdmFsb3IpOwoJCQlpZiAoIG9wZXJhY2FvWzBdID09ICcxJyApCgkJCQlkZXBvc2l0byAoIGd1YXJkYXJfY29udGEgLCBpZF9vcmlnZW0gLCB2YWxvciApOwoJCQlpZiAoIG9wZXJhY2FvWzBdID09ICcyJyApCgkJCQlsZXZhbnRhbWVudG8oIGd1YXJkYXJfY29udGEgLCBpZF9vcmlnZW0gLCB2YWxvciApOwoJCX0KCQlmY2xvc2UoZnApOwoJfQp9Cgp2b2lkIGNvbnRhcyAoQ29udGEqIGEpewoKCUZJTEUqIGZwID0gZm9wZW4gKCJjb250YXMudHh0IiwgInIiKTsgLy8iciIgLT4gbGVpdHVyYSAobW9kbyB0ZXh0bykgb3UgImIiIC0+IGxlaXR1cmEgKG1vZG8gYmluYXJpbykKCUZJTEUqIGZwMiA9IGZvcGVuICgic3RhdHMudHh0IiwgInciKTsKCgogICAgaWYgKGZwICE9IE5VTEwpewoKCQkJY2hhciB0bXBpZFsxMV07CgkJCWNoYXIgdG1wc2FsZG9bMTAwMDAwMF07CgkJCWNoYXIgdG1wbGltaXRlY3JlZGl0b1sxMDAwMDAwXTsKICAgICAgICAgICAgY2hhciBjb250YXNbMjU1KzFdOwogICAgICAgICAgICBjaGFyKiB0ZW1wX2lkWzExKzFdOwogICAgICAgICAgICBjaGFyKiBjb21wb25lbnRlczsKICAgICAgICAgICAgaW50IGNvbnRhZG9yID0gMDsKICAgICAgICAgICAgaW50IHZhbDE7CiAgICAgICAgICAgIGludCB2YWwyOwogICAgICAgICAgICBpbnQgdmFsMzsKCiAgICAgICAgICAgIHByaW50ZiAoIkFzIGNvbnRhcyBleGlzdGVudGVzIG5vIGZpY2hlaXJvIHNhbzpcbiIpOwoKICAgICAgICAgICAgd2hpbGUgKGZnZXRzKGNvbnRhcywgMjU1KzEsIGZwKSAhPSBOVUxMKQoJCQl7CgkJCQlwcmludGYgKCJcbi0+ICVzXG5cbiIsIGNvbnRhcyk7CiAgICAgICAgICAgICAgICBjb250YWRvciA9IDA7CgogICAgICAgICAgICAgICAgaW50IGxhc3QgPSBzdHJsZW4gKGNvbnRhcyk7CiAgICAgICAgICAgICAgICBpZiAoY29udGFzW2xhc3QtMV0gPT0gJ1xuJykKICAgICAgICAgICAgICAgICAgICBjb250YXNbbGFzdC0xXSA9ICdcMCc7CgoJCQkJY29tcG9uZW50ZXMgPSBzdHJ0b2sgKGNvbnRhcywgIiAiKTsKCgkJCQl3aGlsZSAoY29tcG9uZW50ZXMgIT0gTlVMTCkKCQkJCXsKCgkJCQkJaWYgKGNvbnRhZG9yID09IDApCgkJCQkJewoKCQkJCQkJcHJpbnRmICgiLSBJRCA9ICVzXG4iLCBjb21wb25lbnRlcyk7CgkJCQkJCXN0cmNweSh0bXBpZCAsIGNvbXBvbmVudGVzKTsKCQkJCQkJaW50IHZhbGlkbyA9IHZhbGlkYXJfaWQgKGNvbXBvbmVudGVzKTsKCQkJCQkJaW50IHZhbGlkbzIgPSB2YWxpZGFyX2lkMiAoY29tcG9uZW50ZXMpOwoKCQkJCQkJaWYgKHZhbGlkbyA9PSAxICYmIHZhbGlkbzIgPT0gMSkKCQkJCQkJewoJCQkJCQkJcHJpbnRmICgiSUQgdmFsaWRvIVxuIik7CgkJCQkJCQl2YWwxID0gMTsKCQkJCQkJfQoJCQkJCQllbHNlIAoJCQkJCQl7CgkJCQkJCQlwcmludGYgKCJJRCBpbnZhbGlkbyFcbiIpOwoJCQkJCQkJdmFsMSA9IDA7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZSBpZiAoY29udGFkb3IgPT0gMSkKCQkJCQl7CgkJCQkJCXN0cmNweSh0bXBzYWxkbyAsIGNvbXBvbmVudGVzKTsKCQkJCQkJaW50IHZhbGlkbyA9IHZhbGlkYXJfc2FsZG8oY29tcG9uZW50ZXMpOwoJCQkJCQlpZiAodmFsaWRvID09IDEpCgkJCQkJCXsKCQkJCQkJCXByaW50ZiAoIi0gU2FsZG86ICVzXG4iLCBjb21wb25lbnRlcyk7CgkJCQkJCQl2YWwyID0gMTsKCQkJCQkJfQoJCQkJCQllbHNlCgkJCQkJCXsKCQkJCQkJCXByaW50ZiAoIlNhbGRvIGludmFsaWRvIVxuIik7CgkJCQkJCQl2YWwyID0gMDsKCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlIGlmIChjb250YWRvciA9PSAyKQoJCQkJCXsKCQkJCQkJc3RyY3B5KHRtcGxpbWl0ZWNyZWRpdG8gLCBjb21wb25lbnRlcyk7CgkJCQkJCWludCB2YWxpZG8gPSAgaXNfdmFsaWRfbnVtYmVyKGNvbXBvbmVudGVzKTsKCQkJCQkJLyogQVRFTsOHw4JPIEFPIEZBQ1RPIERFIE7Dg08gSEFWRVIgQ09NUE9ORU5URSkgKi8KCQkJCQkJaWYgKHZhbGlkbyA9PSAxKQoJCQkJCQl7CgkJCQkJCQlwcmludGYgKCItIExpbWl0ZSBkZSBjcmVkaXRvOiAlc1xuIiwgY29tcG9uZW50ZXMpOwoJCQkJCQkJdmFsMyA9IDE7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQlwcmludGYgKCJMaW1pdGUgZGUgY3JlZGl0byBpbnZhbGlkbyFcbiIpOwoJCQkJCQkJdmFsMyA9IDA7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCWNvbXBvbmVudGVzID0gc3RydG9rIChOVUxMLCAiICIpOwoJCQkJCWNvbnRhZG9yKys7CgoJCQkJfQoKCQkJCWlmICh2YWwxID09IDEgJiYgdmFsMiA9PSAxICYmIHZhbDMgPT0gMSkKCQkJCXsKCgkJCQkJCXN0cmNweShhW2NvbnRhc192YWxpZGFzXS5pZCAsIHRtcGlkKTsKCQkJCQkJc3RyY3B5KGFbY29udGFzX3ZhbGlkYXNdLnNhbGRvICwgdG1wc2FsZG8pOwoJCQkJCQlzdHJjcHkoYVtjb250YXNfdmFsaWRhc10ubGltaXRlX3NhbGRvICwgdG1wbGltaXRlY3JlZGl0byk7CgkJCQkJCWNvbnRhc192YWxpZGFzKys7CgkJCQkJCWlmKChjb250YXNfdmFsaWRhcyVNQVgpPT0wKQoJCQkJCQl7CgkJCQkJCQlDb250YSogcHRyOwoJCQkJCQkJcHRyPShDb250YSopcmVhbGxvYyhhLHNpemVvZihDb250YSkqKGNvbnRhc192YWxpZGFzK01BWCkpOwoJCQkJCQkJaWYocHRyIT1OVUxMKQoJCQkJCQkJewoJCQkJCQkJCWE9cHRyOwoJCQkJCQkJCXB0cj1OVUxMOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmICh2YWwxID09IDAgfHwgdmFsMiA9PSAwIHx8IHZhbDMgPT0gMCkKCQkJCXsKICAgICAgICAgICAgICAgICAgICBjb250YXNfaW52YWxpZGFzKys7CgkJCQl9CiAgICAgICAgICAgIH0KCQkJCgkJCWZjbG9zZShmcCk7CgoJCQlwcmludGYgKCJcbk51bWVybyBkZSBjb250YXMgdmFsaWRhczogJWRcbiIsIGNvbnRhc192YWxpZGFzKTsKCQkJcHJpbnRmICgiXG5OdW1lcm8gZGUgY29udGFzIGludmFsaWRhczogJWRcbiIsIGNvbnRhc19pbnZhbGlkYXMpOwogICAgfQogICAgZWxzZXsKCQlwcmludGYgKCJFcnJvIVxuIik7CiAgICB9Cn0KLyoKaW50IGNvbXBhcmFfY29udGEgKENvbnRhICogYzEsIENvbnRhICogYzIpIHsKICAgICAgICBpZiAoYzEgLT4gc2FsZG8gPiBjMiAtPiBzYWxkbykKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgaWYgKGMxIC0+IHNhbGRvID0gYzIgLT4gc2FsZG8pCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIGlmIChjMSAtPiBzYWxkbyA8IGMyIC0+IHNhbGRvKQogICAgICAgICAgICByZXR1cm4gLTE7Cn0KKi8KCmludCBtYWluKCkgewoKCUZJTEUgKiBmcCA9IGZvcGVuKCJjb250YXMtZmluYWwudHh0IiAsICJ3KyIpOwoJQ29udGEqIGd1YXJkYXJfY29udGE9KENvbnRhKiltYWxsb2Moc2l6ZW9mKENvbnRhKSpNQVgpOwogICAgY29udGFzKGd1YXJkYXJfY29udGEpOwoJbG9uZyBpbnQgc29tYXRvcmlvSW5pY2lhbCA9IDA7CglpbnQgaSA9IDA7Cglmb3IgKCBpICA7IGk8IGNvbnRhc192YWxpZGFzIDsgaSsrKXsKICAgICAgIHNvbWF0b3Jpb0luaWNpYWwgKz0gYXRvaShndWFyZGFyX2NvbnRhW2ldLnNhbGRvKTsKCX0KCXByaW50ZigiXG4lZCIsIHNvbWF0b3Jpb0luaWNpYWwpOyAvKiBBVEVOw4fDgk8gQU8gQ09NRU5Uw4FSSU8gREUgQ0lNQSAqLwogICAgcHJpbnRmKCJcbiIpOwoJbW92aW1lbnRvcyhndWFyZGFyX2NvbnRhKTsKCWludCBuOwoJZm9yICggbj0wIDsgbjxjb250YXNfdmFsaWRhcyA7IG4rKyl7CgkJZnByaW50ZihmcCAsICIlcyAlcyAlc1xuIiAsIGd1YXJkYXJfY29udGFbbl0uaWQgLCBndWFyZGFyX2NvbnRhW25dLnNhbGRvICxndWFyZGFyX2NvbnRhW25dLmxpbWl0ZV9zYWxkbyk7Cgl9CglmY2xvc2UoZnApOwoKICAgIHJldHVybiAwOwp9