#ifndef LIBSUDOKU_H #define LIBSUDOKU_H #include #include #include #include class sudoku { private: std::array, 9> board; public: class iterate_sudoku : public std::iterator { protected: std::array, 9> &ref; int x, y; public: iterate_sudoku(std::array, 9> &ref, int x, int y) : ref(ref), x(x), y(y) {} iterate_sudoku(const iterate_sudoku& mit) : ref(mit.ref), x(mit.x), y(mit.y) {} iterate_sudoku& operator++() { if(x == 8) { x = 0; ++y; } else { ++x; } return *this; } bool operator==(const iterate_sudoku& rhs) {return x==rhs.x && y==rhs.y;} bool operator!=(const iterate_sudoku& rhs) {return x!=rhs.x || y!=rhs.y;} int& operator*() {return ref[y][x];} }; iterate_sudoku begin() {return iterate_sudoku(board, 0, 0);} iterate_sudoku end() {return iterate_sudoku(board, 0, 9);} sudoku(); sudoku(const sudoku& ref); sudoku(std::initializer_list> list); bool check(); bool is_safe(int x, int y, int candidate); bool solve(); private: class iterate_row : public iterate_sudoku { public: iterate_row(std::array, 9> &ref, int x, int y) : iterate_sudoku(ref, x, y) {} iterate_row& operator++() {++x;return *this;} }; class iterate_column : public iterate_sudoku { public: iterate_column(std::array, 9> &ref, int x, int y) : iterate_sudoku(ref, x, y) {} iterate_column& operator++() {++y;return *this;} }; class iterate_subgrid : public iterate_sudoku { public: iterate_subgrid(std::array, 9> &ref, int x, int y) : iterate_sudoku(ref, x, y) {} iterate_subgrid& operator++() { ++x; if(x % 3 == 0) { x -= 3; ++y; if(y % 3 == 0) { x = 9; y = 9; } } return *this; } }; template bool check_subset(iterate_sudoku start, iterate_sudoku end, int candidate = 0) { std::array count; std::fill(std::begin(count), std::end(count), false); if(candidate != 0) count[candidate-1] = true; for (iterate_sudoku it = start; it != end; ++it) { if(*it == 0) continue; if(count[(*it)-1]) return false; count[(*it)-1] = true; } return true; } std::tuple get_first_free_cell(); }; std::ostream& operator<< (std::ostream& os, sudoku& obj); #endif //LIBCART_H