#include using std::ostream; using std::cout; using std::cin; #include using std::ifstream; #include #include "string.h" #include "Queue.h" LARGE_INTEGER tick1, tick2, ticksPerSecond; double time, timeThinking, timeDoing, totalThinking, totalDoing; class Domain { public: Domain(); void Dump() const; unsigned Size() const; bool Contains(const unsigned n) const; bool Insert(const unsigned n); bool Remove(const unsigned n); private: unsigned domain[9]; unsigned size; }; Domain::Domain() :size(9) { for(unsigned i=0; i<9; i++) domain[i] = i+1; } void Domain::Dump() const { for(unsigned i=0; i<9; i++) { if(i == size) cout << "|"; cout << domain[i]; } cout << "\n"; } unsigned Domain::Size() const { return size; } bool Domain::Contains(const unsigned n) const { for(unsigned i=0; i q; for(unsigned x=0; x<81; x++) for(unsigned y=x; y<81; y++) if(y != x && S.grid[x/9][x%9].GetValue() == 0 && S.grid[y/9][y%9].GetValue() == 0 && (y/9 == x/9 || y%9 == x%9 || ( (y%9)/3 == (x%9)/3 && (y/9)/3 == (x/9)/3 )) && !S.grid[x/9][x%9].IsPermanent() && !S.grid[y/9][y%9].IsPermanent() ) { q.Enqueue(MyArc(x/9, x%9, y/9, y%9)); q.Enqueue(MyArc(y/9, y%9, x/9, x%9)); } while(!q.Empty()) { MyArc a = q.Dequeue(); if(RemoveInconsistencies(S, a)) { if(S.grid[a.r1][a.c1].DomainSize() == 0) { QueryPerformanceCounter(&tick2); time = tick2.QuadPart - tick1.QuadPart; timeThinking += time / ticksPerSecond.QuadPart; QueryPerformanceCounter(&tick1); return false; } for(unsigned x=0; x<9; x++) { if(x != r && !S.grid[x][c].IsPermanent()) q.Enqueue(MyArc(x, c, r, c)); if(x != c && !S.grid[r][x].IsPermanent()) q.Enqueue(MyArc(r, x, r, c)); } for(unsigned row = r - r%3; row < r - r%3 + 3; row++) for(unsigned col = c - c%3; col < c - c%3 + 3; col++) if(r != row && c != col && !S.grid[row][col].IsPermanent()) q.Enqueue(MyArc(row, col, r, c)); } } QueryPerformanceCounter(&tick2); time = tick2.QuadPart - tick1.QuadPart; timeThinking += time / ticksPerSecond.QuadPart; QueryPerformanceCounter(&tick1); return true; } char asdf[10]; SuDoKu RecursiveArcConsistencySearch(SuDoKu& S, const unsigned r, const unsigned c) { if(S.grid[r][c].IsPermanent()) return RecursiveArcConsistencySearch(S, r + 1*(c == 8), (c + 1) % 9); for(unsigned n=1; n<=9; n++) { if(S.grid[r][c].DomainContains(n)) { SuDoKu Su(S); Su.grid[r][c].SetValue(n); if(Su.Filled()) return Su; QueryPerformanceCounter(&tick2); time = tick2.QuadPart - tick1.QuadPart; timeDoing += time / ticksPerSecond.QuadPart; QueryPerformanceCounter(&tick1); for(unsigned x=0; x<9; x++) { if(x != r) Su.grid[x][c].RemoveFromDomain(n); if(x != c) Su.grid[r][x].RemoveFromDomain(n); } for(unsigned row = r - r%3; row < r - r%3 + 3; row++) for(unsigned col = c - c%3; col < c - c%3 + 3; col++) if(r != row && c != col && Su.grid[row][col].GetValue() == 0) Su.grid[row][col].RemoveFromDomain(n); if(MAC3(Su, r, c)) { Su = RecursiveArcConsistencySearch(Su, r + 1*(c == 8), (c + 1) % 9); if(Su.Filled()) return Su; } } } return S; } int main() { SuDoKu *S1; unsigned x; ifstream in; in.open("SuDoKu.txt"); if(in.fail()) exit(0); QueryPerformanceFrequency(&ticksPerSecond); totalThinking = totalDoing = 0; while(in >> x) { S1 = new SuDoKu; S1->Set(0, 0, x, x != 0); for(unsigned i=1; i < 81; i++) { in >> x; S1->Set(i/9, i%9, x, x != 0); } cout << *S1; timeDoing = 0; timeThinking = 0; QueryPerformanceCounter(&tick1); SuDoKu S2 = RecursiveArcConsistencySearch(*S1, 0, 0); QueryPerformanceCounter(&tick2); time = tick2.QuadPart - tick1.QuadPart; timeDoing += time / ticksPerSecond.QuadPart; if(S2.Filled()) cout << S2; else cout << "No Solution\n"; cout << "Doing: " << timeDoing << " seconds\n"; cout << "Thinking: " << timeThinking << " seconds\n\n"; totalDoing+= timeDoing; totalThinking += timeThinking; } cout << "Total Time Doing: " << totalDoing << " seconds\n"; cout << "Total Time Thinking: " << totalThinking << " seconds\n\n"; return 0; }