I'm writing a sudoku col/row validator, what is does is:
- Reads user input on how many Sudoku instances to validate.
- Reads the sudoku matrix grid 9x9 (for me, in my specific case 9x9) into a 2d array. Each line read/row should contain something like:
8 2 1 3 6 4 9 7 5
. - Validates each row and column by flipping a 9 bit bitset to test whether all columns and rows contains nums from 1-9.
Please note that the only purpose of this program is to validate sudoku columns/rows as specified and not to completely validate it. i.e also checking each sudoku block.
How can I improve my code? I believe there's lots to it, naming conventions, fundamental approach...etc..etc.
#include <iostream>
#include <sstream>
#include <bitset>
namespace Constants
{
constexpr int ROW_COL_SIZE = 9;
const std::string STR_YES = "YES";
const std::string STR_NO = "NO";
}
template<unsigned int N>
class Sudoku
{
private:
int m_matrix[N][N] {{0}};
public:
void ReadRows();
std::string strIsValid() const;
};
template<unsigned int N>void Sudoku<N>::ReadRows()
{
for(unsigned int row{0}; row<N; row++)
{
static std::string line;
std::getline(std::cin, line);
std::istringstream issline(line);
int readnum {0};
for(unsigned int i{0}; i<N; i++)
{
issline >> readnum;
m_matrix[row][i] = readnum;
}
}
}
template<unsigned int N>std::string Sudoku<N>::strIsValid() const
{
//9bit default ctor all zeroes, 000000000
std::bitset<N> bitRow[N];
std::bitset<N> bitCol[N];
for(int i{0}; i<N; i++)
{
for(int j{0}; j<N; j++)
{
bitRow[i].flip(m_matrix[i][j]-1); //verify nums 1-9 row, bitset index is 0 not 1.
bitCol[i].flip(m_matrix[j][i]-1); //verify nums 1-9 col
}
if(!bitRow[i].all() && !bitCol[i].all())
{
return Constants::STR_NO;
}
}
return Constants::STR_YES;
}
int main(int, char**)
{
int instances {0};
std::cin >> instances;
std::cin.clear();
std::cin.ignore();
for(int i{0}; i<instances; i++)
{
std::cout << "Instance " << i+1 << std::endl;
Sudoku<Constants::ROW_COL_SIZE> sudokuInstance;
sudokuInstance.ReadRows();
std::cout << sudokuInstance.strIsValid() << std::endl << std::endl;
}
return 0;
}