From 756a8c48b567901d2483e6ea2213c00e5ca47931 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Fri, 28 Oct 2016 23:14:38 +0200 Subject: Initial --- solve.cpp | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 solve.cpp (limited to 'solve.cpp') diff --git a/solve.cpp b/solve.cpp new file mode 100644 index 0000000..59c43e3 --- /dev/null +++ b/solve.cpp @@ -0,0 +1,275 @@ +#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); + } + +public: + Sudoku(const string &init){ + static_assert(N>1&&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 verifyConsistent(bool diag=false) const { + for(int i=0;i seenH,seenV; + for(int j=0;j &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(is)); + Sudoku origS(S); + + auto solutions=S.solve(); + if(solutions.size()==0){ + cerr<<"0 solutions :("<0&&sol==solutions[i-1])continue; + if(!first){ + cout<