#include <stdio.h>
// FEN dedug positions
char start_position[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
char tricky_position[] = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1";
// piece encoding
enum pieces {e, P, N, B, R, Q, K, p, n, b, r, q, k, o};
// square encoding
enum squares {
a8 = 0, b8, c8, d8, e8, f8, g8, h8,
a7 = 16, b7, c7, d7, e7, f7, g7, h7,
a6 = 32, b6, c6, d6, e6, f6, g6, h6,
a5 = 48, b5, c5, d5, e5, f5, g5, h5,
a4 = 64, b4, c4, d4, e4, f4, g4, h4,
a3 = 80, b3, c3, d3, e3, f3, g3, h3,
a2 = 96, b2, c2, d2, e2, f2, g2, h2,
a1 = 112, b1, c1, d1, e1, f1, g1, h1, no_sq
};
// castling binary representation
//
// bin dec
// 0001 1 white king can castle to the king side
// 0010 2 white king can castle to the queen side
// 0100 4 black king can castle to the king side
// 1000 8 black king can castle to the queen side
//
// examples
// 1111 both sides an castle both directions
// 1001 black king => queen side
// white king => king side
// castling writes
enum castling { KC = 1, QC = 2, kc = 4, qc = 8 };
// sides to move
enum sides { white, black };
// ascii pieces
char ascii_pieces[] = ".PNBRQKpnbrqk";
// unicode pieces
char *unicode_pieces[] = {".", "♙", "♘", "♗", "♖", "♕", "♔", "♟︎", "♞", "♝", "♜", "♛", "♚"};
// encode ascii pieces
int char_pieces[] = {
['P'] = P,
['N'] = N,
['B'] = B,
['R'] = R,
['Q'] = Q,
['K'] = K,
['p'] = p,
['n'] = n,
['b'] = b,
['r'] = r,
['q'] = q,
['k'] = k,
};
// chess board representation
int board[128] = {
r, n, b, q, k, b, n, r, o, o, o, o, o, o, o, o,
p, p, p, p, p, p, p, p, o, o, o, o, o, o, o, o,
e, e, e, e, e, e, e, e, o, o, o, o, o, o, o, o,
e, e, e, e, e, e, e, e, o, o, o, o, o, o, o, o,
e, e, e, e, e, e, e, e, o, o, o, o, o, o, o, o,
e, e, e, e, e, e, e, e, o, o, o, o, o, o, o, o,
P, P, P, P, P, P, P, P, o, o, o, o, o, o, o, o,
R, N, B, Q, K, B, N, R, o, o, o, o, o, o, o, o
};
// side to move
int side = white;
// enpassant square
int enpassant = no_sq;
// castling rights (dec 15 => bin 1111 => both kings can castle to both sides)
int castle = 15;
// convert board square indexes to coordinates
char *square_to_coords[] = {
"a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8", "i8", "j8", "k8", "l8", "m8", "n8", "o8", "p8",
"a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7", "i7", "j7", "k7", "l7", "m7", "n7", "o7", "p7",
"a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6", "i6", "j6", "k6", "l6", "m6", "n6", "o6", "p6",
"a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5", "i5", "j5", "k5", "l5", "m5", "n5", "o5", "p5",
"a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4", "i4", "j4", "k4", "l4", "m4", "n4", "o4", "p4",
"a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3", "i3", "j3", "k3", "l3", "m3", "n3", "o3", "p3",
"a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2", "i2", "j2", "k2", "l2", "m2", "n2", "o2", "p2",
"a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1", "i1", "j1", "k1", "l1", "m1", "n1", "o1", "p1"
};
// print board
void print_board()
{
// print new line
// loop over board ranks
for (int rank = 0; rank < 8; rank++)
{
// loop over board files
for (int file = 0; file < 16; file++)
{
// init square
int square = rank * 16 + file;
// print ranks
if (file == 0)
// if square is on board
if (!(square & 0x88))
//printf("%c ", ascii_pieces[board[square]]);
printf("%s ", unicode_pieces
[board
[square
]]); }
// print new line every time new rank is encountered
}
// print files
printf("\n a b c d e f g h\n\n");
// print board stats
printf(" Side: %s\n", (side
== white
) ? "white": "black"); printf(" Castling: %c%c%c%c\n", (castle
& KC
) ? 'K' : '-', (castle & QC) ? 'Q' : '-',
(castle & kc) ? 'k' : '-',
(castle & qc) ? 'q' : '-');
printf(" Enpassant: %s\n\n", square_to_coords
[enpassant
]); }
// reset board
void reset_board()
{
// loop over board ranks
for (int rank = 0; rank < 8; rank++)
{
// loop over board files
for (int file = 0; file < 16; file++)
{
// init square
int square = rank * 16 + file;
// if square is on board
if (!(square & 0x88))
// reset current board square
board[square] = e;
}
}
// reset stats
side = -1;
castle = 0;
enpassant = no_sq;
}
// parse FEN
void parse_fen(char *fen)
{
// reset board
reset_board();
// loop over board ranks
for (int rank = 0; rank < 8; rank++)
{
// loop over board files
for (int file = 0; file < 16; file++)
{
// init square
int square = rank * 16 + file;
// if square is on board
if (!(square & 0x88))
{
// match pieces
if ((*fen >= 'a' && *fen <= 'z') || (*fen >= 'A' && *fen <= 'Z'))
{
// set the piece on board
board[square] = char_pieces[*fen];
// increment FEN pointer
*fen++;
}
// match empty squares
if (*fen >= '0' && *fen <= '9')
{
// calculate offset
int offset = *fen - '0';
// decrement file on empty squares
if (!(board[square]))
file--;
// skip empty squares
file += offset;
// increment FEN pointer
*fen++;
}
// match end of rank
if (*fen == '/')
// increment FEN pointer
*fen++;
}
}
}
// go to side parsing
*fen++;
// parse side to move
side = (*fen == 'w') ? white : black;
// go to castling rights parsing
fen += 2;
// parse castling rights
while (*fen != ' ')
{
switch(*fen)
{
case 'K': castle |= KC; break;
case 'Q': castle |= QC; break;
case 'k': castle |= kc; break;
case 'q': castle |= qc; break;
case '-': break;
}
// increment pointer
*fen++;
}
// got to empassant square
*fen++;
// parse empassant square
if (*fen != '-')
{
// parse enpassant square's file & rank
int file = fen[0] - 'a';
int rank = 8 - (fen[1] - '0');
// set up enpassant square
enpassant = rank * 16 + file;
}
else
enpassant = no_sq;
}
// main driver
int main()
{
parse_fen("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq g5 0 1");
print_board();
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CgovLyBGRU4gZGVkdWcgcG9zaXRpb25zCmNoYXIgc3RhcnRfcG9zaXRpb25bXSA9ICJybmJxa2Juci9wcHBwcHBwcC84LzgvOC84L1BQUFBQUFBQL1JOQlFLQk5SIHcgS1FrcSAtIDAgMSI7CmNoYXIgdHJpY2t5X3Bvc2l0aW9uW10gPSAicjNrMnIvcDFwcHFwYjEvYm4ycG5wMS8zUE4zLzFwMlAzLzJOMlExcC9QUFBCQlBQUC9SM0syUiB3IEtRa3EgLSAwIDEiOwoKLy8gcGllY2UgZW5jb2RpbmcKZW51bSBwaWVjZXMge2UsIFAsIE4sIEIsIFIsIFEsIEssIHAsIG4sIGIsIHIsIHEsIGssIG99OwoKLy8gc3F1YXJlIGVuY29kaW5nCmVudW0gc3F1YXJlcyB7CiAgICBhOCA9IDAsICAgYjgsIGM4LCBkOCwgZTgsIGY4LCBnOCwgaDgsCiAgICBhNyA9IDE2LCAgYjcsIGM3LCBkNywgZTcsIGY3LCBnNywgaDcsCiAgICBhNiA9IDMyLCAgYjYsIGM2LCBkNiwgZTYsIGY2LCBnNiwgaDYsCiAgICBhNSA9IDQ4LCAgYjUsIGM1LCBkNSwgZTUsIGY1LCBnNSwgaDUsCiAgICBhNCA9IDY0LCAgYjQsIGM0LCBkNCwgZTQsIGY0LCBnNCwgaDQsCiAgICBhMyA9IDgwLCAgYjMsIGMzLCBkMywgZTMsIGYzLCBnMywgaDMsCiAgICBhMiA9IDk2LCAgYjIsIGMyLCBkMiwgZTIsIGYyLCBnMiwgaDIsCiAgICBhMSA9IDExMiwgYjEsIGMxLCBkMSwgZTEsIGYxLCBnMSwgaDEsIG5vX3NxCn07CgovLyBjYXN0bGluZyBiaW5hcnkgcmVwcmVzZW50YXRpb24KLy8KLy8gIGJpbiAgZGVjCi8vIDAwMDEgICAgMSAgd2hpdGUga2luZyBjYW4gY2FzdGxlIHRvIHRoZSBraW5nIHNpZGUKLy8gMDAxMCAgICAyICB3aGl0ZSBraW5nIGNhbiBjYXN0bGUgdG8gdGhlIHF1ZWVuIHNpZGUKLy8gMDEwMCAgICA0ICBibGFjayBraW5nIGNhbiBjYXN0bGUgdG8gdGhlIGtpbmcgc2lkZQovLyAxMDAwICAgIDggIGJsYWNrIGtpbmcgY2FuIGNhc3RsZSB0byB0aGUgcXVlZW4gc2lkZQovLwovLyBleGFtcGxlcwovLyAxMTExICAgICAgIGJvdGggc2lkZXMgYW4gY2FzdGxlIGJvdGggZGlyZWN0aW9ucwovLyAxMDAxICAgICAgIGJsYWNrIGtpbmcgPT4gcXVlZW4gc2lkZQovLyAgICAgICAgICAgIHdoaXRlIGtpbmcgPT4ga2luZyBzaWRlCgovLyBjYXN0bGluZyB3cml0ZXMKZW51bSBjYXN0bGluZyB7IEtDID0gMSwgUUMgPSAyLCBrYyA9IDQsIHFjID0gOCB9OwoKLy8gc2lkZXMgdG8gbW92ZQplbnVtIHNpZGVzIHsgd2hpdGUsIGJsYWNrIH07CgovLyBhc2NpaSBwaWVjZXMKY2hhciBhc2NpaV9waWVjZXNbXSA9ICIuUE5CUlFLcG5icnFrIjsKCi8vIHVuaWNvZGUgcGllY2VzCmNoYXIgKnVuaWNvZGVfcGllY2VzW10gPSB7Ii4iLCAi4pmZIiwgIuKZmCIsICLimZciLCAi4pmWIiwgIuKZlSIsICLimZQiLCAi4pmf77iOIiwgIuKZniIsICLimZ0iLCAi4pmcIiwgIuKZmyIsICLimZoifTsKCi8vIGVuY29kZSBhc2NpaSBwaWVjZXMKaW50IGNoYXJfcGllY2VzW10gPSB7CiAgICBbJ1AnXSA9IFAsCiAgICBbJ04nXSA9IE4sCiAgICBbJ0InXSA9IEIsCiAgICBbJ1InXSA9IFIsCiAgICBbJ1EnXSA9IFEsCiAgICBbJ0snXSA9IEssCiAgICBbJ3AnXSA9IHAsCiAgICBbJ24nXSA9IG4sCiAgICBbJ2InXSA9IGIsCiAgICBbJ3InXSA9IHIsCiAgICBbJ3EnXSA9IHEsCiAgICBbJ2snXSA9IGssCn07CgovLyBjaGVzcyBib2FyZCByZXByZXNlbnRhdGlvbgppbnQgYm9hcmRbMTI4XSA9IHsKICAgIHIsIG4sIGIsIHEsIGssIGIsIG4sIHIsICBvLCBvLCBvLCBvLCBvLCBvLCBvLCBvLAogICAgcCwgcCwgcCwgcCwgcCwgcCwgcCwgcCwgIG8sIG8sIG8sIG8sIG8sIG8sIG8sIG8sCiAgICBlLCBlLCBlLCBlLCBlLCBlLCBlLCBlLCAgbywgbywgbywgbywgbywgbywgbywgbywKICAgIGUsIGUsIGUsIGUsIGUsIGUsIGUsIGUsICBvLCBvLCBvLCBvLCBvLCBvLCBvLCBvLAogICAgZSwgZSwgZSwgZSwgZSwgZSwgZSwgZSwgIG8sIG8sIG8sIG8sIG8sIG8sIG8sIG8sCiAgICBlLCBlLCBlLCBlLCBlLCBlLCBlLCBlLCAgbywgbywgbywgbywgbywgbywgbywgbywKICAgIFAsIFAsIFAsIFAsIFAsIFAsIFAsIFAsICBvLCBvLCBvLCBvLCBvLCBvLCBvLCBvLAogICAgUiwgTiwgQiwgUSwgSywgQiwgTiwgUiwgIG8sIG8sIG8sIG8sIG8sIG8sIG8sIG8KfTsKCi8vIHNpZGUgdG8gbW92ZQppbnQgc2lkZSA9IHdoaXRlOwoKLy8gZW5wYXNzYW50IHNxdWFyZQppbnQgZW5wYXNzYW50ID0gbm9fc3E7CgovLyBjYXN0bGluZyByaWdodHMgKGRlYyAxNSA9PiBiaW4gMTExMSA9PiBib3RoIGtpbmdzIGNhbiBjYXN0bGUgdG8gYm90aCBzaWRlcykKaW50IGNhc3RsZSA9IDE1OwoKLy8gY29udmVydCBib2FyZCBzcXVhcmUgaW5kZXhlcyB0byBjb29yZGluYXRlcwpjaGFyICpzcXVhcmVfdG9fY29vcmRzW10gPSB7CiAgICAiYTgiLCAiYjgiLCAiYzgiLCAiZDgiLCAiZTgiLCAiZjgiLCAiZzgiLCAiaDgiLCAiaTgiLCAiajgiLCAiazgiLCAibDgiLCAibTgiLCAibjgiLCAibzgiLCAicDgiLAogICAgImE3IiwgImI3IiwgImM3IiwgImQ3IiwgImU3IiwgImY3IiwgImc3IiwgImg3IiwgImk3IiwgImo3IiwgIms3IiwgImw3IiwgIm03IiwgIm43IiwgIm83IiwgInA3IiwKICAgICJhNiIsICJiNiIsICJjNiIsICJkNiIsICJlNiIsICJmNiIsICJnNiIsICJoNiIsICJpNiIsICJqNiIsICJrNiIsICJsNiIsICJtNiIsICJuNiIsICJvNiIsICJwNiIsCiAgICAiYTUiLCAiYjUiLCAiYzUiLCAiZDUiLCAiZTUiLCAiZjUiLCAiZzUiLCAiaDUiLCAiaTUiLCAiajUiLCAiazUiLCAibDUiLCAibTUiLCAibjUiLCAibzUiLCAicDUiLAogICAgImE0IiwgImI0IiwgImM0IiwgImQ0IiwgImU0IiwgImY0IiwgImc0IiwgImg0IiwgImk0IiwgImo0IiwgIms0IiwgImw0IiwgIm00IiwgIm40IiwgIm80IiwgInA0IiwKICAgICJhMyIsICJiMyIsICJjMyIsICJkMyIsICJlMyIsICJmMyIsICJnMyIsICJoMyIsICJpMyIsICJqMyIsICJrMyIsICJsMyIsICJtMyIsICJuMyIsICJvMyIsICJwMyIsCiAgICAiYTIiLCAiYjIiLCAiYzIiLCAiZDIiLCAiZTIiLCAiZjIiLCAiZzIiLCAiaDIiLCAiaTIiLCAiajIiLCAiazIiLCAibDIiLCAibTIiLCAibjIiLCAibzIiLCAicDIiLAogICAgImExIiwgImIxIiwgImMxIiwgImQxIiwgImUxIiwgImYxIiwgImcxIiwgImgxIiwgImkxIiwgImoxIiwgImsxIiwgImwxIiwgIm0xIiwgIm4xIiwgIm8xIiwgInAxIgp9OwoKLy8gcHJpbnQgYm9hcmQKdm9pZCBwcmludF9ib2FyZCgpCnsKICAgIC8vIHByaW50IG5ldyBsaW5lCiAgICBwcmludGYoIlxuIik7CgogICAgLy8gbG9vcCBvdmVyIGJvYXJkIHJhbmtzCiAgICBmb3IgKGludCByYW5rID0gMDsgcmFuayA8IDg7IHJhbmsrKykKICAgIHsKICAgICAgICAvLyBsb29wIG92ZXIgYm9hcmQgZmlsZXMKICAgICAgICBmb3IgKGludCBmaWxlID0gMDsgZmlsZSA8IDE2OyBmaWxlKyspCiAgICAgICAgewogICAgICAgICAgICAvLyBpbml0IHNxdWFyZQogICAgICAgICAgICBpbnQgc3F1YXJlID0gcmFuayAqIDE2ICsgZmlsZTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIHByaW50IHJhbmtzCiAgICAgICAgICAgIGlmIChmaWxlID09IDApCiAgICAgICAgICAgICAgICBwcmludGYoIiAlZCAgIiwgOCAtIHJhbmspOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gaWYgc3F1YXJlIGlzIG9uIGJvYXJkCiAgICAgICAgICAgIGlmICghKHNxdWFyZSAmIDB4ODgpKQogICAgICAgICAgICAgICAgLy9wcmludGYoIiVjICIsIGFzY2lpX3BpZWNlc1tib2FyZFtzcXVhcmVdXSk7CiAgICAgICAgICAgICAgICBwcmludGYoIiVzICIsIHVuaWNvZGVfcGllY2VzW2JvYXJkW3NxdWFyZV1dKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gcHJpbnQgbmV3IGxpbmUgZXZlcnkgdGltZSBuZXcgcmFuayBpcyBlbmNvdW50ZXJlZAogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KICAgIAogICAgLy8gcHJpbnQgZmlsZXMKICAgIHByaW50ZigiXG4gICAgYSBiIGMgZCBlIGYgZyBoXG5cbiIpOwogICAgCiAgICAvLyBwcmludCBib2FyZCBzdGF0cwogICAgcHJpbnRmKCIgICAgU2lkZTogICAgICVzXG4iLCAoc2lkZSA9PSB3aGl0ZSkgPyAid2hpdGUiOiAiYmxhY2siKTsKICAgIHByaW50ZigiICAgIENhc3RsaW5nOiAgJWMlYyVjJWNcbiIsIChjYXN0bGUgJiBLQykgPyAnSycgOiAnLScsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2FzdGxlICYgUUMpID8gJ1EnIDogJy0nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2FzdGxlICYga2MpID8gJ2snIDogJy0nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2FzdGxlICYgcWMpID8gJ3EnIDogJy0nKTsKICAgIHByaW50ZigiICAgIEVucGFzc2FudDogICAlc1xuXG4iLCBzcXVhcmVfdG9fY29vcmRzW2VucGFzc2FudF0pOwp9CgovLyByZXNldCBib2FyZAp2b2lkIHJlc2V0X2JvYXJkKCkKewogICAgLy8gbG9vcCBvdmVyIGJvYXJkIHJhbmtzCiAgICBmb3IgKGludCByYW5rID0gMDsgcmFuayA8IDg7IHJhbmsrKykKICAgIHsKICAgICAgICAvLyBsb29wIG92ZXIgYm9hcmQgZmlsZXMKICAgICAgICBmb3IgKGludCBmaWxlID0gMDsgZmlsZSA8IDE2OyBmaWxlKyspCiAgICAgICAgewogICAgICAgICAgICAvLyBpbml0IHNxdWFyZQogICAgICAgICAgICBpbnQgc3F1YXJlID0gcmFuayAqIDE2ICsgZmlsZTsKICAgICAgICAKICAgICAgICAgICAgLy8gaWYgc3F1YXJlIGlzIG9uIGJvYXJkCiAgICAgICAgICAgIGlmICghKHNxdWFyZSAmIDB4ODgpKQogICAgICAgICAgICAgICAgLy8gcmVzZXQgY3VycmVudCBib2FyZCBzcXVhcmUKICAgICAgICAgICAgICAgIGJvYXJkW3NxdWFyZV0gPSBlOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gcmVzZXQgc3RhdHMKICAgIHNpZGUgPSAtMTsKICAgIGNhc3RsZSA9IDA7CiAgICBlbnBhc3NhbnQgPSBub19zcTsKfQoKLy8gcGFyc2UgRkVOCnZvaWQgcGFyc2VfZmVuKGNoYXIgKmZlbikKewogICAgLy8gcmVzZXQgYm9hcmQKICAgIHJlc2V0X2JvYXJkKCk7CiAgICAKICAgIC8vIGxvb3Agb3ZlciBib2FyZCByYW5rcwogICAgZm9yIChpbnQgcmFuayA9IDA7IHJhbmsgPCA4OyByYW5rKyspCiAgICB7CiAgICAgICAgLy8gbG9vcCBvdmVyIGJvYXJkIGZpbGVzCiAgICAgICAgZm9yIChpbnQgZmlsZSA9IDA7IGZpbGUgPCAxNjsgZmlsZSsrKQogICAgICAgIHsKICAgICAgICAgICAgLy8gaW5pdCBzcXVhcmUKICAgICAgICAgICAgaW50IHNxdWFyZSA9IHJhbmsgKiAxNiArIGZpbGU7CiAgICAgICAgCiAgICAgICAgICAgIC8vIGlmIHNxdWFyZSBpcyBvbiBib2FyZAogICAgICAgICAgICBpZiAoIShzcXVhcmUgJiAweDg4KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gbWF0Y2ggcGllY2VzCiAgICAgICAgICAgICAgICBpZiAoKCpmZW4gPj0gJ2EnICYmICpmZW4gPD0gJ3onKSB8fCAoKmZlbiA+PSAnQScgJiYgKmZlbiA8PSAnWicpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgcGllY2Ugb24gYm9hcmQKICAgICAgICAgICAgICAgICAgICBib2FyZFtzcXVhcmVdID0gY2hhcl9waWVjZXNbKmZlbl07CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gaW5jcmVtZW50IEZFTiBwb2ludGVyCiAgICAgICAgICAgICAgICAgICAgKmZlbisrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBtYXRjaCBlbXB0eSBzcXVhcmVzCiAgICAgICAgICAgICAgICBpZiAoKmZlbiA+PSAnMCcgJiYgKmZlbiA8PSAnOScpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIG9mZnNldAogICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSAqZmVuIC0gJzAnOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIGRlY3JlbWVudCBmaWxlIG9uIGVtcHR5IHNxdWFyZXMKICAgICAgICAgICAgICAgICAgICBpZiAoIShib2FyZFtzcXVhcmVdKSkKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS0tOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIHNraXAgZW1wdHkgc3F1YXJlcwogICAgICAgICAgICAgICAgICAgIGZpbGUgKz0gb2Zmc2V0OwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIGluY3JlbWVudCBGRU4gcG9pbnRlcgogICAgICAgICAgICAgICAgICAgICpmZW4rKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gbWF0Y2ggZW5kIG9mIHJhbmsKICAgICAgICAgICAgICAgIGlmICgqZmVuID09ICcvJykKICAgICAgICAgICAgICAgICAgICAvLyBpbmNyZW1lbnQgRkVOIHBvaW50ZXIKICAgICAgICAgICAgICAgICAgICAqZmVuKys7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gZ28gdG8gc2lkZSBwYXJzaW5nCiAgICAqZmVuKys7CiAgICAKICAgIC8vIHBhcnNlIHNpZGUgdG8gbW92ZQogICAgc2lkZSA9ICgqZmVuID09ICd3JykgPyB3aGl0ZSA6IGJsYWNrOwogICAgCiAgICAvLyBnbyB0byBjYXN0bGluZyByaWdodHMgcGFyc2luZwogICAgZmVuICs9IDI7CiAgICAKICAgIC8vIHBhcnNlIGNhc3RsaW5nIHJpZ2h0cwogICAgd2hpbGUgKCpmZW4gIT0gJyAnKQogICAgewogICAgICAgIHN3aXRjaCgqZmVuKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSAnSyc6IGNhc3RsZSB8PSBLQzsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ1EnOiBjYXN0bGUgfD0gUUM7IGJyZWFrOwogICAgICAgICAgICBjYXNlICdrJzogY2FzdGxlIHw9IGtjOyBicmVhazsKICAgICAgICAgICAgY2FzZSAncSc6IGNhc3RsZSB8PSBxYzsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJy0nOiBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gaW5jcmVtZW50IHBvaW50ZXIKICAgICAgICAqZmVuKys7CiAgICB9CiAgICAKICAgIC8vIGdvdCB0byBlbXBhc3NhbnQgc3F1YXJlCiAgICAqZmVuKys7CiAgICAKICAgIC8vIHBhcnNlIGVtcGFzc2FudCBzcXVhcmUKICAgIGlmICgqZmVuICE9ICctJykKICAgIHsKICAgICAgICAvLyBwYXJzZSBlbnBhc3NhbnQgc3F1YXJlJ3MgZmlsZSAmIHJhbmsKICAgICAgICBpbnQgZmlsZSA9IGZlblswXSAtICdhJzsKICAgICAgICBpbnQgcmFuayA9IDggLSAoZmVuWzFdIC0gJzAnKTsKICAgICAgICAKICAgICAgICAvLyBzZXQgdXAgZW5wYXNzYW50IHNxdWFyZQogICAgICAgIGVucGFzc2FudCA9IHJhbmsgKiAxNiArIGZpbGU7CiAgICB9CiAgICAKICAgIGVsc2UKICAgICAgICBlbnBhc3NhbnQgPSBub19zcTsKICAgIAp9CgovLyBtYWluIGRyaXZlcgppbnQgbWFpbigpCnsKICAgIHBhcnNlX2ZlbigicjNrMnIvcDFwcHFwYjEvYm4ycG5wMS8zUE4zLzFwMlAzLzJOMlExcC9QUFBCQlBQUC9SM0syUiB3IEtRa3EgZzUgMCAxIik7CiAgICBwcmludF9ib2FyZCgpOwogICAgCiAgICByZXR1cm4gMDsKfQo=