I was writing the program for finding a path through an defined matrix.
#include<iostream>
#include<list>
using namespace std;
class maze{
int inst[10][10];
int m,n,initr,initc,finalr,finalc;
public:
maze(int c){
if(c==1) return;
cout<<"\n Enter rows and colums: ";
cin>>m>>n;
cout<<endl<<"\n ENter initial configuration (1 for block, 0 for open):";
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
cin>>inst[i][j];
}
}
cout<<endl<<"Enter initial state in row column:";
cin>>initr>>initc;
cout<<endl<<"Enter final state in row column:";
cin>>finalr>>finalc;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==1) inst[i][j]=(-1);
}
}
inst[initr][initc]=1;
}
bool up(int curr){
int x,y;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(x==0) return false;
if(inst[x-1][y]==0){
//cout<<"\n up "<<x-1<<y;
inst[x-1][y]=curr+1;
return true;
}else return false;
}
bool down(int curr){
int x,y;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(x==m-1) return false;
if(inst[x+1][y]==0){
//cout<<"\n down "<<x+1<<y;
inst[x+1][y]=curr+1;
return true;
}else return false;
}
bool left(int curr){
int x,y;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(y==0) return false;
if(inst[x][y-1]==0){
//cout<<"\n left "<<x<<y-1;
inst[x][y-1]=curr+1;
return true;
}else return false;
}
bool right(int curr){
int x,y;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(y==n-1) return false;
if(inst[x][y+1]==0){
//cout<<"\n right "<<x<<y+1;
inst[x][y+1]=curr+1;
return true;
}else return false;
}
bool check(int curr){
int x,y;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(x==finalr && y==finalc) return true;
else return false;
}
void print_maze(){
cout<<endl<<endl;
for(int i=0;i<m;i++){
cout<<endl;
for(int j=0;j<n;j++){
cout<<"\t"<<inst[i][j];
}
}
}
};
bool state_search(){
int curr=1;
maze start(0),temp(1);
list<maze> queue;
queue.push_back(start);
while(!queue.empty()){
start = queue.front();
queue.pop_front();
if(start.check(curr)){
start.print_maze();
return true;
}
//start.print_maze();
temp=start;
if(temp.up(curr)) queue.push_back(temp);
temp=start;
if(temp.down(curr)) queue.push_back(temp);
temp=start;
if(temp.left(curr)) queue.push_back(temp);
temp=start;
if(temp.right(curr)) queue.push_back(temp);
curr++;
}
cout<<"\n No answer found";
}
int main(){
state_search();
}
This program works fine for most of the inputs. But gives an address boundry error for the following input
Enter rows and colums: 4 4
ENter initial configuration (1 for block, 0 for open):0 0 0 0 0 1 0 1
0 1 1 1 0 0 0 0
Enter initial state in row column:1 0
Enter final state in row column:3 3 fish: “./a.out” terminated by
signal SIGSEGV (Address boundary error)
Please suggest the possible reason for this error and how to correct it
The problem is that you don't initialize x and y values in your up, down, left and right functions. And then if you don't find the indexes for curr, you access the inst array at random indexes.
In right function you should declare x and y like this:
int x = 0,y = 0;
In left:
int x = m - 1,y = 0;
Do the same in right and left.
You use uninitialized variables x and y in method maze::up:
bool up(int curr){
int x,y; // !!!
...
So when in following loops we didn't go inside if statement these variables still contain garbage from uninitialized allocated memory.
...
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
...
And it's very high possibility that x is not in range [0, 10).
...
if(x==0) return false;
if(inst[x-1][y]==0){
...
And we immediately try to get value somewhere (inst[x-1][y]) far away in memory, and terminated with segmentation error.
Fix: It's better to initialize all the variables with meaningful values. Suppose that for your code this is correct solution:
bool up(int curr){
int x = 0, y = 0;
...
You can tell to compiler to notify you when you keep somewhere uninitialized variables.
If you use GCC compiler you can use compilation flag:
g++ -O2 -Wuninitialized prog.cpp
And you will see a lot of similar places in your code.
Additionally you can use flag -Wall, and you will found that bool state_search() function reaches end without returning any value.
I realized where the mistake was. I did not initialize x and y in the functions maze::up(), maze::down(), maze::right() and maze::left() as it was always supposed to be initialized by the function while traversing the matrix. The Error was in the algorithm itself. The variable curr from state_search() was supposed to denote the depth of the BFS tree. But since it was incrementing for every node found, it denoted the depth wrongly causing error whenever there were 2 possible paths.
To solve this issue, I removed the curr variable from state_search() and added it to the class definition initializing it to 1 and incrementing it whenever the functions maze::up(), maze::down(), maze::right() and maze::left() are called.
here is the complete working code
#include<iostream>
#include<list>
using namespace std;
class maze{
int inst[10][10];
int m,n,initr,initc,finalr,finalc,curr;
public:
maze(int c){
if(c==1) return;
cout<<"\n Enter rows and colums: ";
cin>>m>>n;
cout<<endl<<"\n ENter initial configuration (1 for block, 0 for open):";
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
cin>>inst[i][j];
}
}
cout<<endl<<"Enter initial state in row column:";
cin>>initr>>initc;
cout<<endl<<"Enter final state in row column:";
cin>>finalr>>finalc;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==1) inst[i][j]=(-1);
}
}
inst[initr][initc]=1;
curr=1;
}
bool up(){
int x=0,y=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(x==0) return false;
if(inst[x-1][y]==0){
inst[x-1][y]=curr+1;
curr++;
return true;
}else return false;
}
bool down(){
int x=m-1,y=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(x==m-1) return false;
if(inst[x+1][y]==0){
inst[x+1][y]=curr+1;
curr++;
return true;
}else return false;
}
bool left(){
int x,y=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(y==0) return false;
if(inst[x][y-1]==0){
inst[x][y-1]=curr+1;
curr++;
return true;
}else return false;
}
bool right(){
int x,y=n-1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(y==n-1) return false;
if(inst[x][y+1]==0){
inst[x][y+1]=curr+1;
curr++;
return true;
}else return false;
}
bool check(){
int x,y;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(inst[i][j]==curr) {
x=i;
y=j;
break;
}
}
}
if(x==finalr && y==finalc) return true;
else return false;
}
void print_maze(){
cout<<endl<<endl;
for(int i=0;i<m;i++){
cout<<endl;
for(int j=0;j<n;j++){
cout<<"\t"<<inst[i][j];
}
}
}
};
bool state_search(){
maze start(0),temp(1);
list<maze> queue;
queue.push_back(start);
while(!queue.empty()){
start = queue.front();
queue.pop_front();
if(start.check()){
start.print_maze();
return true;
}
temp=start;
if(temp.up()) queue.push_back(temp);
temp=start;
if(temp.down()) queue.push_back(temp);
temp=start;
if(temp.left()) queue.push_back(temp);
temp=start;
if(temp.right()) queue.push_back(temp);
}
cout<<"\n No answer found";
return false;
}
int main(){
state_search();
}
Related
class Suduko
{
public:
int N=4;
int grid[N][]={{1,0,3,0}
,{0,0,2,1}
,{0,1,0,2}
,{2,4,0,0}};
bool solve()
{
int i,j;
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
if(grid[i][j]==0)
break;
}
if(i==N && j==N)
return true;
for(int n=1;n<=N;n++)
{
if(issafe(i,j,n))
{
grid[i][j]=n;
if(solve())
return true;
grid[i][j]=0;
}
}
return false;
}
bool issafe(int i,int j,int n)
{
for(int k=0;k<N;k++)
if(grid[k][j]==n || grid[i][k]==n)
return false;
int s=sqrt(N);
int rs=i-i%s;
int cs=j-j%s;
for(int i=0;i<s;i++)
for(int j=0;j<s;j++)
if(grid[i+rs][j+cs]==n)
return false;
return true;
}
void print()
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
cout<<grid[i][j]<<" ";
}
cout<<endl;
}
};
When I try to solve the sudoku problem I got an error in line number 8 " Invalid use of non-static data member 'Suduko::N' ".
I am new to C++, I don't figure out what is the cause of this error please help me to remove this error.
I wrote this code for printing the productions after eliminating left recursion.And also i stored these output productions in "all" array. when i print this array, only the last values are being printed with blank lines in the initial rows.How to resolve this problem?
#include<iostream>
#include<cstring>
using namespace std;
class production
{
private:
char lhs;
char rhs[10][10],nr[10][10],rs[10][10],all[30][30];
int noa,m;
public:
production()
{
noa=0;m=0;
for(int i=0;i<30;i++)
for(int j=0;j<30;j++)
all[i][j]='\0';
}
void makeprod(char *str)
{
noa=0;
for(int i=0;i<30;i++)
for(int j=0;j<30;j++)
rhs[i][j]='\0';
lhs=str[0];
char r[20];
strcpy(r,str+3);
int j=0;
for(int i=0;r[i]!='\0';i++)
{
if(r[i]!='/')
rhs[noa][j++]=r[i];
else
{
rhs[noa++][j]='\0';
j=0;
}
}
noa++;
}
void checks(string sr)
{
for(int i=0;i<30;i++)
for(int j=0;j<30;j++)
rs[i][j]=nr[i][j]='\0';
int ct=0,k=0,l=0;
for(int i=0;i<noa;i++)
{
if(lhs==rhs[i][0])
{
strcat(rhs[i],sr.c_str());
strcpy(rs[k],rhs[i]+1);
k++;
}
else
{
strcpy(nr[l],rhs[i]);
strcat(nr[l],sr.c_str());
l++;
}
}
if(l==noa)
{
cout<<lhs<<"->";
for(int i=0;i<noa;i++)
cout<<rhs[i]<<" ";
cout<<"\n";
all[m][0]=lhs;
strcat(all[m],"->");
for(int i=0;i<noa;i++)
{
strcat(all[m],rhs[i]);
strcat(all[m],"/");
}
m++;
}
else
{
cout<<lhs<<"->";
for(int i=0;i<l;i++)
cout<<nr[i]<<" ";
p.all[m][0]=lhs;
strcat(all[m],"->");
for(int i=0;i<l;i++)
{
strcat(all[m],nr[i]);
strcat(all[m],"/");
}
m++;
cout<<"\n"<<sr<<"->";
for(int i=0;i<k;i++)
cout<<rs[i]<<" ";
cout<<" e\n";
all[m][0]=lhs;
strcat(all[m],"->");
for(int i=0;i<k;i++)
{
strcat(all[m],rs[i]);
strcat(all[m],"/");
}
m++;
}
cout<<"m= "<<m<<"\n";
for(int i=0;i<m;i++)
{
for(int j=0;all[i][j]!='\0';j++)
cout<<all[i][j];
cout<<"\n";
}
}
void display()
{
cout<<"m= "<<m<<"\n";
for(int i=0;i<m;i++)
{
for(int j=0;all[i][j]!='\0';j++)
cout<<all[i][j];
cout<<"\n";
}
}
};
int main()
{
production p;
char str[20][20];
string op[5]={"X","Y","Z","U","V"};
cout<<"enter no of productions\n";
int n,l=0;
cin>>n;
for(int i=0;i<n;i++)
{
cout<<"enter a production\n";
cin>>str[i];
p.makeprod(str[i]);
p.checks(op[l++]);
}
p.display();
return 0;
}
So I am trying to solve sudoku with backtracking
And with this example :
example_pic
I hard-coded some of the indexes in the two dimensional array with numbers on places given from webSudoku (picture above).
It definitely has solutions but, my code prints "solution doesn't exist
Here is my code :
#include <stdio.h>
int a[10][10]= {{2,0,0,0,9,0,0,3,1},
{0,0,3,5,0,6,0,2,0},
{0,0,8,1,3,0,5,4,0},
{7,2,0,0,0,9,0,0,4},
{4,0,0,0,0,0,0,0,8},
{3,0,0,6,0,0,0,9,5},
{0,7,6,0,4,5,1,0,0},
{0,1,0,9,0,7,4,0,0},
{5,3,0,0,8,0,0,0,6}};
bool is_valid(int x, int y, int value){
if(a[x][y] != 0) return false;
//check_row and column
for(int tmp=1; tmp<=9; tmp++){
if(value == a[x][tmp]) return false;
}
for(int tmp=1; tmp<=9; tmp++){
if(value == a[tmp][y]) return false;
}
//check in 3*3 block
int x_s = (x-1)/3*3 + 1;
int y_s = 3*((y+2)/3-1)+1;
for(int ch_x = x_s; ch_x<x_s+3; ch_x++){
for(int ch_y=y_s; ch_y<y_s+3; ch_y++){
if(ch_x!=x && ch_y!=y){
if(value==a[ch_x][ch_y]) return false;
}
}
}
return true;
}
bool find(int &x, int &y){
// check if valid cells are exists
for(x=1; x<=9; x++){
for(y=1; y<=9; y++){
if(a[x][y] == 0)
return true;
}
}
return false;
}
bool solve(){
int x,y;
//base::case
if(!find(x,y)) return true;
for(int cand = 1; cand <=9; cand++){
if(is_valid(x,y,cand)){
a[x][y] = cand;
if(solve()) return true;
a[x][y] = 0;
}
}
return false;
}
void print(){
//print the sudoku plate
for(int i=1;i<=9; i++){
for(int j=1; j<=9; j++){
printf("%2d",a[i][j]);
}
printf("\n");
}
return ;
}
int main(){
//Fill in some empty grid with the known values
/*for(int i=1; i<=9; i++){
for(int j=1; j<=9; j++){
scanf("%1d",&a[i][j]);
}
}*/
if (solve()) print();
else printf("No solution exists\n");
return 0;
}
I guess my 'solve function' or 'is_valid' function is not working right.
In 'is_valid' function, if there is problem it would be
bool find(int &x, int &y){
// check if valid cells are exists
for(x=1; x<=9; x++){
for(y=1; y<=9; y++){
if(a[x][y] == 0)
return true;
}
}
return false;
}
But, I also hard-coded this part and in my scope it doesn't seem like have problem.
In 'solve function'
bool solve(){
int x,y;
//base::case
if(!find(x,y)) return true;
for(int cand = 1; cand <=9; cand++){
if(is_valid(x,y,cand)){
a[x][y] = cand;
if(solve()) return true;
a[x][y] = 0;
}
}
return false;
}
I cant figure out where i got it wrong. If you find any other mistakes in the solve() function - let me know. Because I am not sure I understand the "backtracking" thing completely...
p.s. : reference I read (https://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf)
There are a few mistakes
You are mixing up (x, y) and (row, col) addressing (row is y, not x). Choose a representation and stick to it
There is a typo in is_valid because the check on (c, x) should be on (c, y) (or (y, c) depending on convention but surely using y and not x again)
The 3x3 sub-block computation is wrong... a correct formula could be for example int start_x = (x-1)/3*3 + 1, start_y = (y-1)/3*3 + 1;
Fixing all that the code works on the given example
I was coding about ullman algorithm and when I run my program I faced with :
"Invalid allocation size: 4294967295 byte" error. it could be about vector? or anything else? could any help me about this?
void ullman(Graph &graph,Pattern pattern,int **p,int k)
{
bool flg=true;
if(k>=pattern.vertexNum)
{
int **tmp;
tmp=new int *[pattern.vertexNum];
for(int i=0;i<pattern.vertexNum;i++)
tmp[i]=new int [graph.vertexNum];
for(int i=0;i<pattern.vertexNum;i++)
for(int j=0;j<graph.vertexNum;j++)
tmp[i][j]=p[i][j];
graph.permutation.push_back(tmp);
return;
}
for(int i=0;i<graph.vertexNum;i++)
{
for(int j=0;j<pattern.vertexNum;j++)
if(p[j][i])
flg=false;
if(!flg)
{
flg=true;
continue;
}
p[k][i]=1;
if(examin(graph,pattern,p,k))
ullman(graph,pattern,p,k+1);
p[k][i]=0;
}
return;}
bool examin(Graph &graph,Pattern pattern,int **p,int k)
{
bool flg=true;
int **pt;
pt=new int *[graph.vertexNum];
for(int i=0;i<graph.vertexNum;i++)
pt[i]=new int [pattern.vertexNum];
for(int i=0;i<pattern.vertexNum;i++)
for(int j=0;j<graph.vertexNum;j++)
pt[j][i]=p[i][j];
char **tmp; // P*graph
char **tmp2; // tmp*pt
tmp= new char *[pattern.vertexNum];
for(int i=0;i<pattern.vertexNum;i++)
tmp[i]=new char[graph.vertexNum];
for(int i=0;i<pattern.vertexNum;i++)
for(int j=0;j<graph.vertexNum;j++)
tmp[i][j]='-';
tmp2=new char *[pattern.vertexNum];
for(int i=0;i<pattern.vertexNum;i++)
tmp2[i]=new char[pattern.vertexNum];
for(int i=0;i<pattern.vertexNum;i++)
for(int j=0;j<pattern.vertexNum;j++)
tmp2[i][j]='-';
for(int j=0;j<pattern.vertexNum;j++)
for(int i=0;i<graph.vertexNum;i++)
if(p[j][i])
for(int m=0;m<graph.vertexNum;m++)
tmp[j][m]=graph.G[i][m];
for(int m=0;m<pattern.vertexNum;m++)
for(int i=0;i<graph.vertexNum;i++)
if(pt[i][m])
for(int j=0;j<pattern.vertexNum;j++)
tmp2[j][m]=tmp[j][i];
for(int i=0;i<pattern.vertexNum;i++)
{
for(int j=0;j<pattern.vertexNum;j++)
if(pattern.P[i][j]!='-' && tmp2[i][j]!='-')
if(pattern.P[i][j] != tmp2[i][j])
{
flg=false;
break;
}
if(!flg)
break;
}
if(flg)
return true;
else
return false;}
It looks like you are passing -1 for the size, because 4294967295 corresponds to 0xFFFFFFFF, i.e. the negative one in two's complement representation.
Since the only value that you pass to new [...] is vertexNum, that's the value that you need to check. Add a condition at the top of your functions to see if graph.vertexNum or pattern.vertexNum is negative, set a breakpoint inside the conditional, and see what part of your code is making the invalid call:
void ullman(Graph &graph,Pattern pattern,int **p,int k) {
if(pattern.vertexNum < 0) {
cerr << "pattern.vertexNum is negative" << endl; // Set brekpoint here
}
bool flg=true;
... // The rest of your code
}
I am getting runtime error (SIGSEGV) error when this code is submitted on SPOJ. I cleared the vectors and initialized all variables but still getting the error. What is wrong with this code?
#include<iostream>
#include<vector>
using namespace std;
vector<int> even_greater_increment(vector<int> num,int mid1,int mid2){
int bigindex=0,smallindex=0;
if(num[mid1]==num[mid2]){
return num;
}
if(num[mid1]>num[mid2]){
bigindex=mid1;
smallindex=mid2;
}
else{
bigindex=mid2;
smallindex=mid1;
}
while(num[smallindex]!=num[bigindex]){
num[smallindex]++;
}
return num;
}
bool check9(vector<int> num,int vlen){
for(int i=0;i<vlen;i++){
if(num[i]==9){
continue;
}
else{
return false;
}
}
return true;
}
int nine(vector<int> num,int vlen){
vlen=vlen+1;
num[0]=1;
cout<<num[0];
for(int i=1;i<vlen-1;i++){
num[i]=0;
cout<<num[i];
}
num[vlen-1]=1;
cout<<num[vlen-1];
return 0;
}
vector<int> increment9(vector<int> num,int mid1,int mid2,int vlen){
int l=mid1,k=mid2;
do{
l--;k++;
}while((l>=0&&k<=(vlen-1))&&(num[l]==9&&num[k]==9));
num[l]++;
num[k]++;
for(int i=l+1;i<k;i++){
num[i]=0;
}
return num;
}
vector<int> incrementmiddle(vector<int> num,int mid1,int mid2,int vlen){
if(num[mid1]==9&&num[mid2]==9){
num=increment9(num,mid1,mid2,vlen);
return num;
}
if(mid1==mid2){//odd implementation
num[mid1]=num[mid1]+1;
}
else{//even implementation
num=even_greater_increment(num,mid1,mid2);
}
return num;
}
int println(vector<int> r,int vlen){
for(int p=0;p<vlen;p++){
cout<<r[p];
}
}
bool comp(const vector<int>& v1, const vector<int>& v2) {
if (v1.size() != v2.size())
return v1.size() < v2.size();
for (int i = 0; i < v1.size(); i++)
if (v1[i] != v2[i])
return v1[i] < v2[i];
return false;
}
int palindrome(){
int length=0;
char ch[7];
cin>>ch;
for(int i=0;ch[i]!='\0';i++){
length++;
}
vector<int> num;
vector<int> temp;
for(int j=0;j<length;j++){
int a= ch[j] - '0';
num.push_back(a);
}
int vlen=num.size();
int mid1=0,mid2=0;
if(vlen==1){
cout<<num[0]<<endl;
return 0;
}
if(vlen==2){
mid1=0;mid2=1;
int bigindex,smallindex;
if(num[mid1]>num[mid2]){
bigindex=mid1;
smallindex=mid2;
}
else{
bigindex=mid2;
smallindex=mid1;
}
num[smallindex]=num[bigindex];
println(num,2);
return 0;
}
if(vlen%2==0){
mid2=vlen/2;
mid1=mid2-1;
}
else{
mid1=mid2=vlen/2;
}
temp=num;
if(mid1==mid2){
int y=mid1;
//for odd implementation
for(int j=0;j<mid1;j++){
++y;
num[y]=num[j];
}
//num contains palindrome and temp contains original
if(comp(temp,num)){
println(num,vlen);
return 0;
}//printing the number if the palindrome is greater than the input number
else{
if(check9(num,vlen)){
nine(num,vlen);
return 0;
}
num=incrementmiddle(num,mid1,mid2,vlen);
println(num,vlen);
return 0;
}
}
else{//even implementation
int h=vlen-1;
for(int b=0;b<mid1;b++){
num[h]=num[b];
h--;
}
if(comp(temp,num)){
num=even_greater_increment(num,mid1,mid2);
println(num,vlen);
return 0;
}//printing the number if the palindrome is greater than the input number
else{
if(check9(num,vlen)){
nine(num,vlen);
return 0;
}
num=incrementmiddle(num,mid1,mid2,vlen);
println(num,vlen);
return 0;
}
}
num.clear();
temp.clear();
}
int main(){
int test=0;
cin>>test;
testcase:
for(int f=0;f<test;f++){
palindrome();
cout<<endl;
}
}
It actually takes a number and the print the next small palindrome.
The logic and everything is correct. It works fine in the compiler and ideone.
please help. I really want to get this problem accepted because i spent more than 5 hrs writing the logic.