Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Suduko Solver
- by someone
- examples of sudoku available at http://magictour.free.fr/top1465
- */
- #include <iostream>
- #include <string>
- //#include <array>
- #include <algorithm>
- #include <exception>
- #include <cctype>
- #include <vector>
- #include <memory>
- class InitNbrSudokuError : public std::runtime_error
- {
- public :
- InitNbrSudokuError(std::string str) : std::runtime_error(str) {}
- enum TypeErr
- {
- err_alloc
- };
- TypeErr getErrType()
- {
- return err_alloc;
- }
- };
- class NbrSudoku
- {
- public :
- NbrSudoku();
- void init(int val);
- NbrSudoku(const NbrSudoku& val);
- int getNbr() const;
- std::vector<int>& getVec() const;
- bool isValid() const;
- void addLittleNbr(int val);
- void putOffLitteNbr(int val);
- private :
- int nbr;
- std::unique_ptr<std::vector<int>> listInt;
- };
- std::ostream& operator<<(std::ostream& outuput, NbrSudoku a);
- //external overloading lul
- NbrSudoku::NbrSudoku()
- {
- listInt = nullptr;
- }
- NbrSudoku::NbrSudoku(const NbrSudoku& val)
- {
- nbr = val.nbr;
- try
- {
- listInt = std::unique_ptr<std::vector<int>>(new std::vector<int> {val.getVec()});
- }
- catch (const InitNbrSudokuError& e)
- {
- listInt = std::unique_ptr<std::vector<int>>(new std::vector<int> {});
- }
- }
- void NbrSudoku::addLittleNbr(int val)
- {
- listInt->push_back(val);
- }
- int NbrSudoku::getNbr() const
- {
- return nbr;
- }
- bool NbrSudoku::isValid() const
- {
- if(nbr == 0)
- {
- return false; //the vector is used
- }
- else
- {
- return true;
- }
- }
- std::vector<int>& NbrSudoku::getVec() const
- {
- if(listInt != nullptr)
- {
- return *listInt;
- }
- else
- {
- throw InitNbrSudokuError("There aren't any vector to give here, sorry");
- }
- }
- void NbrSudoku::init(int val)
- {
- nbr = val;
- if(nbr == 0) //if the case is empty
- {
- listInt = std::unique_ptr<std::vector<int>>(new std::vector<int> {}) ;
- }
- }
- std::ostream& operator<<(std::ostream& outuput, NbrSudoku a)
- {
- if(a.isValid())
- {
- outuput << a.getNbr();
- }
- else
- {
- for(unsigned int i = 0; i < a.getVec().size() ; i++)
- {
- outuput << a.getVec()[i] << " ";
- }
- }
- return outuput;
- }
- void NbrSudoku::putOffLitteNbr(int val)
- {
- std::vector<int>::iterator listVirer {std::find_if(listInt->begin(), listInt->end(), [](int val_) -> bool {retrun val == val_;})};
- listInt->esrase(listVirer);
- }
- class Sudoku
- {
- public :
- Sudoku(std::string sentence);
- std::string toString();
- bool isValid();
- void addLittleNbrEveywhere();
- void addLittleNbrForOne(int i, int j);
- std::ostream& coutLittleNbr(std::ostream& prut);
- private :
- std::vector<std::vector<NbrSudoku>> listNbr;
- //Wide spaces are saved into 0
- };
- Sudoku::Sudoku(std::string sentence)
- {
- listNbr = std::vector<std::vector<NbrSudoku>>
- {9, std::vector<NbrSudoku>
- {9, NbrSudoku {/* default constructor */} } };
- if(sentence.size() != 81 ||
- !std::any_of(sentence.begin(), sentence.end(), [](char a) -> bool
- {
- if(!isdigit(a) || a != '.')
- {
- return true;
- }
- return false;
- }) )
- {
- throw std::runtime_error("This isn't a valid input");
- }
- for(unsigned int i = 0; i < listNbr.size() ; i++)
- {
- for(unsigned int j = 0; j < listNbr[i].size() ; j++)
- {
- char nbr = sentence[i * 9 + j];
- if(isdigit(nbr))
- {
- listNbr[i][j].init(nbr - '0');
- }
- else if(nbr == '.')
- {
- listNbr[i][j].init(0);
- }
- else
- {
- throw std::runtime_error("Something went wrong");
- }
- }
- }
- }
- std::string Sudoku::toString()
- {
- std::string output;
- for(unsigned int i = 0; i < listNbr.size() ; i++)
- {
- if(i % 3 == 0)
- {
- output += "+ - - - + - - - + - - - +\n";
- }
- for(unsigned int j = 0 ; j < listNbr.size() ; j++)
- {
- if(j % 3 == 0)
- {
- output += "| ";
- }
- if(listNbr[i][j].getNbr() == 0)
- {
- output += ".";
- }
- else
- {
- output += std::to_string(listNbr[i][j].getNbr());
- }
- output += " ";
- }
- output += "|\n";
- }
- output += "+ - - - + - - - + - - - +\n";
- return output;
- }
- bool Sudoku::isValid()
- {
- //try for each ligne
- for(unsigned int i = 0 ; i < listNbr.size() ; i++)
- {
- std::vector<int> listFind;
- for(unsigned int j = 0 ; j < listNbr[i].size() ; j++)
- {
- int val = listNbr[i][j].getNbr();
- listFind.push_back(val);
- if(any_of(listFind.begin(), listFind.end(),
- [val](int nbrTest) -> bool
- {
- return nbrTest == val;
- }))
- {
- //the "pitu" come back
- std::cout << "pitu" << std::endl;
- return false;
- }
- }
- if(listFind.size() != 9)
- {
- return false;
- }
- }
- //try for each row
- for(unsigned int i = 0 ; i < listNbr[0].size() ; i++)
- {
- std::vector<int> listFind;
- for(unsigned int j = 0 ; j < listNbr.size() ; j++)
- {
- int val {listNbr[j][i].getNbr()};
- listFind.push_back(val);
- if(std::any_of(listFind.begin(), listFind.end(),
- [val](int nbrTest) -> bool
- {
- return nbrTest == val;
- }))
- {
- std::cout << "pruti" << std::endl;
- return false; //salut ca va
- }
- }
- if(listFind.size() != 9)
- {
- return false;
- }
- }
- //the hard part : the cases
- for(unsigned int nbrCase = 0; nbrCase < 9 ; nbrCase++)
- {
- std::vector<int> listFind;
- for(unsigned int i = nbrCase % 3 * 3; i < (nbrCase) % 3 * 3 + 3; i++)
- {
- std::vector<int> listFind;
- for(unsigned int j = nbrCase / 3 * 3; j < (nbrCase) / 3 * 3 + 3; j++)
- {
- int val {listNbr[j][i].getNbr()};
- listFind.push_back(val);
- if(std::any_of(listFind.begin(), listFind.end(),
- [val](int nbrTest) -> bool
- {
- return nbrTest == val;
- }))
- {
- std::cout << "pruti" << std::endl;
- return false; //salut ca va
- }
- }
- }
- }
- return true;
- }
- bool ifIsNotInVect(int valTest, std::vector<int> v)
- {
- return std::find(v.begin(), v.end(), valTest) == v.end();
- }
- void Sudoku::addLittleNbrForOne(int x, int y)
- {
- std::vector<int> nbrFind;
- //for each row
- for(unsigned int i = 0; i < listNbr.size() ; i++)
- {
- //std::cout << ifIsNotInVect(listNbr[i][y].getNbr(), nbrFind) << " " << listNbr[i][y].getNbr() << std::endl;
- if(listNbr[i][y].getNbr() != 0 && ifIsNotInVect(listNbr[i][y].getNbr(), nbrFind) )
- {
- nbrFind.push_back(listNbr[i][y].getNbr());
- //std::cout << listNbr[i][y].getNbr() << " ";
- }
- }
- //std::cout << "/ ";
- //for each line
- for(unsigned int j = 0; j < listNbr[x].size() ; j++)
- {
- if(listNbr[x][j].getNbr() != 0 && ifIsNotInVect(listNbr[x][j].getNbr(), nbrFind))
- {
- nbrFind.push_back(listNbr[x][j].getNbr());
- //std::cout << listNbr[x][j].getNbr() << " ";
- }
- }
- //std::cout << "/ ";
- //for each case
- int nbrCase = (x / 3) * 3 + (y / 3);
- //std::cout << "- " << nbrCase << " " << x << " " << y << std::endl;
- for(int i = nbrCase % 3 * 3; i < (nbrCase) % 3 * 3 + 3; i++)
- {
- for(int j = (nbrCase) / 3 * 3; j < (nbrCase) / 3 * 3 + 3; j++)
- {
- if(listNbr[j][i].getNbr() != 0 && ifIsNotInVect(listNbr[j][i].getNbr(), nbrFind))
- {
- nbrFind.push_back(listNbr[i][j].getNbr());
- //std::cout << listNbr[j][i].getNbr() << " ";
- }
- //std::cout << listNbr[j][i].getNbr() << " ";
- }
- //std::cout << std::endl;
- }
- //std::cout << std::endl;
- for(int i = 1; i <= 9; i++)
- {
- if(std::count(nbrFind.begin(), nbrFind.end(), i) == 0)
- {
- listNbr[x][y].addLittleNbr(i);
- }
- }
- }
- void Sudoku::addLittleNbrEveywhere()
- {
- for(unsigned int i = 0; i < listNbr.size() ; i++)
- {
- for(unsigned int j = 0; j < listNbr[i].size() ; j++)
- {
- if(listNbr[i][j].getNbr() == 0)
- {
- addLittleNbrForOne(i, j);
- }
- }
- }
- }
- std::ostream& Sudoku::coutLittleNbr(std::ostream& prut)
- {
- for(unsigned int i = 0 ; i < listNbr.size() ; i++)
- {
- for(unsigned int j = 0 ; j < listNbr[i].size() ; j++)
- {
- prut << listNbr[i][j] << std::endl;
- }
- prut << std::endl;
- }
- return prut;
- }
- std::ostream& operator<<(std::ostream& output, Sudoku s)
- {
- output << s.toString();
- return output;
- }
- int main()
- {
- try
- {
- Sudoku a("4...3.......6..8..........1....5..9..8....6...7.2........1.27..5.3....4.9........");
- std::cout << a << std::endl;
- std::cout << a.isValid() << std::endl << std::endl;
- a.addLittleNbrEveywhere();
- std::cout << std::endl << std::endl;
- a.coutLittleNbr(std::cout);
- std::cout << std::endl;
- // ui c la flemme de surcharger l'operateur << une deusième fois
- }
- catch (const std::exception& e)
- {
- std::cout << "error : " << e.what() << std::endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement