I had a square matrix typed dynamically, correctly allocated
double **matrix;
I want to delete a "x" row and "x" column from that matrix, in a way like that:
SOURCE MATRIX:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
I want to remove, for example, the 2nd row/column. The output had to be like this:
FINAL MATRIX:
1 3 4
9 11 12
13 15 16
I've tried to write down and test many algorithms, without success.
How can I do?
Well, to do this, you'll have to realise that in memory your matrix is actually a list of lists.
This means that removing a column is slightly different from removing a row:
Assuming your syntax is matrix[row][column];
void removeColumn(int** matrix, int col){
MATRIX_WIDTH--;
//TODO check for empty matrix etc;
for(int i=0;i<MATRIX_HEIGHT; i++)
{
while(col<MATRIX_WIDTH)
{
//move data to the left
matrix[i][col]=matrix[i][col+1];
col++;
}
matrix[i] = realloc(matrix[i], sizeof(double)*MATRIX_WIDHT);
}
void removeRow(int** matrix, int row){
MATRIX_HEIGHT--;
//TODO check for empty matrix etc.
free(matrix[row]);
while(row<MATRIX_HEIGHT)
{
//move data up
matrix[row] = matrix[row+1];
row++;
}
}
so removeColumn iterates over each row, and deletes the appropriate item, and removeRow can just free the row, and overwrite its pointer.
NOTE that you have to keep track of the size of the matrix size yourself. In the example i used MATRIX_WIDTH and MATRIX_HEIGHT but you'll have to implement something for this. (Maybe a struct with width height and pointer in it.)
As I was looking for a answer to the similar problem but with matrix stored in linear space here's my solution (I'm using column-major order here, but if you're using row-major it only minor changes are needed)
void removeRow(float * arrayToRemove, const int & currentRows, const int & currentCols, const int & row)
{
auto currDiff = 0;
auto step = currentRows;
auto elemNum = currentRows * currentCols;
for (int i = row, stepCounter = 0; i < elemNum; ++i, ++stepCounter)
{
if (stepCounter % step == 0)
{
++currDiff;
}
else
{
arrayToRemove[i - currDiff] = arrayToRemove[i];
}
}
}
void removeCol(float * arrayToRemove, const int & currentRows, const int & currentCols, const int & col)
{
auto destination = arrayToRemove + (col * currentRows);
auto source = arrayToRemove + ((col + 1) * currentRows);
const auto elemsNum = (currentCols - (col + 1)) * currentRows;
memcpy(destination, source, elemsNum * sizeof(float));
}
What I would do is split this matrix into 5 zones.
1) zone to be deleted. 2) Zone "before" the deleted index (it would be just 1 in your example matrix). 3) Zone "after" the deleted index (it would be 11,12,15,16 in your matrix). 4) and 5) Are the two remaining 'zones'. One would be (3, 4) the other would (9,13)
Just make a conditional for each of the 5 zones and copy.
double** matrix = (double**)malloc(sizeof(double)*n*n);
//fill in the matrix here
double** copy (double**)malloc(sizeof(double)*(n-1)*(n-1));
int i;
int j;
int deleteNum; //what ever row you want to delete
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
if(i < deleteNum && j < deleteNum){
copy[i][j] = matrix[i][j];
}
else if(deleteNum == i || deleteNum == j){
//one of the rows/columns to be deletd
//basically skip
}
else if(i < deleteNum && j > deleteNum){
copy[i][j-1] = matrix[i][j];
}
else if(i > deleteNum && j < deleteNum){
copy[i-1][j] = matrix[i][j]
}
else{
copy[i-1][j-1] = matrix[i][j];
}
}
}
Related
I got an assignment to write a program that fills an empty sudoku board and prints it out.
The tools that we have are only functions, arrays and pointers. No recursion, no search and sort algorithms to improve the time complexity.
So far I thought to use two dimension array for the board and go over every row in a nested "for" loop.
Every time I fetch a number with a random function and check a row, a column and a square (3X3), and if all of them pass then I fill the number.
My problem is that, that way it takes the code a very long time to solve, and I don't know if I'm doing it right. I didn't see a solution of my code yet, even after leaving it to run more than 5 minutes. I thought maybe somehow to use a histogram of numbers from 1-9 that maps which numbers already used to somehow change the use of fetching random numbers, but I'm not really sure how to use it and if it's even right to do so. Basically I'm stuck.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MATRIX_SIZE 9
#define MAX_NUM 9
void solve_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE]);
void print_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE]);
int rowCheck(int num, int board[][MATRIX_SIZE], int row);
int columnCheck(int num, int board[][MATRIX_SIZE], int row);
int squareCheck(int num, int board[][MATRIX_SIZE], int row, int col);
int giveNum(void);
void main()
{
srand(time(NULL));
int board[MATRIX_SIZE][MATRIX_SIZE];
/*{
0,0,0,0,0,4,0,0,0,
0,6,8,0,0,0,5,0,0,
0,2,0,0,0,0,0,7,6,
6,0,0,0,0,0,8,9,0,
0,0,5,2,6,0,0,0,0,
0,0,0,9,0,0,1,0,0,
0,0,0,0,0,7,0,5,0,
0,4,0,0,0,0,0,0,1,
0,0,0,0,5,1,4,0,0
};*/
for (int row = 0; row < MATRIX_SIZE; row++)
for (int col = 0; col < MATRIX_SIZE; col++)
board[row][col] = -1;
solve_sudoku(board);
print_sudoku(board);
}
void solve_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE])
{
int rowCh, colCh, sqrCh, num, square = 0;
for (int row = 0; row < MATRIX_SIZE; row++)
{
for (int col = 0; col < MATRIX_SIZE; col++)
{
if (square > 2)
square = 0;
while(1)
{
num = giveNum();
rowCh = rowCheck(num, board, row, col);
if (!rowCh)
continue;
colCh = columnCheck(num, board, row, col);
if (!colCh)
continue;
sqrCh = squareCheck(num, board, row, col-square);
if (!sqrCh)
continue;
break;
} //while (!rowCh || !colCh || !sqrCh);
square++;
board[row][col] = num;
}
}
}
void print_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE])
{
printf("Sudoku solution:\n");
for (int i = 0; i < MATRIX_SIZE; i++)
{
for (int j = 0; j < MATRIX_SIZE; j++)
printf("%d ", board[i][j]);
printf("\n");
}
}
int giveNum(void)
{
int num = rand() % MATRIX_SIZE + 1;
return num;
}
int rowCheck(int num, int board[][MATRIX_SIZE], int row)
{
for (int col = 0; col < MATRIX_SIZE; col++)
{
if (num == board[row][col])
return 0;
}
return 1;
}
int columnCheck(int num, int board[][MATRIX_SIZE], int col)
{
for (int row = 0; row < MATRIX_SIZE; row++)
{
if (num == board[row][col])
return 0;
}
return 1;
}
int squareCheck(int num, int board[][MATRIX_SIZE], int row, int col)
{
for (int i = row; i < row + sqrt(MATRIX_SIZE); i++)
for (int j = col; j < col + sqrt(MATRIX_SIZE); j++)
if (board[i][j] == num)
return 0;
return 1;
}
I strongly doubt that you will have much luck with a pure random approach. There are so many combinations so that chance of hitting a valid solution is very little. Instead you'll most likely end in a dead-lock where there is no valid number to put in current position... then you just have an endless loop.
Anyway... here is a bug:
For the squareCheck function to work, it's required that col and row identifies the upper-left corner. For col you ensure that using square but for row you don't.
In other words, your check isn't correct.
Instead of using "the square method" consider to put these lines in the start of the function:
row = row - (row % 3);
col = col - (col % 3);
There's a loop while(1) where you pick a random number and determine if it is valid in the current position.
It's quite possible to get to a dead end here.
You can have easily filled in numbers that while valid individually leave the puzzle insoluble.
You need some method of backtracking if you get 'stuck' or detecting that it will get stuck.
The 'common' approach is to hold a 9x9 matrix of sets holding a subset of 1-9 which are the untried values. When a value is set (at start) or tried (during solve) you check the constraints and remove the value being tried from its column, row and square.
Start with a 9x9 grid all cells initialised to the full range [1-9].
If you set a cell to (say) 5 remove 5 from all cells in that column, row and sub-square.
If that leaves any cell with the empty set, the puzzle is insoluble.
When solving only pick from the set of 'remaining possible values' rather than rand [1-9].
However it still may be that a trial makes the puzzle insoluble and needs to go back a cell (or more) to come forward again.
The easy way to do that would be recursion. But that's ruled out by the Exercise.
So it looks like some kind of Undo stack is required.
Here is a way to generate a random suduko.
// Check that no number 1..9 is present twice in a column
int colok(int s[][9])
{
for (int col=0; col<9; ++col)
{
for (int n=1; n<=9; ++n)
{
int cnt = 0;
for (int i=0; i<9; ++i)
{
if (s[i][col] == n)
{
if (cnt > 0) return 0;
cnt = 1;
}
}
}
}
return 1;
}
// Check that no number 1..9 is present twice in a 3x3 block
int blockok(int s[][9])
{
for (int row=0; row<9; row += 3)
{
for (int col=0; col<9; col +=3)
{
for (int n=1; n<=9; ++n)
{
int cnt = 0;
for (int i=0; i<3; ++i)
{
for (int j=0; j<3; ++j)
{
if (s[i + row][j + col] == n)
{
if (cnt > 0) return 0;
cnt = 1;
}
}
}
}
}
}
return 1;
}
void p(int s[][9])
{
for (int i=0; i<9; ++i)
{
for (int j=0; j<9; ++j)
{
printf("%d ", s[i][j]);
}
puts("");
}
}
#define MAX_LOOP 10000000
void makerow(int s[][9], int r)
{
int loops = 0;
while(1)
{
++loops;
// FY Shuffle row (this ensures that rows are always valid)
int a[] = {1,2,3,4,5,6,7,8,9};
int max = 8;
while(max)
{
int t = rand() % (max + 1);
int tmp = a[t];
a[t] = a[max];
a[max] = tmp;
--max;
}
// Save row
for (int i=0; i<9; ++i)
{
s[r][i] = a[i];
}
// Check whether it's valid
if (colok(s) && blockok(s))
{
// It's valid so stop here
break;
}
// Stop if too many loops
if (loops > MAX_LOOP)
{
puts("I'm so tired...");
exit(1);
}
}
printf("loops %d\n", loops);
}
int main(void)
{
srand((int)time(0));
int s[9][9] = { 0 };
for (int i=0; i<9; ++i)
{
printf("Make row %d\n", i);
makerow(s, i);
}
p(s);
return 0;
}
Possible output:
Make row 0
loops 1
Make row 1
loops 27
Make row 2
loops 1090
Make row 3
loops 3
Make row 4
loops 1019
Make row 5
loops 5521
Make row 6
loops 96
Make row 7
loops 66727
Make row 8
loops 498687
7 5 2 4 6 8 3 1 9
3 4 6 9 1 7 8 2 5
8 1 9 3 2 5 7 6 4
9 6 3 8 7 4 2 5 1
1 8 5 2 9 3 6 4 7
2 7 4 1 5 6 9 8 3
6 9 7 5 4 2 1 3 8
5 2 8 7 3 1 4 9 6
4 3 1 6 8 9 5 7 2
But notice... it happens that no solution can be generated.. then the output is:
Make row 0
loops 1
Make row 1
loops 37
Make row 2
loops 2957
Make row 3
loops 16
Make row 4
loops 2253
Make row 5
I'm so tired...
In order to avoid recursion you can try to navigate the solution space by levels. That requires a Queue, in which you add the next possible states from a given one (just extracted from the queue) and you mark the already visited ones (e.g. with the selected numbers) In this way you only build a single loop (no nested loops required) and you can generate all the possible solutions (but you can stop at the first that just generates a valid position)
Thanks for all of your responses. There is an update: I found a bug that made me a lot of problems, The bug was that I defined : columnCheck function that receives variable row and I called the function this way: " columnCheck(num, board, row, col); ", so the bug is that in the definition I need to give only 3 arguments, when I called the function accidently with 4 and also gave the columCheck the row instead the column. Also rowCheck was called with 4 arguments instead of 3 as defined. Can someone explain why the debugger didn't warn me about that ?
Also I changed the giveNum() function to this one:
int giveNum(void)
{
int static num = 1;
if (num > 9)
num = 1;
return num++;
}
Now it's not random but it fills the sudoku.
Since a lot of people asked the instructor how to do it, he replied that this kind of solution will be fine for now, However I will take the challenge to solve it with your suggestions.
I am trying to compare the speedup of NxN matrix multiplication by using the classical naive way vs. using compressed row storage. The values in the matrix are binary, either 0 or 1.
In the classical matrix multiplication, multiplying the matrix by itself is straightforward given as:
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
for (k = 0; k < N; k++) {
product[i][j] += mat[i][k]*mat[k][j];
}
}
}
In the compressed row storage format, I am required to store the matrix in an array, col_idx, which stores all the column indices of the non-zero values. I also need a row pointer, which encodes the index in col_idx where the given row starts.
For example if we multiply the following matrix by itself, we have the product:
Matrix Mult
The column index and row pointer in the given matrix will then have the array values:
col_idx = [1,2,2,3,0,3,1]
row_ptr = [0,2,4,6,7]
To get the column indices of one row, say the very first row, I simply have to code in:
for (i = row_ptr[0]; i < row_ptr[1]; i++) {
printf("%d\n",col_idx[i]);
}
I want to have the same product as in the classical matrix multiplication for the CRS-algorithm, but in a 1D-array that only stores the non-zero values, which in this example would be:
product1D = [1,1,2,1,1,2,2,1,1,1]
I've tried to get all rows at the same time, but I'm stuck on what I should do forward. Any tips?
The implementation in https://www.geeksforgeeks.org/operations-sparse-matrices/ (C++) is good :
void multiply(sparse_matrix b)
{
if (col != b.row)
{
// Invalid multiplication
cout << "Can't multiply, Invalid dimensions";
return;
}
// transpose b to compare row
// and col values and to add them at the end
b = b.transpose();
int apos, bpos;
// result matrix of dimension row X b.col
// however b has been transposed,
// hence row X b.row
sparse_matrix result(row, b.row);
// iterate over all elements of A
for (apos = 0; apos < len;)
{
// current row of result matrix
int r = data[apos][0];
// iterate over all elements of B
for (bpos = 0; bpos < b.len;)
{
// current column of result matrix
// data[,0] used as b is transposed
int c = b.data[bpos][0];
// temporary pointers created to add all
// multiplied values to obtain current
// element of result matrix
int tempa = apos;
int tempb = bpos;
int sum = 0;
// iterate over all elements with
// same row and col value
// to calculate result[r]
while (tempa < len && data[tempa][0] == r &&
tempb < b.len && b.data[tempb][0] == c)
{
if (data[tempa][1] < b.data[tempb][1])
// skip a
tempa++;
else if (data[tempa][1] > b.data[tempb][1])
// skip b
tempb++;
else
// same col, so multiply and increment
sum += data[tempa++][2] *
b.data[tempb++][2];
}
// insert sum obtained in result[r]
// if its not equal to 0
if (sum != 0)
result.insert(r, c, sum);
while (bpos < b.len &&
b.data[bpos][0] == c)
// jump to next column
bpos++;
}
while (apos < len && data[apos][0] == r)
// jump to next row
apos++;
}
result.print();
}
The C++ constructor of a sparse matrix is defined in this like
sparse_matrix(int r, int c)
{
// initialize row
row = r;
// initialize col
col = c;
// initialize length to 0
len = 0;
//Array of Pointer to make a matrix
data = new int *[MAX];
// Array representation
// of sparse matrix
//[,0] represents row
//[,1] represents col
//[,2] represents value
for (int i = 0; i < MAX; i++)
data[i] = new int[3];
}
with int** data
In https://codingee.com/c-programs/c-program-for-multiplication-of-two-sparse-matrices/ is C code
I am successfully storing the calculated subsets in a 2-D array matrix in C language.Now I want to print the subsets in an order desired.
For eg.
2-D array matrix is
10 7 3 2 1
10 7 5 1
7 6 5 3 2
10 6 5 2
10 7 6
Desired Output
10 7 6
10 7 5 1
10 7 3 2 1
10 6 5 2
7 6 5 3 2
How quick sort can be applied to sort/order these rows?
As #chqrlie noted, this can be easily solved with qsort.
Depending on the way the matrix is declared (is it an array of pointers to arrays of ints? do all arrays have the same length? is it a global array of fixed size?) the code will have to do slightly different things.
So, assuming the array is a global variable and all rows have same length (padded with 0s):
MWE:
#include <stdio.h>
#include <stdlib.h>
/*
Compare 2 integers
returns:
-1 if *i1 < *i2
+1 if *i1 > *i2
0 if *i1 == *i2
*/
int intcmp(const int *i1, const int *i2)
{
return (*i2 < *i1) - (*i1 < *i2);
}
#define ROWS 5
#define COLS 5
/*
Assumes rows already sorted in descending order
NOTE: qsort calls the comparison function with pointers to elements
so this function has to be tweaked in case the matrix is an array of
pointers. In that case the function's declaration would be:
int rowcmp(int **pr1, int **pr2)
{
const int *r1 = *pr1;
const int *r2 = *pr2;
// the rest is the same
}
*/
int rowcmp(const int *r1, const int *r2)
{
int i = 0, cmp;
do {
cmp = intcmp(&r1[i], &r2[i]);
i++;
} while (i < COLS && cmp == 0);
return -cmp; /* return -cmp to sort in descending order */
}
int data[5][5] = {
{10,7,3,2,1},
{10,7,5,1,0},
{ 7,6,5,3,2},
{10,6,5,2,0},
{10,7,6,0,0}
};
void printmatrix()
{
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", data[i][j]); /* leaves a trailing space in each row */
}
printf("\n");
}
}
int main()
{
printmatrix();
qsort(data, 5, sizeof(data[0]), (int (*)(const void *, const void *))rowcmp);
printf("\n");
printmatrix();
return 0;
}
For the most flexible solution, I would define
struct row {
size_t len;
int *elems;
};
struct matrix {
struct row *rows;
size_t nrows;
};
and change the code accordingly.
NOTE: code not thoroughly tested, use with caution ;)
First of all, are you sure that the 1 on row 3,col 5 should be there and not on the last line?
Anyway, an efficient way to achieve what you want is:
compute the frequency array
declare a new matrix
go from the highest element (10 in your case) from frequency array and put in your matrix using your desired format.
It is time-efficient because you don't use any sorting algorithm, thus you don't waste time there.
It is NOT space-efficient because you use 2 matrices and 1 array, instead of only 1 matrix as suggested in other posts, but this should not be a problem, unless you use matrices of millions of rows and columns
C code for frequency array:
int freq[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(MATRIX[i][j]!=null && MATRIX[i][j]>0 && MATRIX[i][j]<11) {
freq[MATRIX[i][j]]++;
}
}
}
C code for computing the new matrix dimensions
(assuming you want to keep the number of rows)
OUTPUT_MATRIX[100][100] /*I declared it statically, but I would advise to make it dinamically */
/* first, compute the number columns.
To do so, we need the number of elements
(we get them by simply summing up frequency array's elements) */
int s=0;
for(int i=0; i<11; i++) {
s+=frequency[i];
}
int addOne = 0 /* boolean value to check if we will have to add one extra column for safety */
if(s % NO_ROWS) {
addOne = 1; /* division is not even, so we will have to add extra column */
}
NO_COLS = s/NO_ROWS + addOne;
Now, final part, assigning the values from frequency array to the OUTPUT_MATRIX
int k=0;
int currentNumber = 10; /* assigning starts from 10 */
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(currentNumber>0) {
if(frequency[currentNumber]==0 || k>=frequency[currentNumber]) {
currentNumber--;
k=0;
}
OUTPUT_MATRIX[i][j] = frequency[currentNumber];
k++;
} else {/*here, you can assign the rest of the value with whatever you want
I will just put 0's */
OUTPUTMATRIX[i][j] = 0;
}
}
}
Hope this helps!
This is what I do in C++ to reorder a matrix:
// b is the matrix and p is an array of integer containing the desired order of rows
for(i=0; i<n; i++){
if( p[i]==i )
continue;
b[i].swap(b[p[i]]);
j = p[i]; // New row i position
// Update row i position to new one
for(int k=i+1; k<n; k++){
if( p[k] == i )
p[k] = j;
}
printRow( b[i] );
}
You need to define an array of pointers of the data type you use and then you can reorder your matrix.
for example your matrix is: arr[5][10], and you want to print line 4 before line 3:
int *[5] arr2;
arr2[0] = &arr[0][0];
arr2[1] = &arr[1][0];
arr2[2] = &arr[2][0];
arr2[3] = &arr[4][0];
arr2[4] = &arr[3][0];
in regard to how will the ordering algorithm work, i would suggest placing a header in the start of each array in the matrix which will tell you how many elements it has(basically the first element of each array can be a counter of the total elements) afterwards you can order the strings by comparing the header, and if it is equal comparing the first element and so on. this can be done in a loop that iterates as many times as there are elements in the array, when the elements are not equal, break out of the loop.
hope this helps.
Alright so I thought my code was working and it seems to do so, it allows the user to choose the size of a magic square where the number one is the start point and starts in the center of the first row. The pattern goes along this line....go up one and over one, if you go up above the first row.....move back to the last row or if you run off the end of the right side of the column than go back to the start of the column...in a magic square if your not familiar with it, all sides are equal when the numbers on that side or diagonal are counted.
An odd number must be entered for this to be written out as a magic square (example: 3x3, 5x5, 7x7, etc..) the problem is it works until I enter 11x11....when done, it comes back around and when the program runs into a slot that has already been filled it is supposed to enter the next number below the last one that was entered into the array...but when 11x11 is entered it overwrites the 1 with a 13 which breaks the cycle and ruins the pattern....I would appreciate it if someone helped me with this, I think maybe the problem has to do with the equation I use to choose the starting point. This works all the way up to 11x11, every odd number entered after that seems to overwrite the starting point.
// Chapter 8 Programming Project #17
#include <stdio.h>
#define N_squared (N * N)
#define MOVE (--row, ++column)
#define RW_SIZE ((int) (sizeof(magic_square) / sizeof(magic_square[0])))
void create_magic_square(int N, int magic_square[N][N], int ROW_SIZE);
void print_magic_square(int N, int magic_square[N][N], int ROW_SIZE);
int main(void)
{
int N, row, column;
printf("This program creates a magic square of a specified size\n");
printf("The size must be an odd number between 1 and 99.\n");
printf("Enter size of magic square: ");
scanf("%d", &N);
int magic_square[N][N];
for (row = 0; row < N; row++) {
for (column = 0; column < N; column++) {
magic_square[row][column] = 0;
}
}
// Create magic square
create_magic_square(N, magic_square, RW_SIZE);
// Print magic square
print_magic_square(N, magic_square, RW_SIZE);
return 0;
}
void create_magic_square(int N, int magic_square[N][N], int ROW_SIZE)
{
printf("Size of N*N = %d\nSize of ROW_SIZE = %d\n", N_squared, ROW_SIZE);
// Here I iterate through the numbers, rows, and columns
int i = 1, row = 0;
int column = (((ROW_SIZE + 1) / 2) - 1);
while (i != N_squared + 1){
// if new position is empty place next number
if (magic_square[row][column] == 0) {
magic_square[row][column] = i;
i++;
// If new position is filled then move back and down
} else if (row + 2 < ROW_SIZE &&
column - 1 >= 0) {
row += 2;
column -= 1;
} else if (row + 2 > ROW_SIZE - 1 &&
column - 1 < 0) {
row = 1;
column = ROW_SIZE - 1;
}
// If current position has been set then move
if (magic_square[row][column] != 0)
MOVE;
// If row runs off the board reset
if (row < 0)
row = ROW_SIZE - 1;
// if column runs off the board reset
if (column > ROW_SIZE - 1)
column = 0;
}
}
void print_magic_square(int N, int magic_square[N][N], int ROW_SIZE)
{
int row, column;
printf("\n");
for (row = 0; row < ROW_SIZE; row++) {
for (column = 0; column < ROW_SIZE; column++) {
if (N > 9)
printf(" %3d ", magic_square[row][column]);
else
printf(" %2d ", magic_square[row][column]);
}
printf("\n\n");
}
}
I have worked for a sudoku puzzle in C but I'm stuck in one problem: Checking every 3x3 grid for not having duplicate values.
Here is my code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int v[10][10];
//Matrix start from 1 and end with 9
//So everywhere it should be i=1;i<=9 not from 0 to i<9 !!!
//Display function ( Display the results when it have)
void afisare()
{
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++)
printf("%2d",v[i][j]);
printf("\n");
}
printf("\n");
}
//Function to check the valability of value
int valid(int k, int ii, int jj)
{
int i;
//Check for Row/Column duplicate
for(i = 1; i <= 9; ++i) {
if (i != ii && v[i][jj] == k)
return 0;
if (i != jj && v[ii][i] == k)
return 0;
}
//Returns 0 if duplicate found return 1 if no duplicate found.
return 1;
}
void bt()
{
int i,j,k,ok=0;
//Backtracking function recursive
for(i=1;i<=9;i++){
for(j=1;j<=9;j++)
if(v[i][j]==0)
{
ok=1;
break;
}
if(ok)
break;
}
if(!ok)
{
afisare();
return;
}
for(k=1;k<=9;k++)
if(valid(k,i,j))
{
v[i][j]=k;
bt();
}
v[i][j]=0;
}
int main()
{
//Reading from the file the Matrix blank boxes with 0
int i,j;
freopen("sudoku.in","r",stdin);
for(i=1;i<=9;i++)
for(j=1;j<=9;j++)
scanf("%d",&v[i][j]);
bt();
system("pause");
return 0;
}
I know in function Valid I should have the condition to check every 3x3 grid but I don't figure it out: I found those solution to create some variables start and end
and every variable get something like this:
start = i/3*3;
finnish = j/3*3;
i and j in my case are ii and jj.
For example found something like this:
for (int row = (i / 3) * 3; row < (i / 3) * 3 + 3; row++)
for (int col = (j / 3) * 3; col < (j / 3) * 3 + 3; col++)
if (row != i && col != j && grid[row][col] == grid[i][j])
return false;
I tryed this code and it doesn't work.
I don't understand this: I have the next matrix for sudoku:
1-1 1-2 1-3 1-4 1-5 1-6
2-1 2-2 2-3 2-4 2-5 2-6
3-1 3-2 3-3 3-4 3-5 3-6
If my code put's a value on 3-2 how he check in his grid for duplicate value, that formula may work for 1-1 or 3-3 but for middle values doesn't work, understand ?
If my program get's to 2-5 matrix value It should check if this value is duplicate with 1-4 1-5 1-6 2-4 2-6 ... untill 3-6.
Since you are using index arrays starting with 1 and not zero, you have to correct for that when calculating the sub-grid indexes.
start = (i - 1) / 3 * 3 + 1;
finish = (j - 1) / 3 * 3 + 1;