00001 #ifndef __SUDOKUBOARD_H__ 00002 #define __SUDOKUBOARD_H__ 00003 00004 #pragma once 00005 00006 #include <iostream> 00007 #include <fstream> 00008 00009 class SudokuBoard{ 00010 private: 00011 class BitSet{ 00012 private: 00013 00014 int mem; 00015 00016 public: 00017 BitSet() : mem((9 << 16) | (0x000003FEl)) { } 00018 00019 inline int size(){ 00020 return mem >> 16; 00021 } 00022 00023 inline bool allows(int i){ 00024 return (mem & (1 << i)); 00025 } 00026 00027 inline void erase(int i){ 00028 mem &= (~(1 << i)); 00029 mem -= (1 << 16); 00030 } 00031 00032 inline void reduce_to(int i){ 00033 mem = (1 << 16) | (1 << i); 00034 } 00035 00036 friend class SudokuBoard; 00037 }; 00038 00039 int filled_in; 00040 00041 char fill[9][9]; 00042 00043 BitSet row_stats[9]; 00044 BitSet col_stats[9]; 00045 BitSet reg_stats[9]; 00046 00047 public: 00048 SudokuBoard(); 00049 00055 inline bool impossible(int row, int col){ 00056 return 0 == (0x000003FEl & row_stats[row].mem & col_stats[col].mem & reg_stats[row/3*3+col/3].mem); 00057 } 00058 00064 inline int unique_possibility(int row, int col){ 00065 int sol = 0; 00066 for (int i = 1; i <= 9; i++){ 00067 if (allows(row, col, i)){ 00068 if (sol == 0){ 00069 sol = i; 00070 } else { 00071 return 0; 00072 } 00073 } 00074 } 00075 return sol; 00076 } 00077 00084 inline bool allows(int row, int col, int i){ 00085 return row_stats[row].allows(i) && col_stats[col].allows(i) && reg_stats[row/3*3+col/3].allows(i); 00086 } 00087 00093 inline void put(int row, int col, int i){ 00094 if (!is_empty(row,col)){ 00095 std::cerr << "ERROR! You must never overwrite values in the Sudoku board!\n"; 00096 std::cerr << " Make a copy of the board so you can go back to a previous version!\n"; 00097 std::cerr << " Ignoring \"put\" operation!\n"; 00098 return; 00099 } 00100 fill[row][col] = '0' + i; 00101 row_stats[row].erase(i); 00102 col_stats[col].erase(i); 00103 reg_stats[row/3*3+col/3].erase(i); 00104 filled_in++; 00105 } 00106 00110 inline bool is_empty(int row, int col){ 00111 return fill[row][col] == 0; 00112 } 00113 00117 inline bool is_done(){ 00118 return filled_in == 81; 00119 } 00120 00121 friend std::ostream& operator<< (std::ostream& out, SudokuBoard& right); 00122 }; 00123 00125 std::istream& operator>> (std::istream& in, SudokuBoard& right); 00126 00128 std::ostream& operator<< (std::ostream& out, SudokuBoard& right); 00129 00130 #endif 00131