#include using namespace std; #ifdef DEB #define D if(1) #else #define D if(0) #endif using ll = long long; using func = std::function; #define F(IN) [&](int a,int b)->char&{return IN;} // Tuto konstrukci využiji pro určování pozice, kam daný objekt vygeneruji. // Její výhoda je ve snadném převracení a otáčení výstupu // Každá funkce na generování bere jako parametr funkci, která pro dvojici čísel // (souřadnici) určí místo v paměti, tak danou polohu zapsat // První z předešlých řádku je definice typu takovéto funkce // Druhý je zkratková konstrukce pro generování lambda funkcí. // Stačí jen napsat její tělo s použitím a a b jako vstupních souřadnic int n,m; char out[13245][12345]; int solveOut[13245][12345]; void setSize(int N,int M) { n=N;m=M; for(int i=0;ib) hline(out,x,b,a); for(int y=a-1;y<=b+1;y++) { out(x-1,y)='.'; out(x,y)='.'; out(x+1,y)='.'; } } void vline(func out,int a,int b,int y) { // a ve směru první souřadnice if(a>b) vline(out,b,a,y); for(int x=a-1;x<=b+1;x++) { out(x,y-1)='.'; out(x,y)='.'; out(x,y+1)='.'; } } void line(func out,vector> route) {// vezme seznam bodů a mezi nimi nakreslí koridor // Nutně musí být sousední body s alespoň jednou stejnou souřadnicí for(int i=0;i<(int)route.size()-1;i++) { if(route[i].first == route[i+1].first) { hline(out,route[i].first,route[i].second,route[i+1].second); } else if(route[i].second == route[i+1].second) { vline(out,route[i].first,route[i+1].first,route[i].second); } else assert(0); } } void drawCross(func out) {// křížení koridorů const int size = cross_size; char a [size][size+1] = { "XXXXXXXXXXXXXXX...XXX", "XXXXXXX...........XXX", "XXXXXXX...........XXX", "XXXXXXX..............", "XXXXXXX...XXXXXXX....", "XXXXXXX.....XXXXX....", "XXXXXXX.....XXXXX...X", "X...........XXXXX...X", "X.......X...XXXXX...X", "X...............X...X", "X...X...........X...X", "X...X...............X", "X...XXXXX...X.......X", "X...XXXXX...........X", "X...XXXXX.....XXXXXXX", "....XXXXX.....XXXXXXX", "....XXXXXXX...XXXXXXX", "..............XXXXXXX", "XXX...........XXXXXXX", "XXX...........XXXXXXX", "XXX...XXXXXXXXXXXXXXX" }; for(int i=0;i type) {// Blok hradla. Jako vstup bere jeho vstupy pro kombinace vstupů for(int i=0;i0?'!':out[i][j]); fprintf(f,"\n"); } fclose(f); } int solve(int x,int y,int i,int size) {// Snaží se vyřešit vygenerovanou mapu randomizovaným algoritmem (rekurzivní funkce) if(x<0 || y<0 || x+size>n || y+size>m) return 0; for(int p=0;p0) ) return 0; auto draw = [&](int what){ for(int p=0;p> next = {{x+1,y},{x-1,y},{x,y-1},{x,y+1}}; random_shuffle(next.begin(),next.end()); if(x+size==n) return -1; int maxBack=0; for(auto it : next) { draw(i); int out = solve(it.first,it.second,i+1,size); maxBack=max(maxBack,out); if(out==-1) return -1; draw(0); if(maxBack > 200) return maxBack+1; } return maxBack+1; } bool solve(int size=3) {// Celé řešení (1000 krát spustí náhodný algoritmus) for(int i=0;i<1000;i++) { for(int y=0;y type; }; vector gates; int variables=0; vector stackNum; void loadInput(char * in) {// z stringu parametru pomocí postfixové notace // proměnné definujeme pomocí čísel od 0 // oddělovat je lze mezerami či operátory: // & - and // | - or // ^ - xor // = - ekvivalence // ! - negace bool inNum=0; int num = 0; for(int i=0;;i++) { if('0'<=in[i] && in[i]<='9') { inNum=1; num=num*10+in[i]-'0'; } else { if(inNum) variables=max(variables,num); num=inNum=0; } if(!in[i]) break; } variables++; for(int i=0;;i++) { if('0'<=in[i] && in[i]<='9') { inNum=1; num=num*10+in[i]-'0'; } else { if(inNum) stackNum.push_back(num); num=inNum=0; if(!in[i]) break; if(in[i]=='!') { assert(stackNum.size()>=1); int a = *stackNum.rbegin();stackNum.pop_back(); int c = variables++;stackNum.push_back(c); gates.push_back({a,a,c,{1,1,0,0}}); } else if(in[i]!=' ') { assert(stackNum.size()>=2); int a = *stackNum.rbegin();stackNum.pop_back(); int b = *stackNum.rbegin();stackNum.pop_back(); int c = variables++;stackNum.push_back(c); if (in[i]=='&') gates.push_back({a,b,c,{0,0,0,1}}); else if(in[i]=='|') gates.push_back({a,b,c,{0,1,1,1}}); else if(in[i]=='^') gates.push_back({a,b,c,{0,1,1,0}}); else if(in[i]=='=') gates.push_back({a,b,c,{1,0,0,1}}); else assert(0); } } } assert(stackNum.size()==1); } int main(int argc,char ** argv) { // parametry: // [1] vstupní řetězec // [2] nepovinně semínko pro náhodné číslo generátoru (použito aktuálním časem) int sr = time(0)+(argc>2?atoi(argv[2]):0); printf("SR: %d\n",sr); srand(sr); loadInput(argv[1]); setSize(block_size*(variables+4),block_size*(2+gates.size()*4)); for(int i=0;i<(int)gates.size();i++) {// generuje sloupce hradel for(int j=0;j