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