segmentation fault while freeing pointer - c++

class matrix
{
public:
int nrow;
int ncol;
double **m;
matrix(int r, int c)
{
nrow = r; ncol = c;
m = (double**)malloc(nrow*sizeof(double*));
for(int i=0; i<nrow; i++)
m[i] = (double*)malloc(ncol*sizeof(double));
for(int i=0; i<nrow; i++)
for(int j=0; j<ncol; j++)
m[i][j] = 0;
}
~matrix()
{
for(int i=0; i<nrow; i++)
{
printf("destructor loop: %d\n", i); fflush(stdout);
free(m[i]);
}
free(m);
}
matrix(const matrix& that)
{
this->nrow = that.nrow;
this->ncol = that.ncol;
this->m = (double**)malloc(nrow*sizeof(double*)); // dynamic mem allocation
for(int i=0; i<this->nrow; i++)
m[i] = (double*)malloc(ncol*sizeof(double));
for(int i=0; i<that.nrow; i++)
for(int j=0; j<that.ncol; j++)
this->m[i][j] = that.m[i][j];
}
void operator=(const matrix &that)
{
this->nrow = that.nrow;
this->ncol = that.ncol;
for(int i=0; i<nrow; i++) // clear current m
free(m[i]);
free(m);
this->m = (double**)malloc(nrow*sizeof(double*)); // dynamic mem allocation
for(int i=0; i<this->nrow; i++)
m[i] = (double*)malloc(ncol*sizeof(double));
for(int i=0; i<that.nrow; i++)
for(int j=0; j<that.ncol; j++)
this->m[i][j] = that.m[i][j];
}
void show()
{
printf(" Marix:\n");
for(int i=0; i<nrow; i++)
{
printf(" ");
for(int j=0; j<ncol; j++)
{
if(m[i][j] >= 0) printf(" ");
printf("%.6lf ", m[i][j]);
}
printf("\n");
}
printf("\n");
}
matrix cofactor(int r, int c) // returns cofactor of a[r][c]
{
printf("cofactor: size:(%d, %d) element:(%d, %d)\n", nrow, ncol, r, c); fflush(stdout);
matrix ans(nrow-1, ncol-1);
int x = 0, y = 0;
for(int i=0; i<nrow; i++)
{
if(i == r) continue;
for(int j=0; j<ncol; j++)
{
if(j == c) continue;
ans.m[x][y] = m[i][j];
y++;
}
x++;
}
return ans;
}
double det()
{
if(nrow != ncol)
{
printf("non-square matrix: (%d, %d)\n\n", nrow, ncol);
exit(1);
}
if(nrow == 1) return m[0][0];
if(nrow == 2)
{
double ans = m[0][0]*m[1][1] - m[1][0]*m[0][1];
return ans;
}
double ans = 0;
int sign = 1;
for(int i=0; i<nrow; i++)
{
printf("det[size:%d, %d] loop row: %d\n", nrow, ncol, i); fflush(stdout);
matrix a(2, 2);
a = cofactor(i, 0);
ans += (sign*a.det());
sign = sign*(-1);
}
return ans;
}
};
int main()
{
matrix c(3, 3);
c.m[0][0] = 2; c.m[0][1] = -3; c.m[0][2] = 1;
c.m[1][0] = 2; c.m[1][1] = 0; c.m[1][2] = -3;
c.m[2][0] = 1; c.m[2][1] = 4; c.m[2][2] = 5;
c.show();
printf("determinant: %lf\n", c.det());
return 0;
}
A segmentation fault occurs when calling the det function for even 3x3 matrices.
i do not have experience with sophisticated debuggers but using printf statements it looks like the runtime error occurs during an iteration of the loop in the destructor. also i have tried using vector< vector< double >> instead of double**. i assumed it would not need a destructor in that case. then it is giving me a "double free error". i understand when it occurs but cannot find the error in my code. i have also tried calculating the cofactor inline instead of calling a function but it does not help.

int x = 0, y = 0;
for(int i=0; i<nrow; i++)
{
if(i == r) continue;
for(int j=0; j<ncol; j++)
{
if(j == c) continue;
ans.m[x][y] = m[i][j];
y++;
}
x++;
}
The logic for incrementing y is broken here. Perform a simple mental experiment. If the original matrixes are 3x3, and they are being reduced here to a 2x2 matrix, your ans, then you expect each value in ans to be initialized here, and
ans.m[x][y] = m[i][j];
y++;
will get executed four times. Since y is initially set to 0 and never gets reset to 0, the value of y used in this assignment will range from 0 to 3, so, at some point, this will attempt to assign something to ans.m[x][3], which, of course, doesn't exist, and hillarity ensues.
It seems that the obvious intent here is to reset
y=0;
As the very first order of business in the outer for loop, instead of just once, at the very beginning.

The problem is in the cofactor function. You have declared int x = 0, y = 0 outside of the loops. In the case of x (the row of the cofactor matrix, ans) its fine. But we want the y to be 0 everytime we start with a new row, i.e. y should be in sync with j, skipping when j==c.
What is happening is you skip row 0, since i==r, then in the next row (i=1), you iterate over the columns, skip col 0, since j==c, then go over col 1, col 2, so the code that got executed was
ans.m[0][0] = m[1][1], y++,
ans.m[0][1] = m.[1][2], y++, then we are done with the columns.
We increment x (x=1 now), we go to the next row, row 2 (i=2), but y=2, and not reset. So the next row executes this code:
ans.m[1][2] = m[2][1] (skipping col 0),
which is out of bounds for ans, since ans has ncols-1 = 2 columns.
This results in an error when the destructor for ans is called at the end of cofactor function. I fixed the cofactor code, and this results in no errors when calling det for 3*3 matrices.
matrix cofactor(int r, int c) // returns cofactor of a[r][c]
{
printf("cofactor: size:(%d, %d) element:(%d, %d)\n", nrow, ncol, r, c); fflush(stdout);
matrix ans(nrow-1, ncol-1);
int x = 0;
for(int i=0; i<nrow; i++)
{
if(i == r) continue;
int y = 0;
for(int j=0; j<ncol; j++)
{
if(j == c) continue;
ans.m[x][y] = m[i][j];
y++;
}
x++;
}
return ans;
}
To debug, I would recommend gdb. You can use onlinegdb.com paste your code there, click debug. Then set breakpoints by break <line_number>, then run, n for next instruction, s for step into function. You can search to find out more.

