#include <iostream>
#include <algorithm>
#include <vector>
#define NOMINMAX
#include <Windows.h>
//Question by ttp://toro.2ch.net/test/read.cgi/tech/1354393458/909-910
//License is GPLv3
//if need chenge license to fish me.
//this is Dev for FillField Algorithm for me.
//dev on windows!
//need more debug!!!!!
//oh this puzzle algorithm license is i dont know.fish and tell to auther!
static const int ScreenWidth = 80;
static const int ScreenHeight = 20;
static const int Width = 3;
static const int Height = 2;
static const int FireValue = 6;
static const int FirstValue = 7;
enum class MoveState{
None,
MoveRight,
MoveLeft,
MoveUp,//コンソールで開発してる関係で2次元配列的にマイナス側が上
MoveDown,//MoveUpの逆側
DrawRight,
DrawLeft,
DrawUp,
DrawDown,
Wait,
End,
GiveUp,
Confuse,
};
namespace Console{//環境依存部分!
bool MoveCursor(int X, int Y){
COORD Pos = { X, Y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
return true;
}
bool Clear(char(&Screen)[ScreenHeight][ScreenWidth], int X, int Y, int Width = 16, int Height = 16){
Console::MoveCursor(X, Y);
for (int i = Y; i < Y + Height; i++){
Console::MoveCursor(X, i);
for (int j = X; j < X + Width; j++){
std::cout << ' ';
}
}
Console::MoveCursor(X, Y);
return true;
}
void Wait(DWORD Time){
Sleep(Time);
}
}
bool Fill(char (&Screen)[ScreenHeight][ScreenWidth],char Ch=' '){
for (int i = 0; i < ScreenHeight; i++){
for (int j = 0; j < ScreenWidth; j++){
Screen[i][j] = Ch;
}
}
return true;
}
bool ShowField(char (&Screen)[ScreenHeight][ScreenWidth],int Width,int Height){
int w = std::max(std::min(Width, ScreenWidth), 0);
int h = std::max(std::min(Height, ScreenHeight), 0);
Console::MoveCursor(0, 0);
for (int i = 0; i < h; i++){
Console::MoveCursor(0, i);
for (int j = 0; j < w; j++){
if (Screen[i][j] == 0) std::cout << 'o';
if (Screen[i][j] == 1) std::cout << '1';
if (Screen[i][j] == 2) std::cout << '2';
if (Screen[i][j] == 3) std::cout << '3';
if (Screen[i][j] == 4) std::cout << '4';
if (Screen[i][j] == 5) std::cout << '5';
if (Screen[i][j] == FireValue) std::cout << 'F';
if (Screen[i][j] == FirstValue) std::cout << '+';
}
}
return true;
}
bool ShowPlayer(int PX,int PY){
int X = std::max(std::min(PX, ScreenWidth), 0);
int Y = std::max(std::min(PY, ScreenHeight), 0);
Console::MoveCursor(X, Y);
std::cout << 'P';
return true;
}
bool ProcessCoolDown(char (&Screen)[ScreenHeight][ScreenWidth],int Width,int Height){
int w = std::max(std::min(Width, ScreenWidth), 0);
int h = std::max(std::min(Height, ScreenHeight), 0);
for (int i = 0; i < h; i++){
for (int j = 0; j < w; j++){
if (Screen[i][j] == 0) continue;
if (Screen[i][j] < FirstValue) Screen[i][j]--;
}
}
return true;
}
bool IsClear(char(&Screen)[ScreenHeight][ScreenWidth], int Width, int Height){
int w = std::max(std::min(Width, ScreenWidth), 0);
int h = std::max(std::min(Height, ScreenHeight), 0);
for (int i = 0; i < h; i++){
for (int j = 0; j < w; j++){
if (Screen[i][j] == FirstValue) return false;
}
}
return true;
}
bool ProcessOne(MoveState MS, char(&Screen)[ScreenHeight][ScreenWidth], int& Width, int& Height, int& PX, int& PY){
int X = PX;
int Y = PY;
switch (MS)
{
case MoveState::MoveRight:
if (X < Width)X++;
if (!((Screen[Y][X]>0) && (Screen[Y][X] <= FireValue))) PX = X;
return true;
break;
case MoveState::MoveLeft:
if (X > 0 ) X--;
if (!((Screen[Y][X]>0) && (Screen[Y][X] <= FireValue))) PX = X;
return true;
break;
case MoveState::MoveUp:
if (Y > 0) Y--;
if (!((Screen[Y][X]>0) && (Screen[Y][X] <= FireValue))) PY = Y;
return true;
break;
case MoveState::MoveDown:
if (Y < Height) Y++;
if (!((Screen[Y][X]>0) && (Screen[Y][X] <= FireValue))) PY = Y;
break;
case MoveState::DrawRight:
if (X + 1 < Width) Screen[Y][X + 1] = FireValue;
break;
case MoveState::DrawLeft:
if (X - 1 >= 0) Screen[Y][X - 1] = FireValue;
break;
case MoveState::DrawUp:
if (Y - 1 >= 0) Screen[Y - 1][X] = FireValue;
break;
case MoveState::DrawDown:
if (Y+1<Height) Screen[Y + 1][X] = FireValue;
break;
case MoveState::Wait:
return true;
break;
case MoveState::End:
return true;
break;
case MoveState::GiveUp:
return true;
break;
case MoveState::Confuse://未対応
return true;
break;
default:
break;
}
return false;
}
MoveState Think_by_hand(char(&Screen)[ScreenHeight][ScreenWidth], int Width, int Height, int PX, int PY){
static int i = 0;
//std::vector<MoveState> Vec{MoveState::Wait, MoveState::MoveRight, MoveState::MoveLeft, MoveState::MoveDown, MoveState::MoveUp ,MoveState::End};
std::vector<MoveState> Vec{MoveState::DrawDown, MoveState::MoveRight, MoveState::DrawLeft, MoveState::DrawRight, MoveState::MoveDown ,MoveState::DrawUp,MoveState::DrawRight,MoveState::MoveLeft,MoveState::DrawRight,MoveState::End};
return Vec[i++];
}
MoveState Think(char(&Screen)[ScreenHeight][ScreenWidth], int Width, int Height, int PX, int PY){
MoveState MS = MoveState::End;
//Write Code Here...
//this is example.
//MS = Think_by_hand(Screen, Width, Height, PX, PY);
return MS;
}
int Process(char (&Screen)[ScreenHeight][ScreenWidth],int Width,int Height,int PX, int PY){
int X = PX, Y = PY;
Fill(Screen, FirstValue);
int Count = 0;
MoveState MS = MoveState::None;
while (MS != MoveState::End){
MS = Think(Screen, Width, Height, X, Y);
ProcessOne(MS, Screen, Width, Height, X, Y);
ProcessCoolDown(Screen, Width, Height);
ShowField(Screen, Width, Height);
ShowPlayer(X, Y);
Console::Wait(1000);
if (MS == MoveState::End) goto End;//break の 代わりにgoto使ってる。今回は開発効率の問題で・・・。Orz
Count++;
if (MS == MoveState::GiveUp) goto End;
if (MS == MoveState::Confuse) goto End;
}
End:
return Count;
}
int main(){
char Screen[ScreenHeight][ScreenWidth] = { 0, };
int X = 0, Y = 0;
Fill(Screen, FirstValue);
Console::Clear(Screen, 0, 0, ScreenWidth, ScreenHeight);
ShowField(Screen, Width, Height);
ShowPlayer(X, Y);
int C = Process(Screen,Width,Height,X, Y);
Console::MoveCursor(0, Height + 1);
bool F = IsClear(Screen, Width, Height);
char *str[] = { "This is Valid!", "This is Invalid..." };
std::cout << "I use " << C << " Steps!" << std::endl << (F ? str[0] : str[1]) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dmVjdG9yPgojZGVmaW5lIE5PTUlOTUFYCiNpbmNsdWRlIDxXaW5kb3dzLmg+CgovL1F1ZXN0aW9uIGJ5IHR0cDovL3Rvcm8uMmNoLm5ldC90ZXN0L3JlYWQuY2dpL3RlY2gvMTM1NDM5MzQ1OC85MDktOTEwCgovL0xpY2Vuc2UgaXMgR1BMdjMKLy9pZiBuZWVkIGNoZW5nZSBsaWNlbnNlIHRvIGZpc2ggbWUuCi8vdGhpcyBpcyBEZXYgZm9yIEZpbGxGaWVsZCBBbGdvcml0aG0gZm9yIG1lLgovL2RldiBvbiB3aW5kb3dzIQovL25lZWQgbW9yZSBkZWJ1ZyEhISEhCgovL29oIHRoaXMgcHV6emxlIGFsZ29yaXRobSBsaWNlbnNlIGlzIGkgZG9udCBrbm93LmZpc2ggYW5kIHRlbGwgdG8gYXV0aGVyIQoKc3RhdGljIGNvbnN0IGludCBTY3JlZW5XaWR0aCA9IDgwOwpzdGF0aWMgY29uc3QgaW50IFNjcmVlbkhlaWdodCA9IDIwOwpzdGF0aWMgY29uc3QgaW50IFdpZHRoID0gMzsKc3RhdGljIGNvbnN0IGludCBIZWlnaHQgPSAyOwpzdGF0aWMgY29uc3QgaW50IEZpcmVWYWx1ZSA9IDY7CnN0YXRpYyBjb25zdCBpbnQgRmlyc3RWYWx1ZSA9IDc7CgplbnVtIGNsYXNzIE1vdmVTdGF0ZXsKCU5vbmUsCglNb3ZlUmlnaHQsCglNb3ZlTGVmdCwKCU1vdmVVcCwvL+OCs+ODs+OCveODvOODq+OBp+mWi+eZuuOBl+OBpuOCi+mWouS/guOBpzLmrKHlhYPphY3liJfnmoTjgavjg57jgqTjg4rjgrnlgbTjgYzkuIoKCU1vdmVEb3duLC8vTW92ZVVw44Gu6YCG5YG0CglEcmF3UmlnaHQsCglEcmF3TGVmdCwKCURyYXdVcCwKCURyYXdEb3duLAoJV2FpdCwKCUVuZCwKCUdpdmVVcCwKCUNvbmZ1c2UsCn07Cm5hbWVzcGFjZSBDb25zb2xley8v55Kw5aKD5L6d5a2Y6YOo5YiG77yBCglib29sIE1vdmVDdXJzb3IoaW50IFgsIGludCBZKXsKCQlDT09SRCBQb3MgPSB7IFgsIFkgfTsKCQlTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgUG9zKTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCWJvb2wgQ2xlYXIoY2hhcigmU2NyZWVuKVtTY3JlZW5IZWlnaHRdW1NjcmVlbldpZHRoXSwgaW50IFgsIGludCBZLCBpbnQgV2lkdGggPSAxNiwgaW50IEhlaWdodCA9IDE2KXsKCQlDb25zb2xlOjpNb3ZlQ3Vyc29yKFgsIFkpOwoJCWZvciAoaW50IGkgPSBZOyBpIDwgWSArIEhlaWdodDsgaSsrKXsKCQkJQ29uc29sZTo6TW92ZUN1cnNvcihYLCBpKTsKCQkJZm9yIChpbnQgaiA9IFg7IGogPCBYICsgV2lkdGg7IGorKyl7CgkJCQlzdGQ6OmNvdXQgPDwgJyAnOwoJCQl9CgkJfQoJCUNvbnNvbGU6Ok1vdmVDdXJzb3IoWCwgWSk7CgkJcmV0dXJuIHRydWU7Cgl9Cgl2b2lkIFdhaXQoRFdPUkQgVGltZSl7CgkJU2xlZXAoVGltZSk7Cgl9Cn0KYm9vbCBGaWxsKGNoYXIgKCZTY3JlZW4pW1NjcmVlbkhlaWdodF1bU2NyZWVuV2lkdGhdLGNoYXIgQ2g9JyAnKXsKCWZvciAoaW50IGkgPSAwOyBpIDwgU2NyZWVuSGVpZ2h0OyBpKyspewoJCWZvciAoaW50IGogPSAwOyBqIDwgU2NyZWVuV2lkdGg7IGorKyl7CgkJCVNjcmVlbltpXVtqXSA9IENoOwoJCX0KCX0KCXJldHVybiB0cnVlOwp9Cgpib29sIFNob3dGaWVsZChjaGFyICgmU2NyZWVuKVtTY3JlZW5IZWlnaHRdW1NjcmVlbldpZHRoXSxpbnQgV2lkdGgsaW50IEhlaWdodCl7CglpbnQgdyA9IHN0ZDo6bWF4KHN0ZDo6bWluKFdpZHRoLCBTY3JlZW5XaWR0aCksIDApOwoJaW50IGggPSBzdGQ6Om1heChzdGQ6Om1pbihIZWlnaHQsIFNjcmVlbkhlaWdodCksIDApOwoKCUNvbnNvbGU6Ok1vdmVDdXJzb3IoMCwgMCk7Cglmb3IgKGludCBpID0gMDsgaSA8IGg7IGkrKyl7CgkJQ29uc29sZTo6TW92ZUN1cnNvcigwLCBpKTsKCQlmb3IgKGludCBqID0gMDsgaiA8IHc7IGorKyl7CgkJCWlmIChTY3JlZW5baV1bal0gPT0gMCkgc3RkOjpjb3V0IDw8ICdvJzsKCQkJaWYgKFNjcmVlbltpXVtqXSA9PSAxKSBzdGQ6OmNvdXQgPDwgJzEnOwoJCQlpZiAoU2NyZWVuW2ldW2pdID09IDIpIHN0ZDo6Y291dCA8PCAnMic7CgkJCWlmIChTY3JlZW5baV1bal0gPT0gMykgc3RkOjpjb3V0IDw8ICczJzsKCQkJaWYgKFNjcmVlbltpXVtqXSA9PSA0KSBzdGQ6OmNvdXQgPDwgJzQnOwoJCQlpZiAoU2NyZWVuW2ldW2pdID09IDUpIHN0ZDo6Y291dCA8PCAnNSc7CgkJCWlmIChTY3JlZW5baV1bal0gPT0gRmlyZVZhbHVlKSBzdGQ6OmNvdXQgPDwgJ0YnOwoJCQlpZiAoU2NyZWVuW2ldW2pdID09IEZpcnN0VmFsdWUpIHN0ZDo6Y291dCA8PCAnKyc7CgkJfQoJfQoJcmV0dXJuIHRydWU7Cn0KYm9vbCBTaG93UGxheWVyKGludCBQWCxpbnQgUFkpewoJaW50IFggPSBzdGQ6Om1heChzdGQ6Om1pbihQWCwgU2NyZWVuV2lkdGgpLCAwKTsKCWludCBZID0gc3RkOjptYXgoc3RkOjptaW4oUFksIFNjcmVlbkhlaWdodCksIDApOwoKCUNvbnNvbGU6Ok1vdmVDdXJzb3IoWCwgWSk7CglzdGQ6OmNvdXQgPDwgJ1AnOwoJcmV0dXJuIHRydWU7Cn0KYm9vbCBQcm9jZXNzQ29vbERvd24oY2hhciAoJlNjcmVlbilbU2NyZWVuSGVpZ2h0XVtTY3JlZW5XaWR0aF0saW50IFdpZHRoLGludCBIZWlnaHQpewoJaW50IHcgPSBzdGQ6Om1heChzdGQ6Om1pbihXaWR0aCwgU2NyZWVuV2lkdGgpLCAwKTsKCWludCBoID0gc3RkOjptYXgoc3RkOjptaW4oSGVpZ2h0LCBTY3JlZW5IZWlnaHQpLCAwKTsKCglmb3IgKGludCBpID0gMDsgaSA8IGg7IGkrKyl7CgkJZm9yIChpbnQgaiA9IDA7IGogPCB3OyBqKyspewoJCQlpZiAoU2NyZWVuW2ldW2pdID09IDApIGNvbnRpbnVlOwoJCQlpZiAoU2NyZWVuW2ldW2pdICA8IEZpcnN0VmFsdWUpIFNjcmVlbltpXVtqXS0tOwoJCX0KCX0KCXJldHVybiB0cnVlOwp9Cgpib29sIElzQ2xlYXIoY2hhcigmU2NyZWVuKVtTY3JlZW5IZWlnaHRdW1NjcmVlbldpZHRoXSwgaW50IFdpZHRoLCBpbnQgSGVpZ2h0KXsKCWludCB3ID0gc3RkOjptYXgoc3RkOjptaW4oV2lkdGgsIFNjcmVlbldpZHRoKSwgMCk7CglpbnQgaCA9IHN0ZDo6bWF4KHN0ZDo6bWluKEhlaWdodCwgU2NyZWVuSGVpZ2h0KSwgMCk7CgoJZm9yIChpbnQgaSA9IDA7IGkgPCBoOyBpKyspewoJCWZvciAoaW50IGogPSAwOyBqIDwgdzsgaisrKXsKCQkJaWYgKFNjcmVlbltpXVtqXSA9PSBGaXJzdFZhbHVlKSByZXR1cm4gZmFsc2U7CgkJfQoJfQoJcmV0dXJuIHRydWU7Cn0KCmJvb2wgUHJvY2Vzc09uZShNb3ZlU3RhdGUgTVMsIGNoYXIoJlNjcmVlbilbU2NyZWVuSGVpZ2h0XVtTY3JlZW5XaWR0aF0sIGludCYgV2lkdGgsIGludCYgSGVpZ2h0LCBpbnQmIFBYLCBpbnQmIFBZKXsKCglpbnQgWCA9IFBYOwoJaW50IFkgPSBQWTsKCglzd2l0Y2ggKE1TKQoJewoJY2FzZSBNb3ZlU3RhdGU6Ok1vdmVSaWdodDoKCQlpZiAoWCA8IFdpZHRoKVgrKzsKCQlpZiAoISgoU2NyZWVuW1ldW1hdPjApICYmIChTY3JlZW5bWV1bWF0gPD0gRmlyZVZhbHVlKSkpIFBYID0gWDsKCQlyZXR1cm4gdHJ1ZTsKCQlicmVhazsKCWNhc2UgTW92ZVN0YXRlOjpNb3ZlTGVmdDoKCQlpZiAoWCA+IDAgKSBYLS07CgkJaWYgKCEoKFNjcmVlbltZXVtYXT4wKSAmJiAoU2NyZWVuW1ldW1hdIDw9IEZpcmVWYWx1ZSkpKSBQWCA9IFg7CgkJcmV0dXJuIHRydWU7CgkJYnJlYWs7CgljYXNlIE1vdmVTdGF0ZTo6TW92ZVVwOgoJCWlmIChZID4gMCkgWS0tOwkKCQlpZiAoISgoU2NyZWVuW1ldW1hdPjApICYmIChTY3JlZW5bWV1bWF0gPD0gRmlyZVZhbHVlKSkpIFBZID0gWTsKCQlyZXR1cm4gdHJ1ZTsKCQlicmVhazsKCWNhc2UgTW92ZVN0YXRlOjpNb3ZlRG93bjoKCQlpZiAoWSA8IEhlaWdodCkgWSsrOwoJCWlmICghKChTY3JlZW5bWV1bWF0+MCkgJiYgKFNjcmVlbltZXVtYXSA8PSBGaXJlVmFsdWUpKSkgUFkgPSBZOwoJCWJyZWFrOwoJY2FzZSBNb3ZlU3RhdGU6OkRyYXdSaWdodDoKCQlpZiAoWCArIDEgPCBXaWR0aCkgU2NyZWVuW1ldW1ggKyAxXSA9IEZpcmVWYWx1ZTsKCQlicmVhazsKCWNhc2UgTW92ZVN0YXRlOjpEcmF3TGVmdDoKCQlpZiAoWCAtIDEgPj0gMCkgU2NyZWVuW1ldW1ggLSAxXSA9IEZpcmVWYWx1ZTsKCQlicmVhazsKCWNhc2UgTW92ZVN0YXRlOjpEcmF3VXA6CgkJaWYgKFkgLSAxID49IDApIFNjcmVlbltZIC0gMV1bWF0gPSBGaXJlVmFsdWU7CgkJYnJlYWs7CgljYXNlIE1vdmVTdGF0ZTo6RHJhd0Rvd246CgkJaWYgKFkrMTxIZWlnaHQpIFNjcmVlbltZICsgMV1bWF0gPSBGaXJlVmFsdWU7CgkJYnJlYWs7CgljYXNlIE1vdmVTdGF0ZTo6V2FpdDoKCQlyZXR1cm4gdHJ1ZTsKCQlicmVhazsKCWNhc2UgTW92ZVN0YXRlOjpFbmQ6CgkJcmV0dXJuIHRydWU7CgkJYnJlYWs7CgljYXNlIE1vdmVTdGF0ZTo6R2l2ZVVwOgoJCXJldHVybiB0cnVlOwoJCWJyZWFrOwoJY2FzZSBNb3ZlU3RhdGU6OkNvbmZ1c2U6Ly/mnKrlr77lv5wKCQlyZXR1cm4gdHJ1ZTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIGZhbHNlOwp9Ck1vdmVTdGF0ZSBUaGlua19ieV9oYW5kKGNoYXIoJlNjcmVlbilbU2NyZWVuSGVpZ2h0XVtTY3JlZW5XaWR0aF0sIGludCBXaWR0aCwgaW50IEhlaWdodCwgaW50IFBYLCBpbnQgUFkpewoJc3RhdGljIGludCBpID0gMDsKCS8vc3RkOjp2ZWN0b3I8TW92ZVN0YXRlPiBWZWN7TW92ZVN0YXRlOjpXYWl0LCBNb3ZlU3RhdGU6Ok1vdmVSaWdodCwgTW92ZVN0YXRlOjpNb3ZlTGVmdCwgTW92ZVN0YXRlOjpNb3ZlRG93biwgTW92ZVN0YXRlOjpNb3ZlVXAgLE1vdmVTdGF0ZTo6RW5kfTsKCXN0ZDo6dmVjdG9yPE1vdmVTdGF0ZT4gVmVje01vdmVTdGF0ZTo6RHJhd0Rvd24sIE1vdmVTdGF0ZTo6TW92ZVJpZ2h0LCBNb3ZlU3RhdGU6OkRyYXdMZWZ0LCBNb3ZlU3RhdGU6OkRyYXdSaWdodCwgTW92ZVN0YXRlOjpNb3ZlRG93biAsTW92ZVN0YXRlOjpEcmF3VXAsTW92ZVN0YXRlOjpEcmF3UmlnaHQsTW92ZVN0YXRlOjpNb3ZlTGVmdCxNb3ZlU3RhdGU6OkRyYXdSaWdodCxNb3ZlU3RhdGU6OkVuZH07CglyZXR1cm4gVmVjW2krK107CQp9CgpNb3ZlU3RhdGUgVGhpbmsoY2hhcigmU2NyZWVuKVtTY3JlZW5IZWlnaHRdW1NjcmVlbldpZHRoXSwgaW50IFdpZHRoLCBpbnQgSGVpZ2h0LCBpbnQgUFgsIGludCBQWSl7CglNb3ZlU3RhdGUgTVMgPSBNb3ZlU3RhdGU6OkVuZDsKCgkvL1dyaXRlIENvZGUgSGVyZS4uLgoJLy90aGlzIGlzIGV4YW1wbGUuCgkvL01TID0gVGhpbmtfYnlfaGFuZChTY3JlZW4sIFdpZHRoLCBIZWlnaHQsIFBYLCBQWSk7CgoJcmV0dXJuIE1TOwp9CmludCBQcm9jZXNzKGNoYXIgKCZTY3JlZW4pW1NjcmVlbkhlaWdodF1bU2NyZWVuV2lkdGhdLGludCBXaWR0aCxpbnQgSGVpZ2h0LGludCBQWCwgaW50IFBZKXsKCWludCBYID0gUFgsIFkgPSBQWTsKCUZpbGwoU2NyZWVuLCBGaXJzdFZhbHVlKTsKCWludCBDb3VudCA9IDA7CglNb3ZlU3RhdGUgTVMgPSBNb3ZlU3RhdGU6Ok5vbmU7CgoJd2hpbGUgKE1TICE9IE1vdmVTdGF0ZTo6RW5kKXsKCgkJTVMgPSBUaGluayhTY3JlZW4sIFdpZHRoLCBIZWlnaHQsIFgsIFkpOwoJCVByb2Nlc3NPbmUoTVMsIFNjcmVlbiwgV2lkdGgsIEhlaWdodCwgWCwgWSk7CgkJUHJvY2Vzc0Nvb2xEb3duKFNjcmVlbiwgV2lkdGgsIEhlaWdodCk7CgkJU2hvd0ZpZWxkKFNjcmVlbiwgV2lkdGgsIEhlaWdodCk7CgkJU2hvd1BsYXllcihYLCBZKTsKCQlDb25zb2xlOjpXYWl0KDEwMDApOwoJCWlmIChNUyA9PSBNb3ZlU3RhdGU6OkVuZCkgZ290byBFbmQ7Ly9icmVhayDjga7jgIDku6Pjgo/jgorjgatnb3Rv5L2/44Gj44Gm44KL44CC5LuK5Zue44Gv6ZaL55m65Yq5546H44Gu5ZWP6aGM44Gn44O744O744O744CCT3J6CgkKCQlDb3VudCsrOwoKCQlpZiAoTVMgPT0gTW92ZVN0YXRlOjpHaXZlVXApIGdvdG8gRW5kOwoJCWlmIChNUyA9PSBNb3ZlU3RhdGU6OkNvbmZ1c2UpIGdvdG8gRW5kOwoKCX0KRW5kOgoKCXJldHVybiBDb3VudDsKfQoKaW50IG1haW4oKXsKCWNoYXIgU2NyZWVuW1NjcmVlbkhlaWdodF1bU2NyZWVuV2lkdGhdID0geyAwLCB9OwoJaW50IFggPSAwLCBZID0gMDsKCglGaWxsKFNjcmVlbiwgRmlyc3RWYWx1ZSk7CglDb25zb2xlOjpDbGVhcihTY3JlZW4sIDAsIDAsIFNjcmVlbldpZHRoLCBTY3JlZW5IZWlnaHQpOwoKCVNob3dGaWVsZChTY3JlZW4sIFdpZHRoLCBIZWlnaHQpOwoJU2hvd1BsYXllcihYLCBZKTsKCglpbnQgQyA9IFByb2Nlc3MoU2NyZWVuLFdpZHRoLEhlaWdodCxYLCBZKTsKCQoJQ29uc29sZTo6TW92ZUN1cnNvcigwLCBIZWlnaHQgKyAxKTsKCWJvb2wgRiA9IElzQ2xlYXIoU2NyZWVuLCBXaWR0aCwgSGVpZ2h0KTsKCWNoYXIgKnN0cltdID0geyAiVGhpcyBpcyBWYWxpZCEiLCAiVGhpcyBpcyBJbnZhbGlkLi4uIiB9OwoJc3RkOjpjb3V0IDw8ICJJIHVzZSAiIDw8IEMgPDwgIiBTdGVwcyEiIDw8IHN0ZDo6ZW5kbCA8PCAoRiA/IHN0clswXSA6IHN0clsxXSkgPDwgc3RkOjplbmRsOwoKCXJldHVybiAwOwp9