How to break out of a while loop with a boolean? - c++

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.

Related

Difference between flow of if....if block and if....else block

So I was just solving this question the previous day
https://leetcode.com/problems/search-a-2d-matrix-ii/
I was able to solve the problem....but was confused in the execution of if...else block vs if...if block.
The if...else block didn't give me any error while the if....if block gave me an error of IndexOutOfBoundException for length = 1.
Can someone please tell me what's the difference in Layman's term and what am I doing wrong here?
Here is my code ---->
class Solution {
public boolean searchMatrix(int[][] m, int target) {
int x =m.length;
int n= m[0].length;
int i = 0 , j=n-1;
while(i<x && j>=0){
if(m[i][j]==target){
return true;
}
if(m[i][j]>target){
j--;
}
if(m[i][j]<target) {
i++;
}
}
return false;
}
}
************************************* VS ******************************************
class Solution {
public boolean searchMatrix(int[][] m, int target) {
int x =m.length;
int n= m[0].length;
int i = 0 , j=n-1;
while(i<x && j>=0){
if(m[i][j]==target){
return true;
}
if(m[i][j]>target){
j--;
}
else {
i++;
}
}
return false;
}
}
One issue is that this can take you off the bottom of your matrix if j=0.
if(m[i][j]>target){
j--;
}
if(m[i][j]<target) {
i++;
Let's say m[3][0] > target, and you subtract 1 from j, giving j=-1. In your if-else solution, the else is skipped, the while loop then sees that j<0, and the loop exits. Fine.
But in your if-if solution, it then executes if(m[3][-1]<target), which causes the IndexOutOfBoundException
There may be other scenarios too - I haven't checked.

why doesnt the bool function return false?

I'm soo sorry I searched for and read similar questions but couldn't understand/use them to solve my own.
Im writing a bool function within an if statement but the function doesn't seem to return false, what am I doing wrong.
My bool function just checks if there are more than one of the given number in an array:
bool findsame(int a[], int b){
int k=0;
for(int i=0;i<20;i++){
if(a[i]==b){
k++;
}
}
if(k>1){
return true;
}
else{
return false;
}
}
int main()
{
const int size=20;
int a[size]={4,4};
int b=4;
if(findsame(a,b)){
cout<<"true";
}
}
I think you got confused why "false" is not getting printed on console with the function returning the false value.
You need to add to an extra else statement to print false on the console:
if(findsame(a,b)){
std::cout<<"true";
}else{
std::cout<<"false";
}
Also, there are two 4 values in the array, therefore always true will get printed.
Try passing value of b other than 4 and 0.
Have a look at the following implementation where value of variable b is equal to 1:
#include<iostream>
bool findsame(int a[], int b){
int k=0;
for(int i=0;i<20;i++){
if(a[i]==b){
k++;
}
}
if(k>1){
return true;
}
else{
return false;
}
}
int main()
{
const int size=20;
int a[size]={4,4};
int b=1;
if(findsame(a,b)){
std::cout<<"true";
}else{
std::cout<<"false";
}
}
Output:
false
PS: I have also tested code for the value of b = 4 and it prints true. Check and Run the code here: https://onlinegdb.com/S1LR5PtvD

Code only outputs std::vector one time instead of wanted multiple times

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.

UVa 227 (Puzzle) Wrong Answer Despite Passing All Provided Test Cases

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.

SPOJ: What is the difference between these two answers for KURUK14

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.