Related

Pascal triangle matrix using vectors in C++

I need make Pascal Triangle matrix using vectors and then print it.
This algorithm would work with arrays, but somehow it doesn't work with matrix using vectors.
#include <iomanip>
#include <iostream>
#include <vector>
typedef std::vector<std::vector<int>> Matrix;
int NumberOfRows(Matrix m) { return m.size(); }
int NumberOfColumns(Matrix m) {
if (m.size() != 0)
return m[0].size();
return 0;
}
Matrix PascalTriangle(int n) {
Matrix mat;
int a;
for (int i = 1; i <= n; i++) {
a = 1;
for (int j = 1; j <= i; j++) {
if (j == 1)
mat.push_back(j);
else
mat.push_back(a);
a = a * (i - j) / j;
}
}
return mat;
}
void PrintMatrix(Matrix m, int width) {
for (int i = 0; i < NumberOfRows(m); i++) {
for (int j = 0; j < NumberOfColumns(m); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
int main() {
Matrix m = PascalTriangle(7);
PrintMatrix(m, 10);
return 0;
}
I get nothing on screen, and here's the same code just without matrix using vectors program (which works fine).
Could you help me fix this code?
The main problem is that in PascalTriangle, you are starting out with an empty Matrix in both the number of rows and columns.
Since my comments mentioned push_back, here is the way to use it if you did not initialize the Matrix with the number of elements that are passed in.
The other issue is that NumberOfColumns should specify the row, not just the matrix vector.
The final issue is that you should be passing the Matrix by const reference, not by value.
Addressing all of these issues, results in this:
Matrix PascalTriangle(int n)
{
Matrix mat;
for (int i = 0; i < n; i++)
{
mat.push_back({}); // creates a new empty row
std::vector<int>& newRow = mat.back(); // get reference to this row
int a = 1;
for (int j = 0; j < i + 1; j++)
{
if (j == 0)
newRow.push_back(1);
else
newRow.push_back(a);
a = a * (i - j) / (j + 1);
}
}
return mat;
}
And then in NumberOfColumns:
int NumberOfColumns(const Matrix& m, int row)
{
if (!m.empty())
return m[row].size();
return 0;
}
And then, NumberOfRows:
int NumberOfRows(const Matrix& m) { return m.size(); }
And last, PrintMatrix:
void PrintMatrix(const Matrix& m, int width)
{
for (int i = 0; i < NumberOfRows(m); i++)
{
for (int j = 0; j < NumberOfColumns(m, i); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
Here is a live demo
Your code won't compile because you have numerous errors in PascalTriangle.
For one, you initialize a matrix with no elements. Additionally, you use matrix indices starting at 1 rather than 0.
The following prints things for me:
Matrix PascalTriangle(int n) {
Matrix mat(n, std::vector<int>(n, 0)); // Construct Matrix Properly
int a;
for (int i = 0; i < n; i++) { // Start index at 0
a = 1;
for (int j = 0; j < i + 1; j++) { // Start index at 0
if (j == 0) // Changed 1 to 0
mat[i][j] = 1;
else
mat[i][j] = a;
a = a * (i - j) / (j+1); // Changed j to j+1 since j starts at 0
}
}
return mat;
}

How to raise a zero-one matrix to any power in C++?

I made a zero-one matrix with power 2. However, I want the code to be applied to any power the user enters. I tried several times, but it didn't work.
Here's a part of the code that would concern you.
Notes: Suppose the user has entered his (n*m) matrix which is "a", as n and m are equals and they are denoted by s.
k=0;
for(int j=0; j<s; j++)
for(int i=0; i<s; i++)
{
m[k]=0;
for(int t=0; t<s; t++)
m[k]+=a[j][t]*a[t][i];
k++;
}
Here is my implementation for matrix exponentiation:
struct matrix {
intt m[K][K];
matrix() {
memset (m, 0, sizeof (m));
}
matrix operator * (matrix b) {
matrix c = matrix();
for (intt i = 0; i < K; i++) {
for (intt k = 0; k < K; k++) {
for (intt j = 0; j < K; j++) {
c.m[i][j] = (c.m[i][j] + m[i][k] * b.m[k][j]) % MOD;
}
}
}
return c;
}
matrix pow (intt n) {
if (n <= 0) {
return matrix();
}
if (n == 1) {
return *this;
}
if (n % 2 == 1) {
return (*this) * pow (n - 1);
} else {
matrix X = pow (n / 2);
return X * X;
}
}
};

C++ PCA - Calculating covariance MATRIX

I'm trying to calculate the Covariance (matrix) of a vector in C++ ...
I have carried out the following:
std::vector<std::vector<double> > data = { {2.5, 2.4}, {0.5, 0.7} };
I have then calculated and subtracted the mean, which gave the following result:
data = { {0.05, -0.05}, {-0.1, 0.1} }
As far as I'm aware, the next step is to transpose the matrix, and multiply the origin together, take the sum and finally divide by the dimensions X - 1..
I have written the following:
void cover(std::vector<std::vector<double> > &d)
{
double cov = 0.0;
for(unsigned i=0; (i < d.size()); i++)
{
for(unsigned j=0; (j < d[i].size()); j++)
{
cov += d[i][j] * d[j][i] / (d[i].size() - 1);
std::cout << cov << " ";
}
std::cout << std::endl;
}
}
Where d is the vector after the mean has been subtracted from each of the points
Which gives me the result:
0.0025, 0.0075
0.0125, 0.0225
Where compared with matlab:
2.0000 1.7000
1.7000 1.4450
Does anyone have any ideas to where I am going wrong?
Thanks
This statement:
As far as I'm aware, the next step is to transpose the matrix, and multiply the origin together, take the sum and finally divide by the dimensions X - 1..
And this implementation:
cov += d[i][j] * d[j][i] / (d[i].size() - 1);
Don't say the same thing. Based on the definition here:
void outer_product(vector<double> row, vector<double> col, vector<vector<double>>& dst) {
for(unsigned i = 0; i < row.size(); i++) {
for(unsigned j = 0; j < col.size(); i++) {
dst[i][j] = row[i] * col[j];
}
}
}
//computes row[i] - val for all i;
void subtract(vector<double> row, double val, vector<double>& dst) {
for(unsigned i = 0; i < row.size(); i++) {
dst[i] = row[i] - val;
}
}
//computes m[i][j] + m2[i][j]
void add(vector<vector<double>> m, vector<vector<double>> m2, vector<vector<double>>& dst) {
for(unsigned i = 0; i < m.size(); i++) {
for(unsigned j = 0; j < m[i].size(); j++) {
dst[i][j] = m[i][j] + m2[i][j];
}
}
}
double mean(std::vector<double> &data) {
double mean = 0.0;
for(unsigned i=0; (i < data.size());i++) {
mean += data[i];
}
mean /= data.size();
return mean;
}
void scale(vector<vector<double>> & d, double alpha) {
for(unsigned i = 0; i < d.size(); i++) {
for(unsigned j = 0; j < d[i].size(); j++) {
d[i][j] *= alpha;
}
}
}
So, given these definitions, we can compute the value for the covariance matrix.
void compute_covariance_matrix(vector<vector<double>> & d, vector<vector<double>> & dst) {
for(unsigned i = 0; i < d.size(); i++) {
double y_bar = mean(d[i]);
vector<double> d_d_bar(d[i].size());
subtract(d[i], y_bar, d_d_bar);
vector<vector<double>> t(d.size());
outer_product(d_d_bar, d_d_bar, t);
add(dst, t, dst);
}
scale(dst, 1/(d.size() - 1));
}
I think maybe For loop in outer_product it's wrong:
void outer_product(vector<double> row, vector<double> col, vector<vector<double>>& dst) {
for(unsigned i = 0; i < row.size(); i++) {
for(unsigned j = 0; j < col.size(); i++) {
dst[i][j] = row[i] * col[j];
}
}
I will change i++ -> j++

C++ Calculating an average of a variable width of numbers in a 2D array

I am aware that there allready are similar questions here but no answer really helped me.
This is my problem:
I have given an array with 512x512 pixels in it. Each pixel has a value like 165.88009. ( I have to create a heatmap in GnuPlot later)
Now I want to "smoothen" it by creating the average of a variable block of pixels (like 4-16) and write it into a new 2D array and jump to the next block until it is done.
The size of the array should stay the same. So if I average 4 pixels those 4 pixels get the new value.
I made a function for this but it doesn't work properly.
Calculating the average is not my problem. The problem is that I want to have a variable width of pixels but I don't know how to make my algorithm jump to the next block.
Im not experienced in C++ and maybe I have to do it completely different.
So any help or inspiration is greatly appreciated :)
here is my code:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int i, j, m, n, k;
void Average(double **Data, int width) // width gets defined and initiated in main
{
double sum;
double avg;
fstream Output;
Output.open( "GemittelteWerte.dat", ios::out);
double** IV_Matrix = new double* [m];
for (int i=0; i<m; i++)
{
IV_Matrix[i] = new double [n];
}
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
{
IV_Matrix[i][j] = 1.0;
}
}
// Here start all my troubles:
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j+=width)
{
sum = 0.0;
k=j;
for( k; k<(j+width); k++)
{
sum+=Data[i][k];
}
avg=(sum/width);
for (int k; k<(j+width); k++)
{
IV_Matrix[i][k] = avg;
}
}
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
Output<<setprecision(10)<<IV_Matrix[i][j]<<"\t";
}
Output<<"\n";
}
Output.close();
}
Is this block a 2D block (4 = 2x2, 16 = 4x4)? You simply want to do a 2D convolution? Then better use odd widths with 3x3, 5x5, ... kernels.
// int x, y are the dimensions of your image
double get (double **img, int i, int j) // zero padding for areas outside image
{
if (i<0 || i>=x || j<0 || j>=y)
return 0;
else
return img[i][j];
}
void conv (double **img, double **result, int width2) // kernel is (2*width2+1)^2
{
double sum;
for (int i=0; i<x; i++)
for (int j=0; j<y; j++)
{
sum = 0;
for (int ii=-width2; ii<=width2; ii++)
for (int jj=-width2; jj<=width2; jj++)
sum += get(img,i+ii,j+jj) / ((2*width2+1)*(2*width2+1));
result[i][j] = sum;
}
}
This smoothes img to result. Its however the slow unseparated solution. For small images and kernels no problem.
Edit: then easier:
// x, y are the dimensions of your image (x rows, y colums)
void avg (double **img, double **result, int width) // width must be >= 1 and
{ // should be a divider of y
double sum;
for (int i=0; i<x; i++) // process all rows
{
for (int j=0; j<y; j+=width) // jump in block width through a row
{
sum = 0.0;
for (int w=0; w<width; w++) // calculate average of a block
{
sum += img[i][j+w] / width;
}
for (int b=0; b<width; b++) // write average in each pixel inside block
{
result[i][j+b]= sum;
}
}
}
//di means diagonal index
for(int di = 0; di < n/width; ++di) {
int sum = 0.0;
//we sum the values
for(int i = di*width; i < (di+1)*width; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
sum += Data[i][j];
}
}
//Divide by the number of values
sum /= width*width;
//Spread the results
for(int i = di*width; i < (di+1)*width; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
IV_Matrix[i][j];
}
}
}
//n might not be a multiple of width
if(n % width != 0) {
//we sum the values
for(int i = (n/width)*width; i < n; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
sum += Data[i][j];
}
}
//Divide by the number of values
sum /= width*width;
//Spread the results
for(int i = (n/width)*width; i < n; ++i)
{
for(int j = (n/width)*width; j < n; ++j)
IV_Matrix[i][j];
}
}
}

