Advertisement
Guest User

cgh

a guest
Jan 21st, 2020
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.58 KB | None | 0 0
  1. /*
  2. Suduko Solver
  3. by someone
  4.  
  5. examples of sudoku available at http://magictour.free.fr/top1465
  6. */
  7.  
  8. #include <iostream>
  9. #include <string>
  10. //#include <array>
  11. #include <algorithm>
  12. #include <exception>
  13. #include <cctype>
  14. #include <vector>
  15. #include <memory>
  16.  
  17. class InitNbrSudokuError : public std::runtime_error
  18. {
  19. public :
  20.  
  21.     InitNbrSudokuError(std::string str) : std::runtime_error(str) {}
  22.  
  23.     enum TypeErr
  24.     {
  25.         err_alloc
  26.     };
  27.    
  28.     TypeErr getErrType()
  29.     {
  30.         return err_alloc;
  31.     }
  32. };
  33.  
  34. class NbrSudoku
  35. {
  36. public :
  37.    
  38.     NbrSudoku();
  39.     void init(int val);
  40.    
  41.     NbrSudoku(const NbrSudoku& val);
  42.    
  43.     int getNbr() const;
  44.     std::vector<int>& getVec() const;
  45.    
  46.     bool isValid() const;
  47.    
  48.     void addLittleNbr(int val);
  49.    
  50.     void putOffLitteNbr(int val);
  51.    
  52. private :
  53.  
  54.     int nbr;
  55.    
  56.     std::unique_ptr<std::vector<int>> listInt;
  57. };
  58.  
  59. std::ostream& operator<<(std::ostream& outuput, NbrSudoku a);
  60. //external overloading lul
  61.  
  62. NbrSudoku::NbrSudoku()
  63. {
  64.     listInt = nullptr;
  65. }
  66.  
  67. NbrSudoku::NbrSudoku(const NbrSudoku& val)
  68. {
  69.     nbr = val.nbr;
  70.    
  71.     try
  72.     {
  73.         listInt = std::unique_ptr<std::vector<int>>(new std::vector<int> {val.getVec()});
  74.     }
  75.     catch (const InitNbrSudokuError& e)
  76.     {
  77.         listInt = std::unique_ptr<std::vector<int>>(new std::vector<int> {});
  78.     }
  79. }
  80.  
  81. void NbrSudoku::addLittleNbr(int val)
  82. {
  83.     listInt->push_back(val);
  84. }
  85.  
  86. int NbrSudoku::getNbr() const
  87. {
  88.     return nbr;
  89. }
  90.  
  91. bool NbrSudoku::isValid() const
  92. {
  93.     if(nbr == 0)
  94.     {
  95.         return false; //the vector is used
  96.     }
  97.     else
  98.     {
  99.         return true;
  100.     }
  101. }
  102.  
  103. std::vector<int>& NbrSudoku::getVec() const
  104. {
  105.     if(listInt != nullptr)
  106.     {
  107.         return *listInt;
  108.     }
  109.     else
  110.     {
  111.         throw InitNbrSudokuError("There aren't any vector to give here, sorry");
  112.     }
  113. }
  114.  
  115. void NbrSudoku::init(int val)
  116. {
  117.     nbr = val;
  118.        
  119.     if(nbr == 0) //if the case is empty
  120.     {
  121.         listInt = std::unique_ptr<std::vector<int>>(new std::vector<int> {}) ;
  122.     }
  123. }
  124.  
  125. std::ostream& operator<<(std::ostream& outuput, NbrSudoku a)
  126. {
  127.     if(a.isValid())
  128.     {
  129.         outuput << a.getNbr();
  130.     }
  131.     else
  132.     {
  133.         for(unsigned int i = 0; i < a.getVec().size() ; i++)
  134.         {
  135.             outuput << a.getVec()[i] << " ";
  136.         }
  137.     }
  138.    
  139.     return outuput;
  140. }
  141.  
  142. void NbrSudoku::putOffLitteNbr(int val)
  143. {
  144.     std::vector<int>::iterator listVirer {std::find_if(listInt->begin(), listInt->end(), [](int val_) -> bool {retrun val == val_;})};
  145.    
  146.     listInt->esrase(listVirer);
  147. }
  148.  
  149. class Sudoku
  150. {
  151. public :
  152.  
  153.     Sudoku(std::string sentence);
  154.    
  155.     std::string toString();
  156.    
  157.     bool isValid();
  158.    
  159.     void addLittleNbrEveywhere();
  160.     void addLittleNbrForOne(int i, int j);
  161.    
  162.     std::ostream& coutLittleNbr(std::ostream& prut);
  163.    
  164. private :
  165.  
  166.     std::vector<std::vector<NbrSudoku>> listNbr;
  167.     //Wide spaces are saved into 0
  168. };
  169.  
  170. Sudoku::Sudoku(std::string sentence)
  171. {
  172.     listNbr  = std::vector<std::vector<NbrSudoku>>
  173.                 {9, std::vector<NbrSudoku>
  174.                     {9, NbrSudoku {/* default constructor */}   }  };
  175.  
  176.     if(sentence.size() != 81 ||
  177.         !std::any_of(sentence.begin(), sentence.end(), [](char a) -> bool
  178.             {
  179.                 if(!isdigit(a) || a != '.')
  180.                 {
  181.                     return true;
  182.                 }
  183.                
  184.                 return false;
  185.             }) )
  186.     {
  187.         throw std::runtime_error("This isn't a valid input");
  188.     }
  189.    
  190.     for(unsigned int i = 0; i < listNbr.size() ; i++)
  191.     {
  192.         for(unsigned int j = 0; j < listNbr[i].size() ; j++)
  193.         {
  194.             char nbr = sentence[i * 9 + j];
  195.            
  196.             if(isdigit(nbr))
  197.             {
  198.                 listNbr[i][j].init(nbr - '0');
  199.             }
  200.             else if(nbr == '.')
  201.             {
  202.                 listNbr[i][j].init(0);
  203.             }
  204.             else
  205.             {
  206.                 throw std::runtime_error("Something went wrong");
  207.             }
  208.         }
  209.     }
  210. }
  211.  
  212. std::string Sudoku::toString()
  213. {
  214.     std::string output;
  215.    
  216.     for(unsigned int i = 0; i < listNbr.size() ; i++)
  217.     {
  218.         if(i % 3 == 0)
  219.         {
  220.             output += "+ - - - + - - - + - - - +\n";
  221.         }
  222.        
  223.         for(unsigned int j = 0 ; j < listNbr.size() ; j++)
  224.         {
  225.             if(j % 3 == 0)
  226.             {
  227.                 output += "| ";
  228.             }
  229.            
  230.             if(listNbr[i][j].getNbr() == 0)
  231.             {
  232.                 output += ".";
  233.             }
  234.             else
  235.             {
  236.                 output += std::to_string(listNbr[i][j].getNbr());
  237.             }
  238.            
  239.             output += " ";
  240.         }
  241.         output += "|\n";
  242.     }
  243.    
  244.     output += "+ - - - + - - - + - - - +\n";
  245.    
  246.     return output;
  247. }
  248.  
  249. bool Sudoku::isValid()
  250. {
  251.    
  252.    
  253.     //try for each ligne
  254.     for(unsigned int i = 0 ; i < listNbr.size() ; i++)
  255.     {
  256.         std::vector<int> listFind;
  257.        
  258.         for(unsigned int j = 0 ; j < listNbr[i].size() ; j++)
  259.         {
  260.             int val = listNbr[i][j].getNbr();
  261.            
  262.             listFind.push_back(val);
  263.            
  264.             if(any_of(listFind.begin(), listFind.end(),
  265.                 [val](int nbrTest) -> bool
  266.                 {
  267.                     return nbrTest == val;
  268.                 }))
  269.             {
  270.                 //the "pitu" come back
  271.                 std::cout << "pitu" << std::endl;
  272.                
  273.                 return false;
  274.             }
  275.         }
  276.        
  277.         if(listFind.size() != 9)
  278.         {
  279.             return false;
  280.         }
  281.     }
  282.    
  283.     //try for each row
  284.     for(unsigned int i = 0 ; i < listNbr[0].size() ; i++)
  285.     {
  286.         std::vector<int> listFind;
  287.        
  288.         for(unsigned int j = 0 ; j < listNbr.size() ; j++)
  289.         {
  290.             int val {listNbr[j][i].getNbr()};
  291.            
  292.             listFind.push_back(val);
  293.            
  294.             if(std::any_of(listFind.begin(), listFind.end(),
  295.                 [val](int nbrTest) -> bool
  296.                 {
  297.                     return nbrTest == val;
  298.                 }))
  299.             {
  300.                 std::cout << "pruti" << std::endl;
  301.                 return false; //salut ca va
  302.             }
  303.         }
  304.        
  305.         if(listFind.size() != 9)
  306.         {
  307.             return false;
  308.         }
  309.     }
  310.    
  311.     //the hard part : the cases
  312.     for(unsigned int nbrCase = 0; nbrCase < 9 ; nbrCase++)
  313.     {
  314.         std::vector<int> listFind;
  315.         for(unsigned int i = nbrCase % 3 * 3; i < (nbrCase) % 3 * 3 + 3; i++)
  316.         {
  317.             std::vector<int> listFind;
  318.            
  319.             for(unsigned int j = nbrCase / 3 * 3; j < (nbrCase) / 3 * 3 + 3; j++)
  320.             {
  321.                 int val {listNbr[j][i].getNbr()};
  322.                
  323.                 listFind.push_back(val);
  324.            
  325.                 if(std::any_of(listFind.begin(), listFind.end(),
  326.                     [val](int nbrTest) -> bool
  327.                     {
  328.                         return nbrTest == val;
  329.                     }))
  330.                 {
  331.                     std::cout << "pruti" << std::endl;
  332.                     return false; //salut ca va
  333.                 }
  334.             }
  335.         }
  336.     }
  337.    
  338.     return true;
  339. }
  340.  
  341. bool ifIsNotInVect(int valTest, std::vector<int> v)
  342. {
  343.     return std::find(v.begin(), v.end(), valTest) == v.end();
  344. }
  345.  
  346. void Sudoku::addLittleNbrForOne(int x, int y)
  347. {
  348.     std::vector<int> nbrFind;
  349.    
  350.    
  351.     //for each row
  352.     for(unsigned int i = 0; i < listNbr.size() ; i++)
  353.     {
  354.         //std::cout << ifIsNotInVect(listNbr[i][y].getNbr(), nbrFind) << " " << listNbr[i][y].getNbr() << std::endl;
  355.        
  356.         if(listNbr[i][y].getNbr() != 0 && ifIsNotInVect(listNbr[i][y].getNbr(), nbrFind) )
  357.         {
  358.             nbrFind.push_back(listNbr[i][y].getNbr());
  359.             //std::cout << listNbr[i][y].getNbr() << " ";
  360.         }
  361.     }
  362.    
  363.     //std::cout << "/ ";
  364.    
  365.     //for each line
  366.     for(unsigned int j = 0; j < listNbr[x].size() ; j++)
  367.     {
  368.         if(listNbr[x][j].getNbr() != 0 && ifIsNotInVect(listNbr[x][j].getNbr(), nbrFind))
  369.         {
  370.             nbrFind.push_back(listNbr[x][j].getNbr());
  371.             //std::cout << listNbr[x][j].getNbr() << " ";
  372.         }
  373.     }
  374.    
  375.     //std::cout << "/ ";
  376.    
  377.     //for each case
  378.     int nbrCase = (x / 3) * 3 + (y / 3);
  379.    
  380.     //std::cout << "- " << nbrCase << " " << x << " " << y << std::endl;
  381.    
  382.     for(int i = nbrCase % 3 * 3; i < (nbrCase) % 3 * 3 + 3; i++)
  383.     {
  384.         for(int j = (nbrCase) / 3 * 3; j < (nbrCase) / 3 * 3 + 3; j++)
  385.         {
  386.             if(listNbr[j][i].getNbr() != 0 && ifIsNotInVect(listNbr[j][i].getNbr(), nbrFind))
  387.             {
  388.                 nbrFind.push_back(listNbr[i][j].getNbr());
  389.                 //std::cout << listNbr[j][i].getNbr() << " ";
  390.             }
  391.             //std::cout << listNbr[j][i].getNbr() << " ";
  392.         }
  393.         //std::cout << std::endl;
  394.     }
  395.    
  396.     //std::cout << std::endl;
  397.    
  398.     for(int i = 1; i <= 9; i++)
  399.     {
  400.         if(std::count(nbrFind.begin(), nbrFind.end(), i) == 0)
  401.         {
  402.             listNbr[x][y].addLittleNbr(i);
  403.         }
  404.     }
  405. }
  406.  
  407. void Sudoku::addLittleNbrEveywhere()
  408. {
  409.     for(unsigned int i = 0; i < listNbr.size() ; i++)
  410.     {
  411.         for(unsigned int j = 0; j < listNbr[i].size() ; j++)
  412.         {
  413.             if(listNbr[i][j].getNbr() == 0)
  414.             {
  415.                 addLittleNbrForOne(i, j);
  416.             }
  417.         }
  418.     }
  419. }
  420.  
  421. std::ostream& Sudoku::coutLittleNbr(std::ostream& prut)
  422. {
  423.     for(unsigned int i = 0 ; i < listNbr.size() ; i++)
  424.     {
  425.         for(unsigned int j = 0 ; j < listNbr[i].size() ; j++)
  426.         {
  427.             prut << listNbr[i][j] << std::endl;
  428.         }
  429.         prut << std::endl;
  430.     }
  431.     return prut;
  432. }
  433.  
  434. std::ostream& operator<<(std::ostream& output, Sudoku s)
  435. {
  436.     output << s.toString();
  437.     return output;
  438. }
  439.  
  440. int main()
  441. {
  442.     try
  443.     {
  444.         Sudoku a("4...3.......6..8..........1....5..9..8....6...7.2........1.27..5.3....4.9........");
  445.         std::cout << a << std::endl;
  446.         std::cout << a.isValid() << std::endl << std::endl;
  447.        
  448.         a.addLittleNbrEveywhere();
  449.        
  450.         std::cout << std::endl << std::endl;
  451.        
  452.         a.coutLittleNbr(std::cout);
  453.         std::cout << std::endl;
  454.         // ui c la flemme de surcharger l'operateur << une deusième fois
  455.     }
  456.     catch (const std::exception& e)
  457.     {
  458.         std::cout << "error : " << e.what() << std::endl;
  459.     }
  460.  
  461.     return 0;
  462. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement