Here is the simple code which I submitted to UVa Online Judging for Qn 227. (Puzzle) I have tested with various test cases including those from debug.org but still the submission yields "wrong answer". If anyone could point out where the error may lie in the code or just give a test case with which the programme will give wrong answer, it will be greatly appreciated.
//puzzle
#define LOCAL
#include <stdio.h>
#include <string.h>
#define MAX 5
int read(char s[MAX][MAX])
{
int blank=0;
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
s[i][j]=getchar();
if(i==0&&j==0&&s[i][j]=='Z')
return -1;
else if(s[i][j]==' ')
blank=i*10+j;
}
for(;getchar()!='\n';);
}
return blank;
}
int write(char s[MAX][MAX], int blank)
{
char n;
while((n=getchar())!='0')
{
int c1=(blank/10)%10, c2=blank%10;
if(n=='\n')
continue;
else if(n=='A')
{
if(c1==0)
{
for(;getchar()!='\n';);
return 0;
}
else
{
s[c1][c2]=s[c1-1][c2];
s[c1-1][c2]=' ';
blank-=10;
}
}
else if(n=='B')
{
if(c1==4)
{
for(;getchar()!='\n';);
return 0;
}
else
{
s[c1][c2]=s[c1+1][c2];
s[c1+1][c2]=' ';
blank+=10;
}
}
else if(n=='L')
{
if(c2==0)
{
for(;getchar()!='\n';);
return 0;
}
else
{
s[c1][c2]=s[c1][c2-1];
s[c1][c2-1]=' ';
blank-=1;
}
}
else if(n=='R')
{
if(c2==4)
{
for(;getchar()!='\n';);
return 0;
}
else
{
s[c1][c2]=s[c1][c2+1];
s[c1][c2+1]=' ';
blank+=1;
}
}
else
{
for(;getchar()!='\n';);
return 0;
}
}
for(;getchar()!='\n';);
return 1;
}
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
char s[MAX][MAX];
memset(s,'\0',sizeof(s));
int blank, kase=0;
while((blank=read(s))!=-1)
{
if(kase++)
printf("\n");
printf("Puzzle #%d:\n",kase);
if(write(s, blank))
{
for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
printf("%c ",s[i][j]);
printf("%c\n",s[i][4]);
}
continue;
}
else
printf("This puzzle has no final configuration.\n");
}
return 0;
}
In the event that the input contains an invalid move, your write() function consumes the rest of that line of input and returns. But the moves for a given puzzle are explicitly permitted to span multiple lines, so your approach does not necessarily consume all of the remaining moves for the puzzle. If it does not, then you start interpreting the remaining unconsumed moves as the start of the next puzzle. The sample cases do not include such an example.
Related
I was trying to solve Reduce String on codechef which says
Give a string s of length l, and a set S of n sample string(s). We do reduce the string s using the set S by this way:
Wherever Si appears as a consecutive substring of the string s, you can delete (or not) it.
After each deletion, you will get a new string s by joining the part to the left and to the right of the deleted substring.
I wrote a recursive function as follows:-
Basically what i am doing in my code is either don't delete the character or delete it if it is part of any substring but it is giving wrong answer.
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
PS:
link to the question
This question is toughest(seen so far) and most beautiful(again seen so far) question based on DP ON INTERVALS.
The initial code would definitely not work since it only considers single pass on the string and would not consider remaining string after deleting the patterns again and again.
There are 3 cases:-
Case 1 Either character is not deleted.
Case 2It is deleted as a part of contiguous substring.
Case 3It is deleted as a part of subsequence that matches any word given in the set of patterns and everything that is not part of that subsequence is deleted first as a substring(which again belongs to set of words).
The third part is the most tricky and requires enough thinking and is even tougher to implement too.
So for every substring we need to check whether this substring can be completely destroyed or not.
The function compute_full_recur() is the function that ensures that whether substring can be deleted either in Case 2 or Case 3.
The function compute_full takes care of Case 1.And finally this code will not run on codechef link since all the function are recursive with memoization but to verify the code is working i Have run it on Problem Reducto of Hackerrank which is exact similar with lower constraints.Download test cases and then run on test cases on your PC for verifying.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define mx 252
#define nx 40
bool full[mx][mx],vis[mx][mx],full_recur[mx][mx][nx][nx];
int ans[mx];
void init()
{
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
full[i][j]=false,vis[i][j]=false;
}
}
for(int i=0;i<mx;i++)
{
ans[i]=-1;
}
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
for(int k=0;k<nx;k++)
{
for(int l=0;l<nx;l++)
{
full_recur[i][j][k][l]=false;
}
}
}
}
}
bool compute_full_recur(string str,int low,int high,vector<string> pat,int idx,int len)
{
if(low>high&&len==pat[idx].length())
{
return true;
}
if(low>high&&len<pat[idx].length())
{
full_recur[low][high][idx][len]=false;
return false;
}
if(str[low]==pat[idx][len]&&compute_full_recur(str,low+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
for(int i=low+1;i<=high;i++)
{
if(str[low]==pat[idx][len]&&full[low+1][i]&&compute_full_recur(str,i+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
}
full_recur[low][high][idx][len]=false;
return false;
}
void compute_full(string str,int low,int high,vector<string> pats)
{
if(low>high)
{
return;
}
if(vis[low][high])
{
return;
}
vis[low][high]=true;
compute_full(str,low+1,high,pats);
compute_full(str,low,high-1,pats);
for(int i=0;i<pats.size();i++)
{
if(!full[low][high])
full[low][high]=compute_full_recur(str,low,high,pats,i,0);
}
}
int compute_ans(string str,int low,int high)
{
if(low>high)
{
return 0;
}
if(ans[low]!=-1)
{
return ans[low];
}
int sol=1+compute_ans(str,low+1,high);
for(int i=low+1;i<=high;i++)
{
if(full[low][i]==true)
{
sol=min(sol,compute_ans(str,i+1,high));
}
}
return ans[low]=sol;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
vector<string> pats;
cin>>n>>str;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
pats.push_back(tem);
}
init();
compute_full(str,0,str.length()-1,pats);
cout<<compute_ans(str,0,str.length()-1)<<endl;
}
return 0;
}
So my problem is the following: I want to program a basic game of life simulation. Therefore I am using std::vector to save the current state and calculate the next state. All put together in a while(). I am doing std::cout for every value, formated as a matrix. The problem is, that I only get one "matrix" as an output, instead of expected multiple.
I've also tried to output text after calculating the next state (so before and after the nextCells=currentCells), which didn't work, while outputting text within the calculating for() loop works.
I don't know what to do anymore. Appreciate any kind of help!
I've tried to output text after calculating the next state (so before and after the nextCells=currentCells), which didn't work, while outputting text within the calculating for() loop works.
#include <iostream>
#include <vector>
#include <unistd.h>
#define DIMX 10
#define DIMY 10
int countCells(std::vector<std::vector<int>> currentGrid, int x, int y);
int main() {
std::vector<std::vector<int>> currentCells(DIMX, std::vector<int>(DIMY));
std::vector<std::vector<int>> nextCells(DIMX, std::vector<int>(DIMY));
int count = 0;
nextCells = currentCells;
while(true) {
count++;
for(int i=0;i<=DIMX-1;i++) {
for(int j=0;j<=DIMY-1;j++) {
std::cout << currentCells[i][j];
std::cout.flush();
}
std::cout << "\n";
}
for(int i=0;i<=DIMX-1;i++) {
for(int j=0;j<=DIMY-1;j++) {
int aliveCells = countCells(currentCells, i, j);
if(currentCells[i][j]==0) {
if(aliveCells==3) {
nextCells[i][j]=1;
} else {
nextCells[i][j]=0;
}
} else {
if(aliveCells>3) {
nextCells[i][j]=0;
} else if(aliveCells<2) {
nextCells[i][j]=0;
} else {
nextCells[i][j]=1;
}
}
}
}
currentCells = nextCells;
if(count>=5) {
return 0;
}
}
}
int countCells(std::vector<std::vector<int>> currentGrid, int x, int y) {
int aliveCounter;
if(x==DIMX || x==0 || y==DIMY || y==0) {
return 0;
}
if(currentGrid[x-1][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x-1][y]==1) {
aliveCounter++;
} else if(currentGrid[x-1][y+1]==1) {
aliveCounter++;
} else if(currentGrid[x][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x][y+1]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y-1]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y]==1) {
aliveCounter++;
} else if(currentGrid[x+1][y+1]==1) {
aliveCounter++;
}
return aliveCounter;
}
Your code produces an out of vector-range exception, For optimization reasons the exception may not throw in release mode.
When countCells gets called for y = 9 or x = 9
currentGrid[x+1][y+1]
is out of range.
Notice that
v = std::vector<int>(10,0) can be called from v[0] to v[9]; not v[10],
which would be out of range.
I have solved this problem and got AC. My problem is related to equivalence of following two approaches. The first code got accepted, while the second didn't.
As far as I can discern, both are completely equivalent for all the (valid) test cases any human can think of. Am I wrong? If so, what test case can differentiate them?
Code#1 (Accepted one):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
}
bool f = true;
for(int k=0;k<N;k++)
{
f = f && M[k];
}
return f;
}
int main() {
M=new bool[1002];
int num=0;
scanf("%d",&num);
while(num){
int N=0;
scanf("%d",&N);
if(proc(N))
printf("YES\n");
else
printf("NO\n");
num--;
}
return 0;
}
Code #2 (WA):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
else
return false;
}
return true;
}
int main() {
//Exactly same as code#1
}
The bug has nothing to do with the algorithm itself—it's very possible both the algorithms are correct. But the second implementation is wrong.
When you reach a test case which should return NO, you exit the function prematurely. Which means there are some numbers from the current test case left unread in the input, which of course confuses further reading thoroughly. This means the bug only manifests when T > 1.
This code works fine on my machine but when i upload it to codechef it gives me a runtime error SIGSEGV. Can anyone please point out the error in my code? This is the question i made it for http://www.codechef.com/problems/ONP/
#include<iostream>
#include<string>
using namespace std;
class stack
{
public:
void push(char a)
{
++top;
arr[top]=a;
}
void pop()
{
top--;
}
void initialize(int size)
{
top=-1;
max=size;
}
bool chckfull()
{
return (top==max-1);
}
bool chckempty()
{
return (top==-1);
}
char front()
{
return arr[top];
}
private:
int top;
int max;
char arr[404];
};
int chckalphanum(char y)
{
if((y>='a')&&(y<='z'))
return 1;
else if ((y>='A')&&(y<'Z'))
return 1;
else if((y>='0')&&(y<='9'))
return 1;
return 0;
}
int pre(char x)
{
if(chckalphanum(x))
return 0;
if(x=='(')
return -1;
else if(x=='^')
return 3;
else if((x=='/')||(x=='*'))
return 2;
else
return 1;
}
int main ()
{
std::ios::sync_with_stdio(false);
string s, s1=")";
char q[404];
int qmax=0,t;
stack prs;
scanf("%d", &t);
while(t--)
{
cin>>s;
prs.initialize(s.length());
prs.push('(');
s=s+s1;
for(int i=0; i<s.length(); i++)
{
if(s[i]=='(')
prs.push('(');
else if(chckalphanum(s[i]))
{
q[qmax]=s[i];
qmax++;
}
else if(s[i]==')')
{
while(prs.front()!='(')
{
q[qmax]=prs.front();
qmax++;
prs.pop();
}
prs.pop();
}
else
{
while(pre(prs.front())>=pre(s[i]))
{
q[qmax]=prs.front();
qmax++;
prs.pop();
}
prs.push(s[i]);
}
}
for(int i=0; i<qmax; i++)
cout<<q[i];
cout<<"\n";
qmax=0;
}
return 0;
}
I just commented out the below line from your solution and it got accepted in codechef.
std::ios::sync_with_stdio(false);
I am not sure if you are aware of what the above line does but I will try to explain to the best of my knowledge. Better answers will definitely follow in due course from the community.
"With stdio synchronization turned off, iostream standard stream objects may operate independently of the standard C streams (although they are not required to), and mixing operations may result in unexpectedly interleaved characters."
Quoting from cppreference.
"Concurrent access to the same stream object may cause data races."
Since you have turned off the synchronization between stdio (C style I/O) and iostream (C++ style I/O)
and you continued using scanf and cin simultaneously interleaved, I suspect you got a runtime error.
For more research, please go through : http://www.cplusplus.com/reference/ios/ios_base/sync_with_stdio/
Hope it clarifies a bit, if not fully. Thanks!
I am trying to break out of several nested while loops and I am having trouble. I want this program to break out into the outer loop, which will run only a certain amount of times. I tried doing it with a boolean but my program terminates too early. It is an N-Queens problem where I am solving for 1x1, 2x2, 3x3,...nxn queens.
Here is my code:
bool ok(int *q, int col)
{
for(int i=0; i<col; i++)
if(q[col]==q[i] || (col-i)==abs(q[col]-q[i])) return false;
return true;
};
void print(int q[], int n, int cnt)
{
//static int count =0;
cout<<"There are "<<cnt<<" solutions for "<<n<<" queens." <<endl;
};
int main()
{
int n;
int *q;
cout<<"Please enter the size of the board:"<<endl;
cin>>n;
int static count = 0;
int c = 1;
int a = 1;
bool from_backtrack=false;
while(a!=n){
q= new int[a];
q[0]=0;
bool foundSolution=true;
while(foundSolution)
{
if (c==a){
a++;
}
while(c<a)
{
if(!from_backtrack)
q[c] = -1; //Start at the top
from_backtrack=false;
while(q[c]<a)
{
q[c]++;
if (q[c]==a)
{
c--;
if(c==-1) {
print(q, n, count);
foundSolution=false;
//system("PAUSE"); exit(1);
}
continue;
}
if( ok(q,c) ) break; //get out of the closest while loop
}
c++;
}
count++;
c--;
if(c==-1) {
print(q, n, count);
foundSolution=false;
//system("PAUSE"); exit(1);
}
from_backtrack=true;
}
delete[a] q;
a++;
}
system("PAUSE");
}
The most elegant way would be to wrap some of your inner loops in a function.
It will be easier to read and to control.
At my work, we employ MISRA guidelines which state "... only 1 break per while loop". This has caused me to rewrite my if and while loops:
bool can_continue = true;
if (can_continue)
{
status = Do_Something();
if (status != SUCCESS)
{
can_continue = false;
}
}
if (can_continue)
{
status = Do_Another_Thing();
can_continue = status == SUCCESS;
}
//.. and so on.
The idea is to set a flag to "false" if execution can't continue. Check it after any segment can cause execution to fail.
while( true ){
if( condition == true ){
goto bye;
}
}
:bye
Just don't submit this on your homework...
Think it is as crazy as useless.
However, suppose you want 3 iterations, you'll define an array of bool of 3 elements (all set to true). On each iteration you set the current element to false, until you reach the end of your array.