Loading Makefile +3 −3 Original line number Original line Diff line number Diff line Loading @@ -2,10 +2,10 @@ all: sudoku all: sudoku sudoku: sudoku.o sudoku.hh sudoku: sudoku.o grid.o g++ -Wall -Wextra -pedantic -ansi -g $< -o $@ g++ -Wall -Wextra -pedantic -ansi -g $^ -o $@ %.o:%.cc %.o:%.cc sudoku.hh g++ -Wall -Wextra -pedantic -ansi -g $< -o $@ -c g++ -Wall -Wextra -pedantic -ansi -g $< -o $@ -c clean: clean: Loading grid.cc 0 → 100644 +145 −0 Original line number Original line Diff line number Diff line #include "sudoku.hh" bool Grid::verbose = false; bool Grid::advprint = false; int Grid::load(const char *filename) { int val; std::fstream fs; assert(filename); if (Grid::verbose) std::cout << "Loading file: " << filename << "..." << std::endl; fs.open(filename, std::fstream::in); if (!fs.is_open()) return 0; for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) { fs >> std::dec >> val; if (val < 0 || val > 9) { std::cerr << "Invalid value in file: " << val << std::endl; exit(EXIT_LOADFAIL); } if (val > 0) pose(i, j, val); //block_[i][j].set(val); } fs.close(); return 1; } void Grid::pose(int x, int y, int v) { if (x < 0 || x >= GRID_SIDE || y < 0 || y >= GRID_SIDE) { std::cerr << "Invalid position: " << x + 1 << ", " << y + 1 << std::endl; exit(EXIT_INV_POS); } if (v <= 0 || v > GRID_SIDE) { std::cerr << "Invalid value: " << v << std::endl; exit(EXIT_INV_VAL); } for (int i = 0; i < GRID_SIDE; ++i) { block_[x][i].forbid(v); block_[i][y].forbid(v); } for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) block_[(x / 3) * 3 + x][(y / 3) * 3 + y].forbid(v); } void Grid::resolve() { if (Grid::verbose) std::cout << "Resolving..." << std::endl; } void Grid::print() const { int i, j, k; for (i = 0; i < GRID_SIDE; ++i) { print_line(); if (i > 0 && i % 3 == 0) print_line(); if (Grid::advprint) { for (int l = 0; l < 3; ++l) { for (j = 0; j < GRID_SIDE; ++j) { if (j > 0 && j % 3 == 0) std::cout << "| "; std::cout << "|"; for (k = l * 3 + 1; k <= l * 3 + 3; ++k) if (block_[i][j].value_get() == k) std::cout << "\033[0;32m" << k << "\033[0m"; else if (block_[i][j].is_forbid(k)) std::cout << "\033[0;31m" << k << "\033[0m"; else std::cout << k; } std::cout << "|" << std::endl; } } else { std::cout << "|"; for (j = 0; j < GRID_SIDE; ++j) { if (j > 0 && j % 3 == 0) std::cout << " |"; std::cout << " " << block_[i][j] << " |"; } std::cout << std::endl; } } print_line(); } bool Grid::is_done() const { for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) if (block_[i][j].value_get() == 0) return false; return true; } bool Grid::verify() const { bool vertical_line[GRID_SIDE]; bool horizontal_line[GRID_SIDE]; int tmp; // check horizontals and verticales for (int i = 0; i < GRID_SIDE; ++i) { for (int j = 0; j < GRID_SIDE; ++j) horizontal_line[j] = vertical_line[j] = false; for (int j = 0; j < GRID_SIDE; ++j) { //horizontals tmp = block_[i][j].value_get() - 1; if (tmp < 0 || horizontal_line[tmp]) return false; horizontal_line[tmp] = true; //verticals tmp = block_[j][i].value_get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j] || !horizontal_line[j]) return false; } // check nine blocks (use vertical_block) for (int j = 0; j < GRID_SIDE; ++j) vertical_line[j] = false; for (int i = 0; i < GRID_SIDE; i += 3) for (int j = 0; j < GRID_SIDE; j += 3) for (int k = 0; k < 3; ++k) for (int l = 0; l < 3; ++l) { tmp = block_[i + k][j + l].value_get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j]) return false; return true; } grids/metro-221→grids/demoniac/metro-221 +1 −1 File changed and moved.Contains only whitespace changes. Show changes sudoku.cc +24 −120 Original line number Original line Diff line number Diff line #include <stdlib.h> #include <stdlib.h> #include "sudoku.hh" #include "sudoku.hh" bool Grid::verbose = false; int main(int argc, char *argv[]) int main(int argc, char *argv[]) { { int found; if (argc != 2 && argc !=3) { if (argc != 2 && argc !=3) { std::cerr << "Usage: sudoku [-v] file" << std::endl; std::cerr << "Usage: sudoku [-v] file" << std::endl; return 1; return EXIT_USAGE; } } if (argc == 3 && (argv[1] == "-v" || argv[2] == "-v")) if (argc == 3 && argv[1] == (std::string) "-v") Grid::verbose = true; Grid::verbose = true; if (argc == 3 && argv[1] == (std::string) "-p") Grid::advprint = true; Grid *grid = new Grid(); Grid *grid = new Grid(); grid->load(argv[Grid::verbose ? 1 : 2]); if (!grid->load(argv[Grid::verbose || Grid::advprint ? 2 : 1])) { std::cerr << "Loading failed !" << std::endl; return EXIT_LOADFAIL; } if (Grid::verbose) { std::cout << "Loaded grid:" << std::endl; grid->print(); grid->print(); } grid->resolve(); grid->resolve(); if (grid->verify()) { found = grid->verify() ? EXIT_FOUND : EXIT_NOTFOUND; if (found == EXIT_FOUND && Grid::verbose > 0) std::cout << "Solution found." << std::endl; std::cout << "Solution found." << std::endl; grid->print(); grid->print(); } return found; } // // GRID // int Grid::load(const char *filename) { int val; std::fstream fs; std::cout << "coucou"; try { fs.open(filename); std::cout << "sex"; } catch (...) { std::cout << "sex"; } std::cout << filename << std::endl; for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) { fs >> std::dec >> val; std::cout << val << std::endl; //block_[i][j].set(val); } fs.close(); return 0; } void Grid::resolve() { } } void Grid::print() const std::ostream &operator<<(std::ostream &stream, const Block &blk) { { if (blk.value_ == 0) int i, j; stream << " "; else for (i = 0; i < GRID_SIDE; ++i) { stream << blk.value_; //show first line return stream; for (j = 0; j < GRID_SIDE; j += 3) if (j == GRID_SIDE - 3) std::cout << " --- --- ---" << std::endl; else std::cout << " --- --- --- "; //show nine group separator if (i > 0 && i % 3 == 0) { std::cout << std::endl; for (j = 0; j < GRID_SIDE; j += 3) if (j == GRID_SIDE - 3) std::cout << " --- --- ---" << std::endl; else std::cout << " --- --- --- "; } std::cout << "|"; for (j = 0; j < GRID_SIDE; ++j) { if (j > 0 && j % 3 == 0) std::cout << " |"; std::cout << " " << block_[i][j].get() << " |"; } std::cout << std::endl; } for (j = 0; j < GRID_SIDE; j += 3) if (j == GRID_SIDE - 3) std::cout << " --- --- ---" << std::endl; else std::cout << " --- --- --- "; } bool Grid::is_done() const { for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) if (block_[i][j].get() == 0) return false; return true; } bool Grid::verify() const { bool vertical_line[GRID_SIDE]; bool horizontal_line[GRID_SIDE]; int tmp; // check horizontals and verticales for (int i = 0; i < GRID_SIDE; ++i) { for (int j = 0; j < GRID_SIDE; ++j) horizontal_line[j] = vertical_line[j] = false; for (int j = 0; j < GRID_SIDE; ++j) { //horizontals tmp = block_[i][j].get() - 1; if (tmp < 0 || horizontal_line[tmp]) return false; horizontal_line[tmp] = true; //verticals tmp = block_[j][i].get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j] || !horizontal_line[j]) return false; } // check nine blocks (use vertical_block) for (int j = 0; j < GRID_SIDE; ++j) vertical_line[j] = false; for (int i = 0; i < GRID_SIDE; i += 3) for (int j = 0; j < GRID_SIDE; j += 3) for (int k = 0; k < 3; ++k) for (int l = 0; l < 3; ++l) { tmp = block_[i + k][j + l].get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j]) return false; return true; } } sudoku.hh +34 −5 Original line number Original line Diff line number Diff line Loading @@ -2,13 +2,22 @@ #ifndef SUDOKU_HH_ #ifndef SUDOKU_HH_ # define SUDOKU_HH_ # define SUDOKU_HH_ const int GRID_SIDE = 9; //must be able to divise 3 #include <cassert> #include <cassert> #include <ios> #include <ios> #include <iostream> #include <iostream> #include <fstream> #include <fstream> const int GRID_SIDE = 9; //must be able to divise 3 enum { EXIT_FOUND = 0, EXIT_NOTFOUND = 1, EXIT_USAGE = 2, EXIT_LOADFAIL = 3, EXIT_INV_POS = 4, EXIT_INV_VAL = 5 }; class Block class Block { { public: public: Loading @@ -22,12 +31,19 @@ public: assert(value > 0 && value <= GRID_SIDE); assert(value > 0 && value <= GRID_SIDE); return forbidden_[value]; return forbidden_[value]; } } int get() const { return value_; } int value_get() const { return value_; } bool is_forbid(int v) const { assert(v > 0 && v <= GRID_SIDE); return forbidden_[v - 1]; } void init(int val) { assert(val >= 0 && val <= GRID_SIDE); value_ = val; } void set(int val) { assert(val > 0 && val <= GRID_SIDE); value_ = val; } void set(int val) { assert(val > 0 && val <= GRID_SIDE); value_ = val; } void forbid(int val) { void forbid(int val) { assert(val > 0 && val <= GRID_SIDE); assert(val > 0 && val <= GRID_SIDE); if (val != value_) forbidden_[val] = true; forbidden_[val] = true; } } friend std::ostream &operator<<(std::ostream &stream, const Block &blk); private: private: int value_; int value_; bool forbidden_[GRID_SIDE]; bool forbidden_[GRID_SIDE]; Loading @@ -38,13 +54,26 @@ class Grid public: public: int load(const char *filename); int load(const char *filename); void print() const; void print() const; inline void print_line() const; bool verify() const; bool verify() const; bool is_done() const; bool is_done() const; void resolve(); void resolve(); void pose(int x, int y, int v); static bool verbose; static bool verbose; static bool advprint; private: private: Block block_[GRID_SIDE][GRID_SIDE]; Block block_[GRID_SIDE][GRID_SIDE]; }; }; void Grid::print_line() const { for (int j = 0; j < GRID_SIDE; ++j) { if (j % 3 == 0 && j > 0 && j < GRID_SIDE) std::cout << " "; std::cout << " ---"; if (j == GRID_SIDE - 1) std::cout << std::endl; } } #endif #endif Loading
Makefile +3 −3 Original line number Original line Diff line number Diff line Loading @@ -2,10 +2,10 @@ all: sudoku all: sudoku sudoku: sudoku.o sudoku.hh sudoku: sudoku.o grid.o g++ -Wall -Wextra -pedantic -ansi -g $< -o $@ g++ -Wall -Wextra -pedantic -ansi -g $^ -o $@ %.o:%.cc %.o:%.cc sudoku.hh g++ -Wall -Wextra -pedantic -ansi -g $< -o $@ -c g++ -Wall -Wextra -pedantic -ansi -g $< -o $@ -c clean: clean: Loading
grid.cc 0 → 100644 +145 −0 Original line number Original line Diff line number Diff line #include "sudoku.hh" bool Grid::verbose = false; bool Grid::advprint = false; int Grid::load(const char *filename) { int val; std::fstream fs; assert(filename); if (Grid::verbose) std::cout << "Loading file: " << filename << "..." << std::endl; fs.open(filename, std::fstream::in); if (!fs.is_open()) return 0; for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) { fs >> std::dec >> val; if (val < 0 || val > 9) { std::cerr << "Invalid value in file: " << val << std::endl; exit(EXIT_LOADFAIL); } if (val > 0) pose(i, j, val); //block_[i][j].set(val); } fs.close(); return 1; } void Grid::pose(int x, int y, int v) { if (x < 0 || x >= GRID_SIDE || y < 0 || y >= GRID_SIDE) { std::cerr << "Invalid position: " << x + 1 << ", " << y + 1 << std::endl; exit(EXIT_INV_POS); } if (v <= 0 || v > GRID_SIDE) { std::cerr << "Invalid value: " << v << std::endl; exit(EXIT_INV_VAL); } for (int i = 0; i < GRID_SIDE; ++i) { block_[x][i].forbid(v); block_[i][y].forbid(v); } for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) block_[(x / 3) * 3 + x][(y / 3) * 3 + y].forbid(v); } void Grid::resolve() { if (Grid::verbose) std::cout << "Resolving..." << std::endl; } void Grid::print() const { int i, j, k; for (i = 0; i < GRID_SIDE; ++i) { print_line(); if (i > 0 && i % 3 == 0) print_line(); if (Grid::advprint) { for (int l = 0; l < 3; ++l) { for (j = 0; j < GRID_SIDE; ++j) { if (j > 0 && j % 3 == 0) std::cout << "| "; std::cout << "|"; for (k = l * 3 + 1; k <= l * 3 + 3; ++k) if (block_[i][j].value_get() == k) std::cout << "\033[0;32m" << k << "\033[0m"; else if (block_[i][j].is_forbid(k)) std::cout << "\033[0;31m" << k << "\033[0m"; else std::cout << k; } std::cout << "|" << std::endl; } } else { std::cout << "|"; for (j = 0; j < GRID_SIDE; ++j) { if (j > 0 && j % 3 == 0) std::cout << " |"; std::cout << " " << block_[i][j] << " |"; } std::cout << std::endl; } } print_line(); } bool Grid::is_done() const { for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) if (block_[i][j].value_get() == 0) return false; return true; } bool Grid::verify() const { bool vertical_line[GRID_SIDE]; bool horizontal_line[GRID_SIDE]; int tmp; // check horizontals and verticales for (int i = 0; i < GRID_SIDE; ++i) { for (int j = 0; j < GRID_SIDE; ++j) horizontal_line[j] = vertical_line[j] = false; for (int j = 0; j < GRID_SIDE; ++j) { //horizontals tmp = block_[i][j].value_get() - 1; if (tmp < 0 || horizontal_line[tmp]) return false; horizontal_line[tmp] = true; //verticals tmp = block_[j][i].value_get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j] || !horizontal_line[j]) return false; } // check nine blocks (use vertical_block) for (int j = 0; j < GRID_SIDE; ++j) vertical_line[j] = false; for (int i = 0; i < GRID_SIDE; i += 3) for (int j = 0; j < GRID_SIDE; j += 3) for (int k = 0; k < 3; ++k) for (int l = 0; l < 3; ++l) { tmp = block_[i + k][j + l].value_get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j]) return false; return true; }
grids/metro-221→grids/demoniac/metro-221 +1 −1 File changed and moved.Contains only whitespace changes. Show changes
sudoku.cc +24 −120 Original line number Original line Diff line number Diff line #include <stdlib.h> #include <stdlib.h> #include "sudoku.hh" #include "sudoku.hh" bool Grid::verbose = false; int main(int argc, char *argv[]) int main(int argc, char *argv[]) { { int found; if (argc != 2 && argc !=3) { if (argc != 2 && argc !=3) { std::cerr << "Usage: sudoku [-v] file" << std::endl; std::cerr << "Usage: sudoku [-v] file" << std::endl; return 1; return EXIT_USAGE; } } if (argc == 3 && (argv[1] == "-v" || argv[2] == "-v")) if (argc == 3 && argv[1] == (std::string) "-v") Grid::verbose = true; Grid::verbose = true; if (argc == 3 && argv[1] == (std::string) "-p") Grid::advprint = true; Grid *grid = new Grid(); Grid *grid = new Grid(); grid->load(argv[Grid::verbose ? 1 : 2]); if (!grid->load(argv[Grid::verbose || Grid::advprint ? 2 : 1])) { std::cerr << "Loading failed !" << std::endl; return EXIT_LOADFAIL; } if (Grid::verbose) { std::cout << "Loaded grid:" << std::endl; grid->print(); grid->print(); } grid->resolve(); grid->resolve(); if (grid->verify()) { found = grid->verify() ? EXIT_FOUND : EXIT_NOTFOUND; if (found == EXIT_FOUND && Grid::verbose > 0) std::cout << "Solution found." << std::endl; std::cout << "Solution found." << std::endl; grid->print(); grid->print(); } return found; } // // GRID // int Grid::load(const char *filename) { int val; std::fstream fs; std::cout << "coucou"; try { fs.open(filename); std::cout << "sex"; } catch (...) { std::cout << "sex"; } std::cout << filename << std::endl; for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) { fs >> std::dec >> val; std::cout << val << std::endl; //block_[i][j].set(val); } fs.close(); return 0; } void Grid::resolve() { } } void Grid::print() const std::ostream &operator<<(std::ostream &stream, const Block &blk) { { if (blk.value_ == 0) int i, j; stream << " "; else for (i = 0; i < GRID_SIDE; ++i) { stream << blk.value_; //show first line return stream; for (j = 0; j < GRID_SIDE; j += 3) if (j == GRID_SIDE - 3) std::cout << " --- --- ---" << std::endl; else std::cout << " --- --- --- "; //show nine group separator if (i > 0 && i % 3 == 0) { std::cout << std::endl; for (j = 0; j < GRID_SIDE; j += 3) if (j == GRID_SIDE - 3) std::cout << " --- --- ---" << std::endl; else std::cout << " --- --- --- "; } std::cout << "|"; for (j = 0; j < GRID_SIDE; ++j) { if (j > 0 && j % 3 == 0) std::cout << " |"; std::cout << " " << block_[i][j].get() << " |"; } std::cout << std::endl; } for (j = 0; j < GRID_SIDE; j += 3) if (j == GRID_SIDE - 3) std::cout << " --- --- ---" << std::endl; else std::cout << " --- --- --- "; } bool Grid::is_done() const { for (int i = 0; i < GRID_SIDE; ++i) for (int j = 0; j < GRID_SIDE; ++j) if (block_[i][j].get() == 0) return false; return true; } bool Grid::verify() const { bool vertical_line[GRID_SIDE]; bool horizontal_line[GRID_SIDE]; int tmp; // check horizontals and verticales for (int i = 0; i < GRID_SIDE; ++i) { for (int j = 0; j < GRID_SIDE; ++j) horizontal_line[j] = vertical_line[j] = false; for (int j = 0; j < GRID_SIDE; ++j) { //horizontals tmp = block_[i][j].get() - 1; if (tmp < 0 || horizontal_line[tmp]) return false; horizontal_line[tmp] = true; //verticals tmp = block_[j][i].get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j] || !horizontal_line[j]) return false; } // check nine blocks (use vertical_block) for (int j = 0; j < GRID_SIDE; ++j) vertical_line[j] = false; for (int i = 0; i < GRID_SIDE; i += 3) for (int j = 0; j < GRID_SIDE; j += 3) for (int k = 0; k < 3; ++k) for (int l = 0; l < 3; ++l) { tmp = block_[i + k][j + l].get() - 1; if (tmp < 0 || vertical_line[tmp] == true) return false; vertical_line[tmp] = true; } for (int j = 0; j < GRID_SIDE; ++j) if (!vertical_line[j]) return false; return true; } }
sudoku.hh +34 −5 Original line number Original line Diff line number Diff line Loading @@ -2,13 +2,22 @@ #ifndef SUDOKU_HH_ #ifndef SUDOKU_HH_ # define SUDOKU_HH_ # define SUDOKU_HH_ const int GRID_SIDE = 9; //must be able to divise 3 #include <cassert> #include <cassert> #include <ios> #include <ios> #include <iostream> #include <iostream> #include <fstream> #include <fstream> const int GRID_SIDE = 9; //must be able to divise 3 enum { EXIT_FOUND = 0, EXIT_NOTFOUND = 1, EXIT_USAGE = 2, EXIT_LOADFAIL = 3, EXIT_INV_POS = 4, EXIT_INV_VAL = 5 }; class Block class Block { { public: public: Loading @@ -22,12 +31,19 @@ public: assert(value > 0 && value <= GRID_SIDE); assert(value > 0 && value <= GRID_SIDE); return forbidden_[value]; return forbidden_[value]; } } int get() const { return value_; } int value_get() const { return value_; } bool is_forbid(int v) const { assert(v > 0 && v <= GRID_SIDE); return forbidden_[v - 1]; } void init(int val) { assert(val >= 0 && val <= GRID_SIDE); value_ = val; } void set(int val) { assert(val > 0 && val <= GRID_SIDE); value_ = val; } void set(int val) { assert(val > 0 && val <= GRID_SIDE); value_ = val; } void forbid(int val) { void forbid(int val) { assert(val > 0 && val <= GRID_SIDE); assert(val > 0 && val <= GRID_SIDE); if (val != value_) forbidden_[val] = true; forbidden_[val] = true; } } friend std::ostream &operator<<(std::ostream &stream, const Block &blk); private: private: int value_; int value_; bool forbidden_[GRID_SIDE]; bool forbidden_[GRID_SIDE]; Loading @@ -38,13 +54,26 @@ class Grid public: public: int load(const char *filename); int load(const char *filename); void print() const; void print() const; inline void print_line() const; bool verify() const; bool verify() const; bool is_done() const; bool is_done() const; void resolve(); void resolve(); void pose(int x, int y, int v); static bool verbose; static bool verbose; static bool advprint; private: private: Block block_[GRID_SIDE][GRID_SIDE]; Block block_[GRID_SIDE][GRID_SIDE]; }; }; void Grid::print_line() const { for (int j = 0; j < GRID_SIDE; ++j) { if (j % 3 == 0 && j > 0 && j < GRID_SIDE) std::cout << " "; std::cout << " ---"; if (j == GRID_SIDE - 1) std::cout << std::endl; } } #endif #endif