[Q ] Use parameterized class and concept of constraints to solve following 3 Sudoku and print their solution. The class parameter denotes the size of Sudoku (N x N). Here N can be multiple of 2 or 3.
{A] - - - 3
- - - 1
1 - - -
2 - - -
[B] - 4 - - - -
- 5 6 - - -
5 - - 3 2 -
- 2 3 - - 5
- - - 5 1 -
- - - - 6 -
[C] - 9 8 - - 3 7 - 6
- - 2 - - - - 8 -
- - - - - 4 1 - 9
- - 6 - - - - - -
- 7 - 5 - 9 - - -
- - - - 7 - - - 8
1 6 - - - - 5 - -
- - - - 4 - - - -
- - 3 - 2 7 - - -
I don’t want to use Unique Constraint as some Older Simulators don’t support them , although a Solution with Unique Constraint would also be appreciated .
Row and Column with Unique Element is something I achieved but the individual Constraint for 2X2 OR 3X2 OR 3X3 box I am confused with
you can find the below logic that contains constraints for solving sudoku puzzle with 9 * 9 size. you can use this logic to come with a generic logic for other sizes as well. Please find the below code.
class sudoku;
rand int unsigned item[9][9];
int unsigned problem[9][9]; // the problem data (9*9 matrix with 0 in the blank spaces)
constraint c1{foreach(item[i,j])
item[i][j] inside {[1:9]};}
constraint c2{foreach(item[i,j]) // this constraint is for getting unique elements in each row
foreach(item[,k])
if(j != k)
item[i][j] != item[i][k];}
constraint c3{foreach(item[i,j]) // this constraint is for getting unique elements in each column
foreach(item[k,])
if(i != k)
item[i][j] != item[k][j];}
constraint c4{foreach(item[i,j]) // this constraint is for getting unique elements in each matrix of 3 * 3
foreach(item[k,l])
if((i/3 == k/3)&&(j/3 == l/3)&&(i!=k)&&(j!=l))
item[i][j]!=item[k][l];}
constraint c5{foreach(item[i,j])
if(problem[i][j] != 0)
item[i][j] == problem[i][j];}
function int get_solution(int unsigned prob[9][9]);
problem = prob;
return this.randomize();
endfunction
function void print();
int k,l;
$display("\n\n");
for(int i=0; i<9; i++)
begin
for(int j=0; j<9; j++)
begin
$write(" %0d", this.item[i][j]);
l++;
if(l%3 == 0)
$write(" ");
end
$display("");
k++;
if(k%3 == 0)
$display("");
end
$display("\n\n");
endfunction
endclass
Here is one method using unique. If you do not want to use unique, you can just replace unique with an equivalent constraint.
The solution below is not scalable for other sudoku sizes. A 9x9 size sudoku is assumed.
class sudoku;
parameter ROWS =9;
parameter COLS =9;
//mat is the final sudoku 9X9 matrix
rand int mat[ROWS][COLS];
//trans_mat is the transpose of the final sudoku
rand int trans_mat[COLS][ROWS];
// boxes has 9 rows. Each row has the elements of the 3X3 grid in sudoku
// that have unique numbers
rand int boxes[COLS][ROWS];
constraint sudoku {
//make the numbers in the 3X3 grid unique
foreach(boxes[i])
unique {boxes[i]};
//This effectively makes the cols in the sudoku unique
foreach( trans_mat[i]) {
unique {trans_mat[i]};
}
//make the rows in the sudoku unique
foreach( mat[i]) {
unique {mat[i]};
}
//This is essentially saying that the 3X3 boxes are rows in boxes array
foreach(mat[i,j]) {
boxes[(3*(i/3)) + (j/3)][(3*(i%3))+(j%3)] == mat[i][j];
}
//Constrain for the numbers to be used in the sudoku
foreach(mat[i,j]) {
mat[i][j] >0;
mat[i][j] <=9;
}
//Constrain for mat and trans_mat to be transpose of each other
foreach(mat[k,j]) {
mat[k][j] == trans_mat[j][k];
}
}
//Display each element of matrix
function string display_elem(int k);
return($psprintf("%0d",k));
endfunction:display_elem
//Display each row matrix
function string display_row(input int row[COLS]);
string disp_string;
foreach(row[i])
begin
disp_string = {disp_string, "\t", display_elem(row[i])};
end
return disp_string;
endfunction:display_row
//Display each matrix
function display_mat(ref int mat[ROWS][COLS]);
foreach(mat[i])
begin
$display(display_row(mat[i]));
end
$display("=====================================");
endfunction:display_mat
//Display all matrices for debug
function display_all_mats();
display_sudoku();
display_mat(trans_mat);
display_mat(boxes);
endfunction:display_all_mats
function display_sudoku();
display_mat(mat);
endfunction:display_sudoku
endclass
module sudoku_tb();
sudoku sudoku_h;
initial
begin
sudoku_h = new();
sudoku_h.randomize();
sudoku_h.display_sudoku();
sudoku_h.randomize();
sudoku_h.display_sudoku();
end
endmodule
@puttasatish: Shouldn’t the “if” condition in your constraint for unique elements in each 3*3 sub-matrix needs to be fixed like below?
constraint c4{foreach(item[i,j]) // this constraint is for getting unique elements in each matrix of 3 * 3
foreach(item[k,l])
//if((i/3 == k/3)&&(j/3 == l/3)&&(i!=k)&&(j!=l))
if((i/3 == k/3)&&(j/3 == l/3)&& !(i==k && j==l))
item[i][j]!=item[k][l];}