Advertisement
Guest User

this is the usefulest thing in this little world

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