SUDOKU solver in c++

I need help to make a Sudoku solver in C++.
Requirements of the program:
Input Sudoku:[Done]
Read Sudoku: [Done]
Validate function: (validates the Sudoku:) [Done]
Display function [done]
solve function [need help]
My plan:
Make a function to validate the sudoku [done]
and assign possibility of 1-9 for every blank colume. and perform a brute-force
method to solve the puzzle. It will call the function validate each time
while doing brute force. It consumes a lot of time and I understood that it is
impossible.
I need a better algorithm for the solve function, please help me.
I have commented some of the code just to analyses the code: Apologize if that is the wrong way.
Here is what I have done so far:
/* Program: To solve a SU-DO-KU:
Date:23-sep-2013 # 5.30:
*/
#include<iostream>
using namespace std;
int su_in[9][9]={
0,0,7 ,0,0,0 ,4,0,6,
8,0,0 ,4,0,0 ,1,7,0,
0,0,0 ,3,0,0 ,9,0,5,
0,0,0 ,7,0,5 ,0,0,8,
0,0,0 ,0,0,0 ,0,0,0,
4,0,0 ,2,0,8 ,0,0,0,
7,0,4 ,0,0,3 ,0,0,0,
0,5,2 ,0,0,1 ,0,0,9,
1,0,8 ,0,0,0 ,6,0,0
};
int su_out[9][9];/*={
5,3,7 ,9,1,2 ,4,8,6,
8,2,9 ,4,5,6 ,1,7,3,
6,4,1 ,3,8,7 ,9,2,5,
9,1,3 ,7,4,5 ,2,6,8,
2,8,6 ,1,3,9 ,7,5,4,
4,7,5 ,2,6,8 ,3,9,1,
7,6,4 ,8,9,3 ,5,1,2,
3,5,2 ,6,7,1 ,8,4,9,
1,9,8 ,5,2,4 ,6,3,7
};*/
struct chance{
int poss[9];
};
int box_validate(int,int,int);
void read(int);
void display(int);
int validate(int);
int solve();
int main()
{
int i,j,row,get_res=2;
enum {input=1,output};
cout<<"enter the sudoku: use 0 if the colum is empty:\n";
// for(i=0; i<9; i++){
// read(i);
// }
cout<<"\n\t\tTHE ENTERED SU-DO-CU IS:\n\n";
display(input);
get_res=validate(input);
if(get_res==0)
cout<<"valid input!\n";
else if(get_res==1)
cout<<"invalid input!\n";
// display(input);
for(i=0; i<9; i++)
for(j=0; j<9; j++)
su_out[i][j]=su_in[i][j];
// display(output);
get_res=validate(output);
if(get_res==0){
cout<<"valid solution!\n"; display(output);}
// else if(get_res==1)
// cout<<"invalid sudoku!\n";
if(solve()==0) display(output);
else cout<<"not solved buddy!!\n";
}
void read(int row) // function to read the SU-DO-CU
{
unsigned num,i;
cout<<"enter the row:'"<<row+1<<"'\n";
for(i=0; i<9; i++)
{
cin>>num;
if(num<0||num>9)
cout<<"error! invalid input: enter a number < or = 9 and > or = 0 \n";
else
su_in[row][i]=num;
}
}
void display(int sudoku) // function to display the SU-DO-CU
{
unsigned i,j;
for(i=0;i<9; i++)
{
if(i%3==0)
cout<<"\t\t-------------------------\n";
cout<<"\t\t";
for(j=0; j<9; j++)
{
if(j%3==0)
cout<<"| ";
// if(su[i][j]==0)
// cout<<"_ ";
// else
if(sudoku==1)
cout<<su_in[i][j]<<" ";
else if(sudoku==2)
cout<<su_out[i][j]<<" ";
if(j==8)
cout<<"|";
}
cout<<"\n";
if(i==8)
cout<<"\t\t-------------------------\n";
}
}
int validate(int sudoku) // function to validate the input SU-DO-CU
{
unsigned i,j,k,n,count=0;
//..........................row validation
for(i=0; i<9; i++)
for(j=0; j<9; j++)
for(k=0;k<9;k++)
{
if(sudoku==1 && k!=j && su_in[i][j]!=0)
{
if(su_in[i][j]==su_in[i][k])
return 1;
}
else if(sudoku==2 && k!=j )
{
if(su_out[i][j]==su_out[i][k])
return 1;
}
}
//..................................colume validation
for(i=0; i<9; i++)
for(j=0; j<9; j++)
for(k=0; k<9; k++)
{
if(sudoku==1 && k!=j && su_in[j][i]!=0)
{
if(su_in[j][i]==su_in[k][i])
return 1;
}
else if(sudoku==2 && k!=i )
{
if(su_out[j][i]==su_out[j][k])
return 1;
}
}
// each box validating.......................
for(i=0; i<=6; i=i+3)
for(j=0; j<=6; j=j+3)
{
if(box_validate(i,j,sudoku)==1)
return 1;
}
// sum validation for output....
if(sudoku==2)
{
for(i=0; i<9; i++)
for(j=0; j<9; j++)
count=count+su_out[i][j];
if(count!=405) return 1;
}
return 0;
}
int box_validate(int i,int j,int sudoku)
{
unsigned k=j,n=i;
int temp_i=i,temp_j=j,temp_k=k, temp_n=n;
for(i=temp_i; i<temp_i+3; i++)
for(j=temp_j; j<temp_j+3; j++)
for(k=temp_k; k<temp_k+3; k++)
{
if(sudoku==1 && k!=j && su_in[i][j]!=0)
{
if(su_in[i][j]==su_in[i][k])
return 1;
for(n=temp_n; n<temp_n+3; n++)
{
if(sudoku==1 && su_in[i][j]!=0)
if(k==j && n==i)
;else
if(su_in[i][j]==su_in[n][k])
return 1;
}
}
if(sudoku==2 && k!=j )
{
if(su_out[i][j]==su_out[i][k])
return 1;
for(n=temp_n; n<temp_n+3; n++)
{
if(sudoku==1 )
if(k==j && n==i)
;else
if(su_out[i][j]==su_out[n][k])
return 1;
}
}
}
return 0;
}
int solve()
{
unsigned i,j,k,m,n,x;
struct chance cell[9][9];
for(i=0; i<9; i++)
for(j=0; j<9; j++)
if(su_in[i][j]==0)
for(k=0;k<9; k++)
cell[i][j].poss[k]=k+1;
/*
for(i=0; i<9; i++)
for(j=0; j<9; j++)
if(su_in[i][j]==0)
for(k=0;k<9; k++)
{ su_out[i][j]=cell[i][j].poss[k]=k+1;
su_out[i][j]=cell[i][j].poss[k];
for(m=0; m<9; m++)
for(n=0; n<9; n++)
for(x=1; x<=9; x++)
{ if(x!=k+1)
cell[m][n].poss[x]==x;
if(validate(2)==0)
return 0;
}
}*/
for(i=0; i<9; i++)
for(j=0; j<9; j++)
if(su_in[i][j]==0)
while (validate(2)==0)
{
for(k=0;k<9; k++)
{ su_out[i][j]=k+1;
for(m=i+1; m <9 ; m++)
for(n=0; n <9 ; n++)
for(x=1; x<=9; x++)
{ su_out[m][n]=x;
if(validate(2)==0)
return 0;
}
}
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
#define UNASSIGNED 0
#define N 9
bool FindUnassignedLocation(int grid[N][N], int &row, int &col);
bool isSafe(int grid[N][N], int row, int col, int num);
/* assign values to all unassigned locations for Sudoku solution
*/
bool SolveSudoku(int grid[N][N])
{
int row, col;
if (!FindUnassignedLocation(grid, row, col))
return true;
for (int num = 1; num <= 9; num++)
{
if (isSafe(grid, row, col, num))
{
grid[row][col] = num;
if (SolveSudoku(grid))
return true;
grid[row][col] = UNASSIGNED;
}
}
return false;
}
/* Searches the grid to find an entry that is still unassigned. */
bool FindUnassignedLocation(int grid[N][N], int &row, int &col)
{
for (row = 0; row < N; row++)
for (col = 0; col < N; col++)
if (grid[row][col] == UNASSIGNED)
return true;
return false;
}
/* Returns whether any assigned entry n the specified row matches
the given number. */
bool UsedInRow(int grid[N][N], int row, int num)
{
for (int col = 0; col < N; col++)
if (grid[row][col] == num)
return true;
return false;
}
/* Returns whether any assigned entry in the specified column matches
the given number. */
bool UsedInCol(int grid[N][N], int col, int num)
{
for (int row = 0; row < N; row++)
if (grid[row][col] == num)
return true;
return false;
}
/* Returns whether any assigned entry within the specified 3x3 box matches
the given number. */
bool UsedInBox(int grid[N][N], int boxStartRow, int boxStartCol, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row+boxStartRow][col+boxStartCol] == num)
return true;
return false;
}
/* Returns whether it will be legal to assign num to the given row,col location.
*/
bool isSafe(int grid[N][N], int row, int col, int num)
{
return !UsedInRow(grid, row, num) && !UsedInCol(grid, col, num) &&
!UsedInBox(grid, row - row % 3 , col - col % 3, num);
}
void printGrid(int grid[N][N])
{
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++)
cout<<grid[row][col]<<" ";
cout<<endl;
}
}
int main()
{
int grid[N][N] = {{3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0}};
if (SolveSudoku(grid) == true)
printGrid(grid);
else
cout<<"No solution exists"<<endl;
return 0;
}
Here's my code:
I think it's the best.
/*
* File: Sudoku-Solver.cc
*
* Created On: 12, April 2016
* Author: Shlomo Gottlieb
*
* Description: This program holds A sudoku board (size: 9*9),
* it allows the user to input values that he choices
* and finds the first rational solution.
* The program also prints the sudoku whether A solution
* was found or not.
*
*/
//========= Includes =========//
#include <iostream>
//========= Using ==========//
using namespace std;
//========= Constants =========//
const int N = 3; // The size of 1 square in the sudoku.
const int EMPTY = 0; // A sign for an empty cell.
const int STOP_INPUT = -1; // A sign for stop get input.
//====== Function Declaration ======//
void input_sud(int sud[][N*N]);
bool fill_sud(int sud[][N*N], int row, int col);
void print_sud(const int sud[][N*N]);
bool is_legal(const int sud[][N*N], int row, int col, int val);
bool is_row_ok(const int row[], int col, int val);
bool is_col_ok(const int sud[][N*N], int row, int col, int val);
bool is_sqr_ok(const int sud[][N*N], int row, int col, int val);
//========== Main ===========//
int main()
{
int sud[N*N][N*N] = { { EMPTY } }; // The sudoku board.
input_sud(sud);
fill_sud(sud, 0, 0);
print_sud(sud);
return 0;
}
//======== Input Sudoku ========//
// Gets the input for the sudoku,
// 0 means an empty cell.
void input_sud(int sud[][N*N])
{
for(int i = 0; i < N*N; i++)
for(int j = 0; j < N*N; j++)
cin >> sud[i][j];
}
//======== Fill Sudoku =========//
// Tries to fill-in the given sudoku board
// according to the sudoku rules.
// Returns whether it was possible to solve it or not.
bool fill_sud(int sud[][N*N], int row, int col)
{
// Points to the row number of the next cell.
int next_row = (col == N*N - 1) ? row + 1 : row;
// Points to the column number of the next cell.
int next_col = (col + 1) % (N*N);
// If we get here, it means we succeed to solve the sudoku.
if(row == N*N)
return true;
// Checks if we are allowed to change the value of the current cell.
// If we're not, then we're moving to the next one.
if(sud[row][col] != EMPTY)
return fill_sud(sud, next_row, next_col);
// We're about to try and find the legal and appropriate value
// to put in the current cell.
for(int value = 1; value <= N*N; value++)
{
sud[row][col] = value;
// Checks if 'value' can stay in the current cell,
// and returns true if it does.
if(is_legal(sud, row, col, value) && fill_sud(sud, next_row, next_col))
return true;
// Trial failed!
sud[row][col] = EMPTY;
}
// None of the values solved the sudoku.
return false;
}
//======== Print Sudoku ========//
// Prints the sudoku Graphically.
void print_sud(const int sud[][N*N])
{
for(int i = 0; i < N*N; i++)
{
for(int j = 0; j < N*N; j++)
cout << sud[i][j] << ' ';
cout << endl;
}
}
//========== Is Legal ==========//
// Checks and returns whether it's legal
// to put 'val' in A specific cell.
bool is_legal(const int sud[][N*N], int row, int col, int val)
{
return (is_row_ok(sud[row], col, val) &&
is_col_ok(sud, row, col, val) &&
is_sqr_ok(sud, row, col, val));
}
//========= Is Row OK =========//
// Checks and returns whether it's legal
// to put 'val' in A specific row.
bool is_row_ok(const int row[], int col, int val)
{
for(int i = 0; i < N*N; i++)
if(i != col && row[i] == val)
return false; // Found the same value again!
return true;
}
//========= Is Column OK =========//
// Checks and returns whether it's legal
// to put 'val' in A specific column.
bool is_col_ok(const int sud[][N*N], int row, int col, int val)
{
for(int i = 0; i < N*N; i++)
if(i != row && sud[i][col] == val)
return false; // Found the same value again!
return true;
}
//========= Is Square OK =========//
// Checks and returns whether it's legal
// to put 'val' in A specific square.
bool is_sqr_ok(const int sud[][N*N], int row, int col, int val)
{
int row_corner = (row / N) * N;
// Holds the row number of the current square corner cell.
int col_corner = (col / N) * N;
// Holds the column number of the current square corner cell.
for(int i = row_corner; i < (row_corner + N); i++)
for(int j = col_corner; j < (col_corner + N); j++)
if((i != row || j != col) && sud[i][j] == val)
return false; // Found the same value again!
return true;
}
//here's a pseudo sudoku solver:
#include <iostream>
#include <cmath>
#include "time.h"
//for(int i=0; i< ++i){}
using namespace std;
int main(){
int a[9][9]={{0,7,0,0,2,0,1,0,0},
{6,0,3,0,0,0,0,0,0},
{2,0,0,3,0,0,5,0,0},
{0,0,0,0,3,0,0,6,0},
{0,6,4,7,0,0,0,8,0},
{0,5,0,0,9,0,0,4,0},
/*54*/ {0,4,0,0,7,0,9,0,0},
{0,2,0,0,0,8,0,5,0},
{0,0,0,0,0,0,0,0,0}};/*this is the grid. I need to use two so that I can use one as a constant reference*/
int a2[9][9]={{0,7,0,0,2,0,1,0,0},
{6,0,3,0,0,0,0,0,0},
{2,0,0,3,0,0,5,0,0},
{0,0,0,0,3,0,0,6,0},
{0,6,4,7,0,0,0,8,0},
{0,5,0,0,9,0,0,4,0},
{0,4,0,0,7,0,9,0,0},
{0,2,0,0,0,8,0,5,0},
{0,0,0,0,0,0,0,0,0}};
int x=0,y=0,z=0;
int oo=0,o=0,ooo=0,oooo=0;
for(int i=0; i<9; ++i)/*this is the double for loop. to keep track of the cells*/
{
for(int j=0; j<9; ++j)
{
if(!a2[i][j])
{a://label that if something doesn't work, to restart here.
++a[i][j];//increment the number in the cell by 1.
if(a[i][j]>9)/*if no valid number is found/the number is out of range, execute the if statement. **This is the backtracking algorithm.***/
{
a[i][j]=0;//erase the invalid number.
--j;if(j<0){--i;j=8;} /*if j equals < 0, j is reset to 8, as the first 9 numbers are easy to find, and if j needs to be reset, there will always be a number in the j equals 8 cell. The "i" will never be less than zero, if it is a valid puzzle, so the j=8 will only happen after i is > 0.*/
while(a2[i][j]){--j;if(j<0){--i;j=8;}}/*if there was a number present from the beginning, skip it until a variable cell space is found.*/
goto a;//jump to a: and increment the current number in the cell by 1.
}
if(j<3){o=0;oo=3;}if(j>2 && j<6){o=3;oo=6;}/*locate the 3X9 grid j is in.*/
if(j>5){o=6;oo=9;}
if(i<3){ooo=0;oooo=3;}if(i>2 && i<6){ooo=3;oooo=6;}/*locate the 9X3 grid i is in.*/
if(i>5){ooo=6;oooo=9;}
for(int u=ooo; u<oooo; ++u)/*intersect the 3X9 and 9X3 grids to create a searchable 3X3 grid.*/
{
for(int p=o; p<oo; ++p)
{
if(a[u][p]==a[i][j]){++x;if(x>1){x=0;goto a;}}/*if the number is not valid, go to a: and increment the number in the cell by 1.*/
}
}
x=0;
for(int n=0; n<9; ++n)
{
if(a[i][j]==a[i][n]){++y; if(y>1){y=0;goto a;}}/*if no valid number is found, goto a: and increment the number in the cell by 1.*/
}y=0;
for(int m=0; m<9; ++m)
{
if(a[i][j]==a[m][j]){++y; if(y>1){y=0;goto a;}}//""
} y=0;
}
}
}
for(int i=0; i<9; ++i)//print the completed puzzle.
{
for(int j=0; j<9; ++j)
{
cout<<a[i][j]<<" ";
}
cout<<endl;//print on the next line after 9 digits are printed.
}
return 0;
}
//if no valid puzzle is found, the screen hangs. - Harjinder
/*random sudokus' can be generated and solved in one program by copying the following code into an editor. hit enter to generate and solve a new puzzle:
//the following works the same way as above except that it is 2 solvers in a continuous while loop
//the first solver, to generate the random puzzle:
#include <iostream>
using namespace std;
int main(){
while(1){
int a[9][9]={0}, a2[9][9]={0};
int w=0, x=0,y=0,z=0, yy=0, oo=0,o=0,ooo=0,oooo=0;
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{
if(!a2[i][j])
{srand(time(0));if(w<5){++w;a[i][j]=rand()%9;}a:++a[i][j];//generate a random number from 0 to 9 and and then increment by 1.
if(a[i][j]>9)
{
a[i][j]=0;
--j;if(j<0){--i;j=8;}
while(a2[i][j]){--j;if(j<0){--i;j=8;}}
goto a;
}
if(j<3){o=0;oo=3;}if(j>2 && j<6){o=3;oo=6;}
if(j>5){o=6;oo=9;}
if(i<3){ooo=0;oooo=3;}if(i>2 && i<6){ooo=3;oooo=6;}
if(i>5){ooo=6;oooo=9;}
for(int u=ooo; u<oooo; ++u)
{
for(int p=o; p<oo; ++p)
{
if(a[u][p]==a[i][j]){++x;if(x>1){x=0;goto a;}}
}}
x=0;
for(int n=0; n<9; ++n)
{
if(a[i][j]==a[i][n]){++y; if(y>1){y=0;goto a;}}
}y=0;
for(int m=0; m<9; ++m)
{
if(a[i][j]==a[m][j]){++y; if(y>1){y=0;goto a;}}
} y=0;}//if
}
}
//the second part below is to add zeros' to the puzzle, and copy the puzzle into the second solver arrays.
int n=40;//adjusts the amount of empty spaces. works only if landed on non-zero, or else the zero will be counted.
x=0;int xx=0;
o=0;int pp=0,ppp=0;
while(o<n)
{
pp=rand()%9;
ppp=rand()%9;
a[pp][ppp]=0;
pp=rand()%9;
ppp=rand()%9;
a[ppp][pp]=0;
++o;
}
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
x=0,xx=0;
cout<<endl<<endl;
int a5[9][9]={0}, a6[9][9]={0};x=-1;
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{
++x;
a5[i][j]=a[i][j];//copy first puzzle with added zeros into the new array.
}
}
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{
a6[i][j]=a5[i][j];//copy the updated puzzle with zeros, into the constant reference array.
}
}
x=0;
////////////////////////////////////////////////////////////////////////
//second solver to solve the zero updated array:
cout<<endl<<endl;
o=0;
y=0,z=0;
oo=0,ooo=0,oooo=0;
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{
if(!a6[i][j])
{c5:
++a5[i][j];
if(a5[i][j]>9)
{
a5[i][j]=0;
--j;if(j<0){--i;j=8;}
while(a6[i][j]){--j;if(j<0){--i;j=8;}}
goto c5;
}
if(j<3){o=0;oo=3;}if(j>2 && j<6){o=3;oo=6;}
if(j>5){o=6;oo=9;}
if(i<3){ooo=0;oooo=3;}if(i>2 && i<6){ooo=3;oooo=6;}
if(i>5){ooo=6;oooo=9;}
for(int u=ooo; u<oooo; ++u)
{
for(int p=o; p<oo; ++p)
{
if(a5[u][p]==a5[i][j]){++x;if(x>1){x=0;goto c5;}}
}}
x=0;
for(int n=0; n<9; ++n)
{
if(a5[i][j]==a5[i][n]){++y; if(y>1){y=0;goto c5;}}
}y=0;
for(int m=0; m<9; ++m)
{
if(a5[i][j]==a5[m][j]){++y; if(y>1){y=0;goto c5;}}
} y=0;} }
}
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{
cout<<a5[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
system("pause");//hit enter to load a new puzzle
}
return 0;
} */
The answer given above is similar to what a lot of people have posted at several websites like https://www.geeksforgeeks.org/sudoku-backtracking-7/. TBH, those solutions are not intuitive to me when they don't initialize row and col and call it in the FindUnassignedLocation function. I wanted to give it a shot myself with slight help from another answer I found on LeetCode. If it helps anyone, here you go.
// https://www.pramp.com/challenge/O5PGrqGEyKtq9wpgw6XP
#include <iostream>
#include <vector>
using namespace std;
// Print the sudoku
void print(vector<vector<char>> board){
for(int i = 0; i < board.size(); i++){
for(int j = 0; j < board[i].size(); j++){
cout << board[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
// Check if sudoku is all filled up
bool checkIfFilled(vector<vector<char>> board){
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(board[i][j] == '.')
return false;
}
}
return true;
}
// Check if a given number can be inserted at a given position
bool checkIfInsertOkay(vector<vector<char>> board, int x, int y, char num){
// Check row if num already exists
for(int j = 0; j < 9; j++){
if(board[x][j] == num)
return false;
}
// Check column if num already exists
for(int i = 0; i < 9; i++){
if(board[i][y] == num)
return false;
}
// Check 3x3 gird if num already exists
// Find the corners
// Find i
if(x < 3)
x = 0;
else if(x < 6)
x = 3;
else
x = 6;
// Find j
if(y < 3)
y = 0;
else if(y < 6)
y = 3;
else
y = 6;
// Check the 3x3 box
for(int i = x; i < x+3; i++){
for(int j = y; j < y+3; j++){
if(board[i][j] == num)
return false;
}
}
return true;
}
// Helper function because of const issues
bool sudokuSolveHelper(vector<vector<char>> &board){
// Base condition - if sudoku gets completely filled
if(checkIfFilled(board))
return true;
// Iterate through the sudoku
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
// If empty space
if(board[i][j] == '.'){
for(int k = 1; k <= 9; k++){
// Check if char(k) can be inserted at this empty location
char ch = '0' + k;
if(checkIfInsertOkay(board, i, j, ch)){
// Put k in this empty location and check
board[i][j] = ch;
// Check if done
bool flag = sudokuSolveHelper(board);
if(flag)
return true;
else
// Else, backtrack by making it empty again
board[i][j] = '.';
}
}
return false;
}
}
}
return true;
}
// Return true if a correct sudoku can be formed
// Apply backtracking
// Time complexity = O(9^empty spaces)
bool sudokuSolve(vector<vector<char>> &board){
return sudokuSolveHelper(board);
}
int main() {
vector<vector<char>> board = {
{'.','.','.','7','.','.','3','.','1'},
{'3','.','.','9','.','.','.','.','.'},
{'.','4','.','3','1','.','2','.','.'},
{'.','6','.','4','.','.','5','.','.'},
{'.','.','.','.','.','.','.','.','.'},
{'.','.','1','.','.','8','.','4','.'},
{'.','.','6','.','2','1','.','5','.'},
{'.','.','.','.','.','9','.','.','8'},
{'8','.','5','.','.','4','.','.','.'}
};
print(board);
bool flag = sudokuSolve(board);
if(flag){
cout << "A solution exists as below\n";
print(board);
}
else
cout << "No solution exists!\n";
return 0;
}
//the following works like the one above accept there is a while loop instead of goto statements:
#include <iostream>
#include <cmath>
#include "time.h"
//for(int i=0; i< ++i){}
using namespace std;
int main(){
int a[9][9]={{2,0,0,0,0,0,0,0,1},
{0,0,0,9,0,6,0,0,0},
{0,0,0,8,0,1,7,2,0},
{9,0,0,3,0,0,0,0,0},
{0,0,8,0,0,0,2,0,4},
{0,0,0,0,0,0,0,1,3},
/*54*/ {1,0,3,0,0,5,0,0,9},
{0,0,0,0,0,0,0,0,0},
{0,4,6,2,0,0,0,0,0}};
int a2[9][9]={{2,0,0,0,0,0,0,0,1},
{0,0,0,9,0,6,0,0,0},
{0,0,0,8,0,1,7,2,0},
{9,0,0,3,0,0,0,0,0},
{0,0,8,0,0,0,2,0,4},
{0,0,0,0,0,0,0,1,3},
{1,0,3,0,0,5,0,0,9},
{0,0,0,0,0,0,0,0,0},
{0,4,6,2,0,0,0,0,0}};
int x=0,y=0,z=0;
int colPlusThree=0,col=0,row=0,rowPlusThree=0;
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{z=0;
if(!a2[i][j])
{while(z==0){ //the master while loop. loops until a valid number is found.
++a[i][j];
if(a[i][j]>9)
{
a[i][j]=0;
--j;if(j<0){--i;j=8;}
while(a2[i][j]){--j;if(j<0){--i;j=8;}}
++a[i][j];if(a[i][j]>9){--j;}
}
if(j<3){col=0;colPlusThree=3;}if(j>2 && j<6){col=3;colPlusThree=6;}
if(j>5){col=6;colPlusThree=9;}
if(i<3){row=0;rowPlusThree=3;}if(i>2 && i<6){row=3;rowPlusThree=6;}
if(i>5){row=6;rowPlusThree=9;}
for(int u=row; u<rowPlusThree; ++u)
{
for(int p=col; p<colPlusThree; ++p)
{
if(a[u][p]==a[i][j]){++x;if(x>1){u=rowPlusThree;break;}}
}}if(x<2){z=1;}else{z=0;}x=0;
for(int n=0; n<9; ++n)
{
if(z==0){y=2;break;}
if(a[i][j]==a[i][n]){++y; if(y>1){break;}}
}if(y<2){z=1;}else{z=0;}y=0;
for(int m=0; m<9; ++m)
{
if(z==0){y=2;break;}
if(a[i][j]==a[m][j]){++y; if(y>1){break;}}
} if(y<2){z=1;}else{z=0;}y=0;}}}}
for(int i=0; i<9; ++i)
{
for(int j=0; j<9; ++j)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return 0;
}// - Harjinder