#include #include #include #include #include #include #include #include bool stdout_is_color_tty; #if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) #include class Tty_init_static{ public: Tty_init_static(){ stdout_is_color_tty=(bool)isatty(1); } } tty_init_static; #else class Tty_init_static{ public: Tty_init_static(){ stdout_is_color_tty=false; } } tty_init_static; #endif using namespace std; string readfile(istream &is){ string res; char buf[1024]; while(true){ is.read(buf,sizeof(buf)); int nread=is.gcount(); if(nread==0)break; res.append(buf,sizeof(buf)); } return res; } template class Sudoku{ private: int bd[N][N]; // bd[y][x] bitset poss[N][N]; bool given[N][N]; void calcposs(){ for(int y=0;y> &dst) const { int miny=-1,minx=-1,mincount=N+1; for(int y=0;y0&&count S(*this); S.bd[miny][minx]=i; S.solve(dst); } } bool solved() const { if(!verifyConsistent())return false; for(int y=0;y> &dst){ do calcposs(); while(resolveposs()); if(solved()){ dst.push_back(*this); return; } recurseone(dst); } bool verifyConsistent(bool diag=false) const { for(int i=0;i seenH,seenV; for(int j=0;j1&&BW>1&&BH>1&&BW*BH==N,"Box size inconsistent"); stringstream ss(init); for(int y=0;y>c; if(c=='.'){ bd[y][x]=-1; poss[y][x].set(); given[y][x]=false; continue; } int n=-1; if(c>='1'&&c<='9')n=c-'0'; else if(c>='A'&&c<='Z')n=c-'A'+10; else if(c>='a'&&c<='z')n=c-'a'+10; if(n<1||n>N)throw "Invalid character in init string for Sudoku"; bd[y][x]=n; poss[y][x].set(n-1); given[y][x]=true; } } } vector> solve(){ vector> dst; solve(dst); return dst; } bool verifySolution(const Sudoku &sol) const { for(int y=0;y int compare(const Sudoku &other) const { for(int y=0;yother.bd[y][x])return 1; } } return 0; } bool operator==(const Sudoku &other) const {return compare(other)==0;} bool operator!=(const Sudoku &other) const {return compare(other)!=0;} bool operator> (const Sudoku &other) const {return compare(other)> 0;} bool operator>=(const Sudoku &other) const {return compare(other)>=0;} bool operator< (const Sudoku &other) const {return compare(other)< 0;} bool operator<=(const Sudoku &other) const {return compare(other)<=0;} template friend ostream& operator<<(ostream &os,const Sudoku<_,BW_,BH_> &S); }; template ostream& operator<<(ostream &os,const Sudoku &S){ for(int y=0;y0){ if(y%BH==0)os<0){ if(x%BW==0)os<<" "; os<<' '; } bool color=stdout_is_color_tty&&!S.given[y][x]&&S.bd[y][x]!=-1; if(color)os<<"\x1B[42;1m"; if(S.bd[y][x]==-1)os<<'.'; else if(S.bd[y][x]<=9)os< S(readfile(cin)); Sudoku origS(S); auto solutions=S.solve(); if(solutions.size()==0){ cerr<<"0 solutions :("<0&&sol==solutions[i-1])continue; if(!first){ cout<