Verification in vector<vector<short> >

I am trying to find a way to verify the correctness of a Sudoku board. I was able to make a function but that function does not actually do anything. I made these based on user-defined classes and vector m_map is a vector<vector<cell> > of type cell. I would appreciate some help.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
bool verify(){
  int compareNUM = 0;
		int s;
		for(int row = 0; row < 9; row++){
		for (int col = 0; col < 9; col++){
	compareNUM = m_map[row][col].getNum();
			s = compareNUM;
		for(int iter = 8 - col; iter <= 8; iter--){
			if(compareNUM != m_map[row][iter].getNum()){
					return true;
						}
		if (m_map[row][iter].getNum() == 0)
	cout << "Error at Row " << char('P' + row) << ", Column " << char('A' + iter) << endl;
							}
						}
					}
		//check columns
		for(int col = 0; col < 9; col++){
		for (int row = 0; row < 9; row++){
			compareNUM = m_map[row][col].getNum();
			s = compareNUM;
		for(int iter = 8 - row; iter <= 8; iter--){
			if(compareNUM != m_map[iter][col].getNum()){
					return true;
									}
		if (m_map[iter][col].getNum() == 0)
	cout << "Error at Column " << char('A' + col) << ", Row " << char('P' + iter) << endl;
								}
							}
							}
}
Something along these lines, perhaps (caveat: untested, brute-force):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <vector>
#include <algorithm>
#include <set>

constexpr std::size_t SZ_BOARD = 9 ; // board is SZ_BOARD x SZ_BOARD
constexpr std::size_t SZ_GRID = 3 ; // a sub-grid is SZ_GRID x SZ_GRID
constexpr int EMPTY = 0 ; // 0 is used to indicate an unfilled cell

// filled cells contain the number, unfilled cells contain EMPTY
using board_t = std::vector< std::vector<int> > ;

// return an empty vector if row_num is invalid
std::vector<int> row( const board_t& board, std::size_t row_num )
{ return row_num < SZ_BOARD ? board[row_num] : std::vector<int>{} ; }

// return the nine cells forming column col_num
// return an empty vector if col_num is invalid
std::vector<int> col( const board_t& board, std::size_t col_num )
{
    std::vector<int> column ;
    if( col_num < SZ_BOARD ) for( const auto& row : board ) column.push_back( row[col_num] ) ;
    return column ;
}

// return the nine cells forming the sub-grid
// sub-grids are numbered 0 .. 8 starting with the top-left-grid
// return an empty vector if grid_num is invalid
std::vector<int> sub_grid( const board_t& board, std::size_t grid_num )
{
    std::vector<int> grid ;

    if( grid_num < SZ_BOARD )
    {
     const std::size_t start_row = SZ_GRID * (grid_num/SZ_GRID) ;
     const std::size_t start_col = SZ_GRID * (grid_num%SZ_GRID) ;

     for( auto row = start_row ; row < (start_row+SZ_GRID) ; ++row )
        for( auto col = start_col ; col < (start_col+SZ_GRID) ; ++col )
            grid.push_back( board[row][col] ) ;
    }

    return grid ;
}

// verify that there are no invalid entries in the segment
// partial == true: no invalid entries so far (segment may contain empty cells)
// partial == false (default): all cells must be filled (no empty cells)
bool verify_segment( std::vector<int> segment, bool partial = false )
{
    if( segment.size() != SZ_BOARD ) return false ; // invalid segment size

    // if partial == true, move all EMPTY cells to the end of the back of the sequence
    // end: the non-empty values are up to (not including) end
    const auto end = partial ? std::remove( std::begin(segment), std::end(segment), EMPTY ) :
                               std::end(segment) ;

    const auto begin = std::begin(segment) ;

    // return true if: all non-empty numbers are within range [1,9]
    //                 and no number is repeated (size of set == number of non-empty cells)
    return std::all_of( begin, end, [] ( int v ) { return v > 0 && v < 10 ; } ) &&
           std::set<int>( begin, end ).size() == std::distance(begin,end) ;
}

// verify that there are no invalid entries in the board
// partial == true: no invalid entries so far (segments may contain empty cells)
// partial == false (default): all cells must be filled (no empty cells)
bool verify_board( const board_t& board, bool partial = false )
{
    for( std::size_t i = 0 ; i < SZ_BOARD ; ++i )
    {
        if( !verify_segment( row( board, i ), partial ) ) return false ;
        if( !verify_segment( col( board, i ), partial ) ) return false ;
        if( !verify_segment( sub_grid( board, i ), partial ) ) return false ;
    }
    return true ;
}
Mr. JLBorges, thanks for your response but I haven't much experience using sets as of yet so there is much in this code I have yet to learn. I was able to fix up the above the code I posted, however there seems to be some flaws...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void verify(){
			int total = 0;
			int compareNUM = 0;
			int count = 0;
			for (int row = 0; row < 9; row++){
				for (int col = 0; col < 9; col++){
					total += m_map[row][col].getNum();
				}
			}
			if ((total/9) % 45 == 0) cout << "Invalid Board\n"; //Ensures the correctness of the board

			else cout << "All Columns, Rows, and Components are OK..." << endl;
			//Used to pinpoint the location of the error
			for(int n = 1; n <= 3; n++){ //1st loop is meant to help do the process 9 times over
				int s = 0; int t = 0; //dummy variable to help initiate a changing initializer
				for (int row = s*n; row < 3*n; row++, s++){ //counting rows
					for (int col = t*n; col < 3*n; col++, t++){//for each row set, counting columns
						compareNUM = m_map[row][col].getNum();
						if (compareNUM == m_map[row][col].getNum()){//To check if number appears twice in 3x3 box
							count++;
							if (count <= 2)
							cout << "Found Inconsistency in Component Starting at Row " << char('P' + t*n)
							<<" Column" << char('A' + t*n) << endl; break; continue;
							}
						else if (m_map[row][col].getNum() == 0){ //In case the User erases a value
						cout << "Found Inconsistency in Row " << char('P' + row)
						<< "Column" << char('A' + col) << endl;
						cout << "Found Inconsistency in Component Starting at Row " << char('P' + s*n)
						<<" Column" << char('A' + t*n) << endl; break; continue;}
							}
						}
			}
		}
Topic archived. No new replies allowed.