#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
typedef struct{
char **words;
size_t currentSize;
size_t capacity;
}Words;
typedef struct {
bool up,down,right,left,upRight,upLeft,downRight,downLeft;
}Direction;
void startALloc (Words *words){
words
->words
= (char**) malloc(10 * sizeof(char*)); words->capacity = 10;
words->currentSize = 0;
}
void resize (Words *words){
if (words->currentSize == words->capacity){
words->capacity = words->capacity * 2 + 4;
words
->words
= (char**) realloc(words
->words
,words
->capacity
* sizeof (char*)); }
}
void removeWhitespace(char *str) {
size_t i = 1, j = 0;
while (str[i] != '\0' ) {
str[j++] = str[i];
}
i++;
}
str[j] = '\0';
}
void makeString (Words words, size_t lenOfWords,int** usableWords){
size_t count = 1;
for (size_t i = 0; i < words.currentSize; ++i) {
for (size_t j = 0; j < lenOfWords-1; ++j) {
if (words.words[i][j] != '.' && usableWords[i][j] != 1){
printf("%c",words.
words[i
][j
]); if (count == 60){
count = 0;
}
count++;
}
}
}
if (count != 1)
}
void removeUp (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t r = row - i;
usableWords[r][col] = 1;
}
}
void removeDown (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t r = row + i;
usableWords[r][col] = 1;
}
}
void removeLeft (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t c = col - i;
usableWords[row][c] = 1;
}
}
void removeRight (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t c = col + i;
usableWords[row][c] = 1;
}
}
void removeUpLeft (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t r = row - i;
size_t c = col - i;
usableWords[r][c] = 1;
}
}
void removeUpRight (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t r = row - i;
size_t c = col + i;
usableWords[r][c] = 1;
}
}
void removeDownLeft (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t r = row + i;
size_t c = col - i;
usableWords[r][c] = 1;
}
}
void removeDownRight (size_t len, size_t row , size_t col, int** usableWords) {
for (size_t i = 0; i < len; i++) {
size_t r = row + i;
size_t c = col + i;
usableWords[r][c] = 1;
}
}
bool checkUp (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t r = row - i;
if (words.words[r][col] != subStr[i]) {
return false;
}
}
return true;
}
bool checkDown (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t r = row + i;
if (words.words[r][col] != subStr[i]) {
return false;
}
}
return true;
}
bool checkRight (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t c = col + i;
if (words.words[row][c] != subStr[i]) {
return false;
}
}
return true;
}
bool checkLeft (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t c = col - i;
if (words.words[row][c] != subStr[i]) {
return false;
}
}
return true;
}
bool checkUpRight (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t r = row - i;
size_t c = col + i;
if (words.words[r][c] != subStr[i]) {
return false;
}
}
return true;
}
bool checkUpLeft (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t r = row - i;
size_t c = col - i;
if (words.words[r][c] != subStr[i]) {
return false;
}
}
return true;
}
bool checkDownRight (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t r = row + i;
size_t c = col + i;
if (words.words[r][c] != subStr[i]) {
return false;
}
}
return true;
}
bool checkDownLeft (Words words , char *subStr , size_t row , size_t col){
for (size_t i = 0; i < len; i++) {
size_t r = row + i;
size_t c = col - i;
if (words.words[r][c] != subStr[i]) {
return false;
}
}
return true;
}
void findSubStr
(Words words
, char *subStr
, int** usableWords
, size_t lenOfWords
, bool
remove){ size_t len,count;
Direction dir;
char leadingAlpha = subStr[0];
count = 0;
for (size_t row = 0; row < words.currentSize; ++row) {
for (size_t col = 0; col < lenOfWords; ++col) {
if (words.words[row][col] == leadingAlpha){
dir.up = row+1 >= len ? true : false;
dir.down = words.currentSize-row >= len ? true : false;
dir.right = lenOfWords-col >= len ? true : false;
dir.left = col+1 >= len ? true : false;
dir.upLeft = dir.up && dir.left ? true : false;
dir.upRight = dir.up && dir.right ? true : false;
dir.downLeft = dir.down && dir.left ? true : false;
dir.downRight = dir.down && dir.right ? true : false;
if (dir.up && checkUp(words,subStr,row,col)){
removeUp
(strlen(subStr
),row
,col
,usableWords
); }
count++;
}
if (dir.down && checkDown(words,subStr,row,col)) {
removeDown
(strlen(subStr
),row
,col
,usableWords
); }
count++;
};
if (dir.right && checkRight(words,subStr,row,col)) {
removeRight
(strlen(subStr
),row
,col
,usableWords
); }
count++;
};
if (dir.left && checkLeft(words,subStr,row,col)){
removeLeft
(strlen(subStr
),row
,col
,usableWords
); }
count++;
};
if (dir.upLeft && checkUpLeft(words,subStr,row,col)){
removeUpLeft
(strlen(subStr
),row
,col
,usableWords
); }
count++;
};
if (dir.upRight && checkUpRight(words,subStr,row,col)){
removeUpRight
(strlen(subStr
),row
,col
,usableWords
); }
count++;
};
if (dir.downLeft && checkDownLeft(words,subStr,row,col)) {
removeDownLeft
(strlen(subStr
),row
,col
,usableWords
); }
count++;
};
if (dir.downRight && checkDownRight(words,subStr,row,col)) {
removeDownRight
(strlen(subStr
),row
,col
,usableWords
); }
count++;
};
}
}
}
printf("%s: %zux\n",subStr
,count
); }
int main (void){
Words words;
startALloc(&words);
words.currentSize = 0;
size_t buffer;
size_t lenOfWords = 0;
size_t currentLen;
while ((currentLen = getline(&words.words[words.currentSize],&buffer,stdin)) != (size_t)EOF){
if (words.currentSize == 0){
lenOfWords = currentLen;
}
if (words.words[0][0] == '\n'){
return 0;
}
if (words.currentSize > 0 && currentLen == 1 && words.words[words.currentSize][0] == '\n')
break;
if (currentLen != lenOfWords){
return 0;
}
for (size_t i = 0; i < lenOfWords-1; ++i) {
if ((words.words[words.currentSize][i] < 'a' || words.words[words.currentSize][i] > 'z') && words.words[words.currentSize][i] != '.'){
return 0;
}
}
words.currentSize++;
resize(&words);
}
int **usableWords
= (int **) calloc(words.
currentSize+10,sizeof (int*)); for (size_t i = 0; i < words.currentSize; ++i) {
usableWords
[i
] = (int *)calloc(lenOfWords
+10,sizeof (int)); }
char* subStr = NULL;
size_t mem;
while (getline(&subStr,&mem,stdin) != EOF){
if (subStr[0] == '?'){
return 0;
}
makeString(words,lenOfWords,usableWords);
}
else if (subStr[0] == '#'){
removeWhitespace(subStr);
size_t lenOfSubStr
= strlen(subStr
); if (lenOfSubStr < 2){
return 0;
}
for (size_t i = 0; i < lenOfSubStr; ++i) {
if (subStr[i] < 'a' || subStr[i] > 'z'){
return 0;
}
}
findSubStr
(words
,subStr
,usableWords
,lenOfWords
,remove); }
else if (subStr[0] == '-'){
removeWhitespace(subStr);
size_t lenOfSubStr
= strlen(subStr
); if (lenOfSubStr < 2){
return 0;
}
for (size_t i = 0; i < lenOfSubStr; ++i) {
if (subStr[i] < 'a' || subStr[i] > 'z'){
return 0;
}
}
findSubStr
(words
,subStr
,usableWords
,lenOfWords
,remove); }
else{
return 0;
}
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGJvb2wuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCgp0eXBlZGVmIHN0cnVjdHsKICAgIGNoYXIgKip3b3JkczsKICAgIHNpemVfdCBjdXJyZW50U2l6ZTsKICAgIHNpemVfdCBjYXBhY2l0eTsKfVdvcmRzOwoKCnR5cGVkZWYgc3RydWN0IHsKICAgIGJvb2wgdXAsZG93bixyaWdodCxsZWZ0LHVwUmlnaHQsdXBMZWZ0LGRvd25SaWdodCxkb3duTGVmdDsKfURpcmVjdGlvbjsKCnZvaWQgc3RhcnRBTGxvYyAoV29yZHMgKndvcmRzKXsKICAgIHdvcmRzLT53b3JkcyA9IChjaGFyKiopIG1hbGxvYygxMCAqIHNpemVvZihjaGFyKikpOwogICAgd29yZHMtPmNhcGFjaXR5ID0gMTA7CiAgICB3b3Jkcy0+Y3VycmVudFNpemUgPSAwOwp9Cgp2b2lkIHJlc2l6ZSAoV29yZHMgKndvcmRzKXsKICAgIGlmICh3b3Jkcy0+Y3VycmVudFNpemUgPT0gd29yZHMtPmNhcGFjaXR5KXsKICAgICAgICB3b3Jkcy0+Y2FwYWNpdHkgPSB3b3Jkcy0+Y2FwYWNpdHkgKiAyICsgNDsKICAgICAgICB3b3Jkcy0+d29yZHMgPSAoY2hhcioqKSByZWFsbG9jKHdvcmRzLT53b3Jkcyx3b3Jkcy0+Y2FwYWNpdHkgKiBzaXplb2YgKGNoYXIqKSk7CiAgICB9Cn0KCnZvaWQgcmVtb3ZlV2hpdGVzcGFjZShjaGFyICpzdHIpIHsKICAgIHNpemVfdCBpID0gMSwgaiA9IDA7CgogICAgd2hpbGUgKHN0cltpXSAhPSAnXDAnICkgewogICAgICAgIGlmICghaXNzcGFjZShzdHJbaV0pKSB7CiAgICAgICAgICAgIHN0cltqKytdID0gc3RyW2ldOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICB9CiAgICBzdHJbal0gPSAnXDAnOwp9CgoKdm9pZCBtYWtlU3RyaW5nIChXb3JkcyB3b3Jkcywgc2l6ZV90IGxlbk9mV29yZHMsaW50KiogdXNhYmxlV29yZHMpewogICAgc2l6ZV90IGNvdW50ID0gMTsKICAgIHByaW50ZigiVGFqZW5rYTpcbiIpOwoKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgd29yZHMuY3VycmVudFNpemU7ICsraSkgewoKICAgICAgICBmb3IgKHNpemVfdCBqID0gMDsgaiA8IGxlbk9mV29yZHMtMTsgKytqKSB7CgogICAgICAgICAgICBpZiAod29yZHMud29yZHNbaV1bal0gIT0gJy4nICYmIHVzYWJsZVdvcmRzW2ldW2pdICE9IDEpewogICAgICAgICAgICAgICAgcHJpbnRmKCIlYyIsd29yZHMud29yZHNbaV1bal0pOwogICAgICAgICAgICAgICAgaWYgKGNvdW50ID09IDYwKXsKICAgICAgICAgICAgICAgICAgICBwcmludGYoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgY291bnQgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmIChjb3VudCAhPSAxKQogICAgICAgIHByaW50ZigiXG4iKTsKfQp2b2lkIHJlbW92ZVVwIChzaXplX3QgbGVuLCBzaXplX3Qgcm93ICwgc2l6ZV90IGNvbCwgaW50KiogdXNhYmxlV29yZHMpIHsKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICBzaXplX3QgciA9IHJvdyAtIGk7CgogICAgICAgIHVzYWJsZVdvcmRzW3JdW2NvbF0gPSAxOwogICAgfQp9CnZvaWQgcmVtb3ZlRG93biAoc2l6ZV90IGxlbiwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wsIGludCoqIHVzYWJsZVdvcmRzKSB7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgc2l6ZV90IHIgPSByb3cgKyBpOwoKICAgICAgICB1c2FibGVXb3Jkc1tyXVtjb2xdID0gMTsKICAgIH0KfQp2b2lkIHJlbW92ZUxlZnQgKHNpemVfdCBsZW4sIHNpemVfdCByb3cgLCBzaXplX3QgY29sLCBpbnQqKiB1c2FibGVXb3JkcykgewogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgIHNpemVfdCBjID0gY29sIC0gaTsKCiAgICAgICAgdXNhYmxlV29yZHNbcm93XVtjXSA9IDE7CiAgICB9Cn0Kdm9pZCByZW1vdmVSaWdodCAoc2l6ZV90IGxlbiwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wsIGludCoqIHVzYWJsZVdvcmRzKSB7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgc2l6ZV90IGMgPSBjb2wgKyBpOwoKICAgICAgICB1c2FibGVXb3Jkc1tyb3ddW2NdID0gMTsKICAgIH0KfQp2b2lkIHJlbW92ZVVwTGVmdCAoc2l6ZV90IGxlbiwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wsIGludCoqIHVzYWJsZVdvcmRzKSB7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgc2l6ZV90IHIgPSByb3cgLSBpOwogICAgICAgIHNpemVfdCBjID0gY29sIC0gaTsKCiAgICAgICAgdXNhYmxlV29yZHNbcl1bY10gPSAxOwogICAgfQp9CnZvaWQgcmVtb3ZlVXBSaWdodCAoc2l6ZV90IGxlbiwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wsIGludCoqIHVzYWJsZVdvcmRzKSB7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgc2l6ZV90IHIgPSByb3cgLSBpOwogICAgICAgIHNpemVfdCBjID0gY29sICsgaTsKCiAgICAgICAgdXNhYmxlV29yZHNbcl1bY10gPSAxOwogICAgfQp9CnZvaWQgcmVtb3ZlRG93bkxlZnQgKHNpemVfdCBsZW4sIHNpemVfdCByb3cgLCBzaXplX3QgY29sLCBpbnQqKiB1c2FibGVXb3JkcykgewogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgIHNpemVfdCByID0gcm93ICsgaTsKICAgICAgICBzaXplX3QgYyA9IGNvbCAtIGk7CgogICAgICAgIHVzYWJsZVdvcmRzW3JdW2NdID0gMTsKICAgIH0KfQp2b2lkIHJlbW92ZURvd25SaWdodCAoc2l6ZV90IGxlbiwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wsIGludCoqIHVzYWJsZVdvcmRzKSB7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgc2l6ZV90IHIgPSByb3cgKyBpOwogICAgICAgIHNpemVfdCBjID0gY29sICsgaTsKCiAgICAgICAgdXNhYmxlV29yZHNbcl1bY10gPSAxOwogICAgfQp9Cgpib29sIGNoZWNrVXAgKFdvcmRzIHdvcmRzICwgY2hhciAqc3ViU3RyICwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wpewogICAgc2l6ZV90IGxlbiA9IHN0cmxlbihzdWJTdHIpOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgIHNpemVfdCByID0gcm93IC0gaTsKCiAgICAgICAgaWYgKHdvcmRzLndvcmRzW3JdW2NvbF0gIT0gc3ViU3RyW2ldKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQoKYm9vbCBjaGVja0Rvd24gKFdvcmRzIHdvcmRzICwgY2hhciAqc3ViU3RyICwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wpewogICAgc2l6ZV90IGxlbiA9IHN0cmxlbihzdWJTdHIpOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgIHNpemVfdCByID0gcm93ICsgaTsKCiAgICAgICAgaWYgKHdvcmRzLndvcmRzW3JdW2NvbF0gIT0gc3ViU3RyW2ldKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGNoZWNrUmlnaHQgKFdvcmRzIHdvcmRzICwgY2hhciAqc3ViU3RyICwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wpewogICAgc2l6ZV90IGxlbiA9IHN0cmxlbihzdWJTdHIpOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgIHNpemVfdCBjID0gY29sICsgaTsKCiAgICAgICAgaWYgKHdvcmRzLndvcmRzW3Jvd11bY10gIT0gc3ViU3RyW2ldKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGNoZWNrTGVmdCAoV29yZHMgd29yZHMgLCBjaGFyICpzdWJTdHIgLCBzaXplX3Qgcm93ICwgc2l6ZV90IGNvbCl7CiAgICBzaXplX3QgbGVuID0gc3RybGVuKHN1YlN0cik7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgc2l6ZV90IGMgPSBjb2wgLSBpOwoKICAgICAgICBpZiAod29yZHMud29yZHNbcm93XVtjXSAhPSBzdWJTdHJbaV0pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiB0cnVlOwp9CmJvb2wgY2hlY2tVcFJpZ2h0IChXb3JkcyB3b3JkcyAsIGNoYXIgKnN1YlN0ciAsIHNpemVfdCByb3cgLCBzaXplX3QgY29sKXsKICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oc3ViU3RyKTsKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICBzaXplX3QgciA9IHJvdyAtIGk7CiAgICAgICAgc2l6ZV90IGMgPSBjb2wgKyBpOwoKICAgICAgICBpZiAod29yZHMud29yZHNbcl1bY10gIT0gc3ViU3RyW2ldKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGNoZWNrVXBMZWZ0IChXb3JkcyB3b3JkcyAsIGNoYXIgKnN1YlN0ciAsIHNpemVfdCByb3cgLCBzaXplX3QgY29sKXsKICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oc3ViU3RyKTsKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICBzaXplX3QgciA9IHJvdyAtIGk7CiAgICAgICAgc2l6ZV90IGMgPSBjb2wgLSBpOwoKICAgICAgICBpZiAod29yZHMud29yZHNbcl1bY10gIT0gc3ViU3RyW2ldKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGNoZWNrRG93blJpZ2h0IChXb3JkcyB3b3JkcyAsIGNoYXIgKnN1YlN0ciAsIHNpemVfdCByb3cgLCBzaXplX3QgY29sKXsKICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oc3ViU3RyKTsKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICBzaXplX3QgciA9IHJvdyArIGk7CiAgICAgICAgc2l6ZV90IGMgPSBjb2wgKyBpOwoKICAgICAgICBpZiAod29yZHMud29yZHNbcl1bY10gIT0gc3ViU3RyW2ldKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGNoZWNrRG93bkxlZnQgKFdvcmRzIHdvcmRzICwgY2hhciAqc3ViU3RyICwgc2l6ZV90IHJvdyAsIHNpemVfdCBjb2wpewogICAgc2l6ZV90IGxlbiA9IHN0cmxlbihzdWJTdHIpOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgIHNpemVfdCByID0gcm93ICsgaTsKICAgICAgICBzaXplX3QgYyA9IGNvbCAtIGk7CgogICAgICAgIGlmICh3b3Jkcy53b3Jkc1tyXVtjXSAhPSBzdWJTdHJbaV0pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiB0cnVlOwp9CgoKdm9pZCBmaW5kU3ViU3RyKFdvcmRzIHdvcmRzLCBjaGFyICpzdWJTdHIsIGludCoqIHVzYWJsZVdvcmRzICwgc2l6ZV90IGxlbk9mV29yZHMsIGJvb2wgcmVtb3ZlKXsKICAgIHNpemVfdCBsZW4sY291bnQ7CiAgICBEaXJlY3Rpb24gZGlyOwogICAgbGVuID0gc3RybGVuKHN1YlN0cik7CiAgICBjaGFyIGxlYWRpbmdBbHBoYSA9IHN1YlN0clswXTsKICAgIGNvdW50ID0gMDsKICAgIGZvciAoc2l6ZV90IHJvdyA9IDA7IHJvdyA8IHdvcmRzLmN1cnJlbnRTaXplOyArK3JvdykgewogICAgICAgIGZvciAoc2l6ZV90IGNvbCA9IDA7IGNvbCA8IGxlbk9mV29yZHM7ICsrY29sKSB7CiAgICAgICAgICAgIGlmICh3b3Jkcy53b3Jkc1tyb3ddW2NvbF0gPT0gbGVhZGluZ0FscGhhKXsKICAgICAgICAgICAgICAgIGRpci51cCA9IHJvdysxID49IGxlbiA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgIGRpci5kb3duID0gd29yZHMuY3VycmVudFNpemUtcm93ID49IGxlbiA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgIGRpci5yaWdodCA9IGxlbk9mV29yZHMtY29sID49IGxlbiA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgIGRpci5sZWZ0ID0gY29sKzEgPj0gbGVuID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgICAgICAgICAgZGlyLnVwTGVmdCA9IGRpci51cCAmJiBkaXIubGVmdCA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgIGRpci51cFJpZ2h0ID0gZGlyLnVwICYmIGRpci5yaWdodCA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgIGRpci5kb3duTGVmdCA9IGRpci5kb3duICYmIGRpci5sZWZ0ID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgICAgICAgICAgZGlyLmRvd25SaWdodCA9IGRpci5kb3duICYmIGRpci5yaWdodCA/IHRydWUgOiBmYWxzZTsKCiAgICAgICAgICAgICAgICBpZiAoZGlyLnVwICYmIGNoZWNrVXAod29yZHMsc3ViU3RyLHJvdyxjb2wpKXsKICAgICAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKXsKICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlVXAoc3RybGVuKHN1YlN0cikscm93LGNvbCx1c2FibGVXb3Jkcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZGlyLmRvd24gJiYgY2hlY2tEb3duKHdvcmRzLHN1YlN0cixyb3csY29sKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpewogICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVEb3duKHN0cmxlbihzdWJTdHIpLHJvdyxjb2wsdXNhYmxlV29yZHMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGlmIChkaXIucmlnaHQgJiYgY2hlY2tSaWdodCh3b3JkcyxzdWJTdHIscm93LGNvbCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKXsKICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUmlnaHQoc3RybGVuKHN1YlN0cikscm93LGNvbCx1c2FibGVXb3Jkcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgaWYgKGRpci5sZWZ0ICYmIGNoZWNrTGVmdCh3b3JkcyxzdWJTdHIscm93LGNvbCkpewogICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpewogICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVMZWZ0KHN0cmxlbihzdWJTdHIpLHJvdyxjb2wsdXNhYmxlV29yZHMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGlmIChkaXIudXBMZWZ0ICYmIGNoZWNrVXBMZWZ0KHdvcmRzLHN1YlN0cixyb3csY29sKSl7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVVwTGVmdChzdHJsZW4oc3ViU3RyKSxyb3csY29sLHVzYWJsZVdvcmRzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBpZiAoZGlyLnVwUmlnaHQgJiYgY2hlY2tVcFJpZ2h0KHdvcmRzLHN1YlN0cixyb3csY29sKSl7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVVwUmlnaHQoc3RybGVuKHN1YlN0cikscm93LGNvbCx1c2FibGVXb3Jkcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgaWYgKGRpci5kb3duTGVmdCAmJiBjaGVja0Rvd25MZWZ0KHdvcmRzLHN1YlN0cixyb3csY29sKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpewogICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVEb3duTGVmdChzdHJsZW4oc3ViU3RyKSxyb3csY29sLHVzYWJsZVdvcmRzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBpZiAoZGlyLmRvd25SaWdodCAmJiBjaGVja0Rvd25SaWdodCh3b3JkcyxzdWJTdHIscm93LGNvbCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKXsKICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRG93blJpZ2h0KHN0cmxlbihzdWJTdHIpLHJvdyxjb2wsdXNhYmxlV29yZHMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHByaW50ZigiJXM6ICV6dXhcbiIsc3ViU3RyLGNvdW50KTsKfQoKCmludCBtYWluICh2b2lkKXsKCiAgICBXb3JkcyB3b3JkczsKICAgIHN0YXJ0QUxsb2MoJndvcmRzKTsKICAgIHdvcmRzLmN1cnJlbnRTaXplID0gMDsKCiAgICBzaXplX3QgYnVmZmVyOwogICAgc2l6ZV90IGxlbk9mV29yZHMgPSAwOwogICAgc2l6ZV90IGN1cnJlbnRMZW47CgogICAgcHJpbnRmKCJPc21pc21lcmthOlxuIik7CgogICAgd2hpbGUgKChjdXJyZW50TGVuID0gZ2V0bGluZSgmd29yZHMud29yZHNbd29yZHMuY3VycmVudFNpemVdLCZidWZmZXIsc3RkaW4pKSAhPSAoc2l6ZV90KUVPRil7CgogICAgICAgIGlmICh3b3Jkcy5jdXJyZW50U2l6ZSA9PSAwKXsKICAgICAgICAgICAgbGVuT2ZXb3JkcyA9IGN1cnJlbnRMZW47CiAgICAgICAgfQoKICAgICAgICBpZiAod29yZHMud29yZHNbMF1bMF0gPT0gJ1xuJyl7CiAgICAgICAgICAgIHByaW50ZigiTmVzcHJhdm55IHZzdHVwLlxuIik7CiAgICAgICAgICAgIGZyZWUod29yZHMud29yZHMpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIGlmICh3b3Jkcy5jdXJyZW50U2l6ZSA+IDAgJiYgY3VycmVudExlbiA9PSAxICYmIHdvcmRzLndvcmRzW3dvcmRzLmN1cnJlbnRTaXplXVswXSA9PSAnXG4nKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgaWYgKGN1cnJlbnRMZW4gIT0gbGVuT2ZXb3Jkcyl7CiAgICAgICAgICAgIHByaW50ZigiTmVzcHJhdm55IHZzdHVwLlxuIik7CiAgICAgICAgICAgIGZyZWUod29yZHMud29yZHMpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW5PZldvcmRzLTE7ICsraSkgewogICAgICAgICAgICBpZiAoKHdvcmRzLndvcmRzW3dvcmRzLmN1cnJlbnRTaXplXVtpXSA8ICdhJyB8fCB3b3Jkcy53b3Jkc1t3b3Jkcy5jdXJyZW50U2l6ZV1baV0gPiAneicpICYmIHdvcmRzLndvcmRzW3dvcmRzLmN1cnJlbnRTaXplXVtpXSAhPSAnLicpewogICAgICAgICAgICAgICAgcHJpbnRmKCJOZXNwcmF2bnkgdnN0dXAuXG4iKTsKICAgICAgICAgICAgICAgIGZyZWUod29yZHMud29yZHMpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd29yZHMuY3VycmVudFNpemUrKzsKICAgICAgICByZXNpemUoJndvcmRzKTsKICAgIH0KICAgIGludCAqKnVzYWJsZVdvcmRzID0gKGludCAqKikgY2FsbG9jKHdvcmRzLmN1cnJlbnRTaXplKzEwLHNpemVvZiAoaW50KikpOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCB3b3Jkcy5jdXJyZW50U2l6ZTsgKytpKSB7CiAgICAgICAgdXNhYmxlV29yZHNbaV0gPSAoaW50ICopY2FsbG9jKGxlbk9mV29yZHMrMTAsc2l6ZW9mIChpbnQpKTsKICAgIH0KICAgIGNoYXIqIHN1YlN0ciA9IE5VTEw7CiAgICBzaXplX3QgbWVtOwogICAgd2hpbGUgKGdldGxpbmUoJnN1YlN0ciwmbWVtLHN0ZGluKSAhPSBFT0YpewogICAgICAgIGlmIChzdWJTdHJbMF0gPT0gJz8nKXsKICAgICAgICAgICAgaWYgKHN0cmxlbihzdWJTdHIpICE9IDIpewogICAgICAgICAgICAgICAgcHJpbnRmKCJOZXNwcmF2bnkgdnN0dXAuXG4iKTsKICAgICAgICAgICAgICAgIGZyZWUod29yZHMud29yZHMpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWFrZVN0cmluZyh3b3JkcyxsZW5PZldvcmRzLHVzYWJsZVdvcmRzKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3ViU3RyWzBdID09ICcjJyl7CiAgICAgICAgICAgIGJvb2wgcmVtb3ZlID0gZmFsc2U7CiAgICAgICAgICAgIHJlbW92ZVdoaXRlc3BhY2Uoc3ViU3RyKTsKICAgICAgICAgICAgc2l6ZV90IGxlbk9mU3ViU3RyID0gc3RybGVuKHN1YlN0cik7CiAgICAgICAgICAgIGlmIChsZW5PZlN1YlN0ciA8IDIpewogICAgICAgICAgICAgICAgcHJpbnRmKCJOZXNwcmF2bnkgdnN0dXAuXG4iKTsKICAgICAgICAgICAgICAgIGZyZWUod29yZHMud29yZHMpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW5PZlN1YlN0cjsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3ViU3RyW2ldIDwgJ2EnIHx8IHN1YlN0cltpXSA+ICd6Jyl7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJOZXNwcmF2bnkgdnN0dXAuXG4iKTsKICAgICAgICAgICAgICAgICAgICBmcmVlKHdvcmRzLndvcmRzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5kU3ViU3RyKHdvcmRzLHN1YlN0cix1c2FibGVXb3JkcyxsZW5PZldvcmRzLHJlbW92ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN1YlN0clswXSA9PSAnLScpewogICAgICAgICAgICBib29sIHJlbW92ZSA9IHRydWU7CiAgICAgICAgICAgIHJlbW92ZVdoaXRlc3BhY2Uoc3ViU3RyKTsKICAgICAgICAgICAgc2l6ZV90IGxlbk9mU3ViU3RyID0gc3RybGVuKHN1YlN0cik7CiAgICAgICAgICAgIGlmIChsZW5PZlN1YlN0ciA8IDIpewogICAgICAgICAgICAgICAgcHJpbnRmKCJOZXNwcmF2bnkgdnN0dXAuXG4iKTsKICAgICAgICAgICAgICAgIGZyZWUod29yZHMud29yZHMpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW5PZlN1YlN0cjsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3ViU3RyW2ldIDwgJ2EnIHx8IHN1YlN0cltpXSA+ICd6Jyl7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJOZXNwcmF2bnkgdnN0dXAuXG4iKTsKICAgICAgICAgICAgICAgICAgICBmcmVlKHdvcmRzLndvcmRzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5kU3ViU3RyKHdvcmRzLHN1YlN0cix1c2FibGVXb3JkcyxsZW5PZldvcmRzLHJlbW92ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICAgIHByaW50ZigiTmVzcHJhdm55IHZzdHVwLlxuIik7CiAgICAgICAgICAgIGZyZWUod29yZHMud29yZHMpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgfQogICAgZnJlZSh3b3Jkcy53b3Jkcyk7CiAgICByZXR1cm4gMDsKfQo=