So I am writing a sudoku solver in C++ and have run into a little snag. Below is my solve board code. It works for the first 3 rows of the puzzle, but unrecurses when hitting the end of the 4th row. Looking at the code on gdb it hits the end of the 4th row, backtracks to 6th column, tries and then unrecurses out to the end.
A couple of other notes about the code is the matrix which holds the sudoku board begins at 1,1 not 0,0. So when solveBoard is initially called the parameters are (1, 1, 0). I have also attached the setCell and checkConflicts functions for more insight on there. I have three vectors rowConf,colConf and squConf to store the values that have already been placed in the respective row, column, or square. I have been at this for hours and cannot get it to go past the 3rd row. Any assistance is greatly appreicated. Thanks!
EDIT: Added clearCell()
bool board::solveBoard(int i, int j, int count)
{
if (j > 9)
{
j = 1;
i++;
printBoard();
if (isSolved())
{
printBoard();
cout <<"The Board has been solved!" <<endl
<<" The number of recursive calls was: " <<count <<endl;
return true;
}
}
if (isBlank(i, j))
{
for (int n = 1; n < 10; n++)
{
if (setCell(i, j, (char)n + '0'))
{
if (solveBoard(i, j + 1, count + 1))
{
return true;
}
}
}
}
else
{
return (solveBoard(i, j + 1, count + 1));
}
clearCell(i, j);
return false;
}
bool board::setCell(int i, int j, char val)
{
int intVal;
intVal = atoi(&val);
if (i >= 1 && i <= BoardSize && j >= 1 && j <= BoardSize &&
intVal >= 1 && intVal <= BoardSize)
{
if (!(checkConflicts(intVal, i, j, squareNumber(i, j))))
{
return false;
}
value[i][j] = intVal;
// Set flags of the conflicts
rowConf[i][intVal] = true;
colConf[j][intVal] = true;
squConf[squareNumber(i, j)][intVal] = true;
return true;
}
else
{
throw rangeError("bad value in setCell");
}
}
bool board::checkConflicts(int val, int i, int j, int k)
{
if (i < 1 && i > BoardSize && j < 1 && j > BoardSize &&
k < 1 && k > BoardSize && val < 1 && val > BoardSize)
{
throw rangeError("bad value in checkConflicts()");
}
if (rowConf[i][val] || colConf[j][val] || squConf[k][val])
{
return false;
}
else
{
return true;
}
}
Initial Board:
-----------------------------
| 3 | 8 | -----------------------------
| | 7 | 5 -----------------------------
| 1 | | -----------------------------
-----------------------------
| | | 3 6 -----------------------------
| 2 | 4 | -----------------------------
| 7 | | -----------------------------
-----------------------------
| | 6 | 1 3 -----------------------------
| 4 5 | 2 | -----------------------------
| | | 8 -----------------------------
-----------------------------
Final Output:
-----------------------------
| 3 2 4 | 1 8 5 | 6 7 9 -----------------------------
| 6 8 9 | 7 2 3 | 4 1 5 -----------------------------
| 1 5 7 | 4 9 6 | 2 8 3 -----------------------------
-----------------------------
| | | 3 6 -----------------------------
| 2 | 4 | -----------------------------
| 7 | | -----------------------------
-----------------------------
| | 6 | 1 3 -----------------------------
| 4 5 | 2 | -----------------------------
| | | 8 -----------------------------
-----------------------------
void board::clearCell(int i, int j)
{
int intVal;
if (i >= 1 && i <= BoardSize && j >= 1 && j <= BoardSize)
{
if (value[i][j] != -1)
{
intVal = value[i][j];
rowConf[i][intVal] = false;
colConf[j][intVal] = false;
squConf[squareNumber(i, j)][intVal] = false;
value[i][j] = -1;
}
}
else
{
throw rangeError("bad value in setCell");
}
}
Your problem is most likely here:
if (isBlank(i, j))
{
for (int n = 1; n < 10; n++)
{
if (setCell(i, j, (char)n + '0'))
{
if (solveBoard(i, j + 1, count + 1))
{
return true;
}
}
}
}
Somehow it is going through this section, which is why it isn't going through the else in the end, but since it hasn't returned before, it gets stuck.
This needs more debugging, but here is an idea that could lead to a solution:
if (isBlank(i, j))
{
for (int n = 1; n < 10; n++)
{
if (setCell(i, j, (char)n + '0'))
{
if (solveBoard(i, j + 1, count + 1))
{
return true;
} else {
echo 'Looks like it ended on the farthest-level..';
}
} else {
echo 'Looks like it ended on the second-farthest level.';
}
}
The atoi function expects a string as an argument, that is an array of chars terminated with character '\0', ASCII NUL. You give a parameter being a pointer to a character (equivalent to some arrray of chars) but do not guarantee it is zero-terminated. Please replace intVal = atoi(&val); with intVal = (int)val - '0';
And your checkConflicts should have || operators instead of && in the first if.
These are probably not reasons of the error but certainly need correction.
Related
I'm making a snake game and having trouble with the tail movement. I understand the logic for this part, which is that each segment of the tail follows the previous segment, starting from the end of the tail. I am looking at someone else's code, and it looks like this
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailx[100], taily[100];
int nTail;
enum eDirecton { Stop, Left, Right, Up, Down } dir;
void Setup()
{
gameOver = false;
dir = Stop;
x = width / 2;
y = height / 2;
fruitX = rand() % width;
fruitY = rand() % height;
score = 0;
}
void Draw()
{
system("cls");
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (j == 0)
cout << "#";
if (i == y && j == x)
cout << "O";
else if (i == fruitY && j == fruitX)
cout << "F";
else
{
bool print = false;
for (int k = 0; k < nTail; k++)
{
if (tailx[k] == j && taily[k] == i)
{
cout << "o";
print = true;
}
}
if (!print)
cout << " ";
}
if (j == width - 1)
cout << "#";
}
cout << endl;
}
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
cout << "Score:" << score << endl;
}
void Input()
{
if (_kbhit())
{
switch (_getch())
{
case 'a':
dir = Left;
break;
case 'd':
dir = Right;
break;
case 'w':
dir = Up;
break;
case 's':
dir = Down;
break;
case 'x':
gameOver = true;
break;
}
}
}
void Logic()
{
for (int i = nTail - 1; i > 0; i--)
{
tailx[i] = tailx[i - 1];
taily[i] = taily[i - 1];
}
tailx[0] = x;
taily[0] = y;
switch (dir)
{
case Left:
x--;
break;
case Right:
x++;
break;
case Up:
y--;
break;
case Down:
y++;
break;
default:
break;
}
if (x >= width) x = 0; else if (x < 0) x = width - 1;
if (y >= height) y = 0; else if (y < 0) y = height - 1;
for (int i = 0; i < nTail; i++)
if (tailx[i] == x && taily[i] == y)
gameOver = true;
if (x == fruitX && y == fruitY)
{
score += 10;
fruitX = rand() % width;
fruitY = rand() % height;
nTail++;
}
}
int main()
{
Setup();
while (!gameOver)
{
Draw();
Input();
Logic();
Sleep(50);
}
return 0;
}
I understand the logic but I don't understand why it works. When we create an array, the value of each element is just a garbage value without initializing each element. So in the code above, when doing
tailx[i] = tailx[i-1];
taily[i] = taily[i-1];
what value is assigned to each element?
When displaying the snake, it has a for loop to go through every coordinate of the screen and inside it has another for loop to compare tailx[i] and taily[i] with each coordinate to find out the right position to print each segment of the tail. Since tailx and tialy are not storing the coordinates of the segments of the tail, how come this code works?
Thank you so much!!
Presumably, you're missing a line at the end that looks something like:
if(nTail < 100) { nTail++; }
Assuming that's the case, nTail is initialized to 0 and that this is all in a loop, the code probably looks something like (I'm using a size of 5 instead of 100 to make visualizing easier)
int tailx[5];
int taily[5];
int nTail = 0; //length
while(true) {
for(int i = nTail -1; i > 0; i--)
{
tailx[i] = tailx[i-1];
taily[i] = taily[i-1];
}
// Let's assume there's some logic here the fetches a new
// x and y. For the sake of debugging, let's assume the
// values will be {(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)}
tailx[0] = x; // x is the x-coordinate of the head
taily[0] = y; //y is the y-coordinate of the head
if(nTail < 5) { nTail++; }
}
Let's step through this!
Before we enter the loop, your tail arrays are going to look like: (I'm using NA here to mean "Garbage")
nTail = 0
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | NA| NA| NA| NA| NA|
+-------------------------+
| Y | NA| NA| NA| NA| NA|
+-------------------------+
We enter the loop, initialize i to nTail - 1 which is -1. This doesn't pass the check of i > 0, so we don't even enter the loop.
We'll now grab new x and y vals and assign them into the tails, along with incrementing nTail. So going into the next loop our variables will look like:
nTail = 1
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 1 | NA| NA| NA| NA|
+-------------------------+
| Y | 1 | NA| NA| NA| NA|
+-------------------------+
We'll head on in, initialize i to nTail - 1 => 0. This DOESN'T pass the check of i > 0, so again we don't enter the loop (which sounds wrong to me...maybe you're initializing nTail to 1 instead of 0?).
We head on down, grab new x/y vals and increment nTail and restart the loop with:
nTail = 2
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 2 | NA| NA| NA| NA|
+-------------------------+
| Y | 2 | NA| NA| NA| NA|
+-------------------------+
Initializing i to nTail - 1 => 1 means since i > 0 we'll finally enter the inner loop.
With i = 1, we update our tail arrays:
tailx[1] = tailx[0];
taily[1] = taily[0];
Then head down, grab new values and increment nTail. Our variables now look like:
nTail = 3
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 3 | 2 | NA| NA| NA|
+-------------------------+
| Y | 3 | 2 | NA| NA| NA|
+-------------------------+
After the next loop, things will look like:
nTail = 4
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 4 | 3 | 2 | NA| NA|
+-------------------------+
| Y | 4 | 3 | 2 | NA| NA|
+-------------------------+
I'll leave it to you to keep tracing if you so desire.
You're right; this code cannot work, and it has undefined behaviour.
nTail isn't even initialised to anything.
Are you sure it's a full program, and not just snippets glued together? Or a sort of "pseudocode" to show the logic without being actual valid C++? You'd need values for nTail and all the array elements.
First of all, I'm pretty new to C++ so try not to be too harsh on me. I wrote this block of code:
int LargestProduct (string numStr, int groupSize) {
int numOfGroups = numStr.size() / groupSize;
int groupsRemaining = numStr.size() % groupSize;
int largestProduct = 0, thisProduct = 1;
for (int i = 1; i <= numOfGroups; i++) {
for (int j = i; j <= groupSize; j++)
thisProduct *= (numStr[j-1] - '0');
if (thisProduct > largestProduct)
largestProduct = thisProduct;
thisProduct = 1;
}
// .. A bit more irrelevant code here
return largestProduct;
}
The function call LargestProduct ("1234567890", 2) should yield 72, but it wrongly yields 6. So, for some reason, this code will work but not as expected (Note: this code I wrote should compute the largest product of groupsSize-adjacent numbers in a big, given number called numStr).
I did some debugging, and found a strange behaviour in the nested for-loop. I set up a breakpoint inside the second for-loop
thisProduct *= (numStr[j] - '0');
After some iterations (for example, 8 iterations), this is what I would expect i and j to be:
+--------+---------+
| i | j |
+--------+---------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
| 3 | 2 |
| 4 | 1 |
| 4 | 2 |
+--------+---------+
This is what really happens:
+--------+---------+
| i | j |
+--------+---------+
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
+--------+---------+
And suddenly the program spits out a wrong result (6, instead of 72)
But this seems counterintuitive, to say the least. The variable i goes from 0 to numOfGroups, which in the example above equals 5. On the other hand, j goes from i to groupSize, which happens to be 2.
There should be 5*2 = 10 iterations, but there are only 3 of them. Also, in the last iteration, j should be "re-initialized" to 0. This doesn't happen though.
Anyone please help this C++ newbie?
EDIT
The problem was that the j-for-loop ranged from a moving index (i) to a non-moving index(groupSize). This was causing that "shrinking" effect in the second for-loop, which is easily fixed by changing this line:
for (int j = i; j <= groupSize; j++)
To this other one:
for (int j = i; j <= i + groupSize - 1; j++)
And to make the full algorithm to work as expected, one should also replace these lines:
int numOfGroups = numStr.size() / groupSize;
int groupsRemaining = numStr.size() % groupSize;
with this single one:
int numOfGroups = numStr.size() - 1;
EDIT 2
Everything is OK now, thank you for your kindness guys! I appreciate it. The whole code is:
int LargestProduct (string numStr, int groupSize) {
int numOfGroups = numStr.size() - 1;
int largestProduct = 0, thisProduct = 1;
for (int i = 1; i <= numOfGroups; i++) {
for (int j = i; j <= i + groupSize - 1; j++)
thisProduct *= (numStr[j-1] - '0');
if (thisProduct > largestProduct)
largestProduct = thisProduct;
thisProduct = 1;
}
return largestProduct;
}
You said:
On the other hand, j goes from 0 to groupSize
But the code says:
for (int j = i; j <= groupSize; j++)
This means j is going from i to groupSize, not 0 to groupSize
My code is as follows. My confusion occurs during the 2nd and 3rd loop. Why does the result return 1*** then 12** then 123* then 1234.. I get the j loop is reset to 0 but doesn't it reenter the k loop whenever its true that j<=i?
for(int i = 1; i <= 4; i++)
{
for(int j = 1; j <= i; j++)
cout << j;
for(int k = 4 - i; k >= 1; k--)
cout << "*";
cout << endl;
}
Some clarification first:
Firstly: j is never reset to 0, but to 1.
Secondly: This is imho no triple-nested for-loop, which was be (but is not needed to have your code working as you describe it):
for(...) {
for(...) {
for(...) {
}
}
}
To your confusion:
Pretty printing your code:
for(int i=1; i<=4; i++) {
// Write the digits 1..i (1, 12, 123, 1234)
for(int j=1; j<=i; j++) {
std::cout << j;
}
// Write the stars (***, **, *)
for(int k=(4-i); k>=1; k--) {
std::cout << "*";
}
std::cout << std::endl;
}
Imagine the following sequences:
// Iteration | i | j | k | String
// 1 | 1 | 1 | 3 | 1*
// 2 | 1 | 1 | 2 | 1**
// 3 | 1 | 1 | 1 | 1***\n
// 4 | 2 | 1 | - | 1
// 5 | 2 | 2 | - | 12
// 6 | 2 | 2 | 2 | 12*
// 7 | 2 | 2 | 1 | 12**\n
// 8 | 3 | 1 | - | 1
// 9 | 3 | 2 | - | 12
// 10 | 3 | 3 | - | 123
// 11 | 3 | 3 | 1 | 123*\n
// 12 | 4 | 1 | - | 1
// 13 | 4 | 2 | - | 12
// 14 | 4 | 3 | - | 123
// 15 | 4 | 4 | - | 1234\n
The k-loop is reentered, if the initial index:
// k:=(4-i) >= 1
So entering the k-Loop is exclusively dependent on the index i.
Mathematically:
// (4-i) >= 1
// <=> -i >= (1-3)
// <=> -i >= -3
// <=> i <= 3
So the k-loop is reentered, as long as i is <= 3.
In order to get the effect you want your code should be like this:
for(int i = 1; i <= 4; i++)
{
for(int j = 1; j <= i; j++)
{
cout << j;
for(int k = 4 - i; k >= 1; k--)
cout << "*";
}
cout << endl;
}
if you dont have the {} the k loop is executed only after finishing the j loop
I need to remove as many if conditions as possible from the two functions below:
inline int inc_with_1bit_saturation(int counter)
{
if (counter == 1)
return --counter;
return ++counter;
}
void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
int counter = 0;
for (int i = 0; i < size; ++i)
{
if (input[i] != counter)
{
counter = inc_with_1bit_saturation(counter);
output[i] = 0;
}
else output[i] = 1;
}
}
How can I do that and what if branch is absolutely necessary and cannot be removed and which one can be replaced by simple bitwise operations or something like that?
Update 1
According to User JSF's great tip, the code is now looking like this:
void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
int counter = 0;
for (int i = 0; i < size; ++i)
{
if (input[i] != counter)
{
counter = 1 - counter;
output[i] = 0;
}
else output[i] = 1;
}
}
Update 2
Thanks to Cantfindname, the code became like this:
void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
int counter = 0;
for (int i = 0; i < size; ++i)
{
output[i] = counter == input[i];
counter = output[i] * counter + (1 - output[i])*(1 - counter);
}
}
And this completely solves the question.
For the if statement inside the loop:
output[i] = (int)(input[i]==counter);
counter = output[i]*counter + (1-output[i])*(1-counter) //used JSF's trick
True converts to 1 and false to 0, according to this: bool to int conversion
function inc_with_1bit_saturation is equivalent of modulo 2. So you can replace
counter = inc_with_1bit_saturation(counter);
With
counter = (counter+1) % 2;
void branch_prediction_1bit_saturation(int* input, int* output, int size) {
int counter = 0;
for (int i = 0; i < size; ++i)
{
output[i] = (int)!((!!input[i]) ^ counter);
counter = (int)((!!input[i]) & counter) | ((!!input[i]) & !counter);
}
}
A is logic input[i];
B is logic counter;
The truth table for input[i] != counter is:
A B
0 0 | 0 --> (0 & 0) | (0 & !0) = 0 | 0 = 0
0 1 | 0 --> (0 & 1) | (0 & !1) = 0 | 0 = 0
1 0 | 1 --> (1 & 0) | (1 & !0) = 0 | 1 = 1
1 1 | 1 --> (1 & 1) | (1 & !1) = 1 | 0 = 1
The truth table for output[i]
A B
0 0 | 1 --> !(0 ^ 0) = !(0) = 1
0 1 | 0 --> !(0 ^ 1) = !(1) = 0
1 0 | 0 --> !(1 ^ 0) = !(1) = 0
1 1 | 1 --> !(1 ^ 1) = !(0) = 1
:)
I'm looking for an explanation for how the recursive version of pascal's triangle works
The following is the recursive return line for pascal's triangle.
int get_pascal(const int row_no,const int col_no)
{
if (row_no == 0)
{
return 1;
}
else if (row_no == 1)
{
return 1;
}
else if (col_no == 0)
{
return 1;
}
else if (col_no == row_no)
{
return 1;
}
else
{
return(get_pascal(row_no-1,col_no-1)+get_pascal(row_no-1,col_no));
}
}
I get how the algorithm works
What I wonder is how the recursion does the work.
Your algorithm contains a couple of unnecessary predicates for the base cases. It can be stated more simply as follows:
int pascal(int row, int col) {
if (col == 0 || col == row) {
return 1;
} else {
return pascal(row - 1, col - 1) + pascal(row - 1, col);
}
}
This of course assumes that you're guaranteeing that the arguments passed to the function are non-negative integers; you can always include an assertion if you can't impose such a guarantee from outside the function.
Pascal's triangle is essentially the sum of the two values immediately above it....
1
1 1
1 2 1
1 3 3 1
etc
In this, the 1's are obtained by adding the 1 above it with the blank space (0)
For code, all the 1's are occupied in either the first column (0), or when the (col == row)
For these two border conditions, we code in special cases (for initialization). The main chunk of the code (the recursive part) is the actual logic.
(The condition 'row == 1' is not necessary)
The most optimized way is this one:
int pascal(int row, int col) {
if (col == 0 || col == row) return 1;
else if(col == 1 || (col + 1) == row) return row;
else return pascal(row - 1, col - 1) + pascal(row - 1, col);
}
Unlike Fox's algorithm it prevents recursive calls for values which can be easily computed right from the input values.
Refer to the page for the source code:
#include <stdio.h>
int main()
{
int n, x, y, c, q;
printf("Pascal Triangle Program\n");
printf("Enter the number of rows: ");
scanf("%d",&n);
for (y = 0; y < n; y++)
{
c = 1;
for(q = 0; q < n - y; q++)
{
printf("%3s", " ");
}
for (x = 0; x <= y; x++)
{
printf(" %3d ",c);
c = c * (y - x) / (x + 1);
}
printf("\n");
}
printf("\n");
return 0;
}
The output would be,
Pascal Triangle Program
Enter the number of rows: 11
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
Pascal's triangle can be got from adding the two entries above the current one.
| 0 1 2 3 column
--+----------------------------------------------
0 | 1 (case 1)
1 | 1 (case 2) 1 (case 2)
2 | 1 (case 3) 2 (sum) 1 (case 4)
3 | 1 (case 3) 3 (sum) 3 (sum) 1 (case 4)
row
etc., for example column 2, row 3 = column 2, row 2 + column 1, row 2, where the cases are as follows:
if (row_no == 0) // case 1
{
return 1;
}
else if (row_no == 1) // case 2
{
return 1;
}
else if (col_no == 0) // case 3
{
return 1;
}
else if (col_no == row_no) // case 4
{
return 1;
}
else // return the sum
return pascalRecursive(height-1,width)+pascalRecursive(height-1,width-1);
Here is the code of #kathir-softwareandfinance
with more readable and more meaning variable names
#include <stdio.h>
int main()
{
int nOfRows, cols, rows, value, nOfSpace;
printf("Pascal Triangle Program\n");
printf("Enter the number of rows: ");
scanf("%d",&nOfRows);
for (rows = 0; rows < nOfRows; rows++)
{
value = 1;
for(nOfSpace = 0; nOfSpace < nOfRows - rows; nOfSpace++)
{
printf("%3s", " ");
}
for (cols = 0; cols <= rows; cols++)
{
printf(" %3d ",value);
value = value * (rows - cols) / (cols + 1);
}
printf("\n");
}
printf("\n");
return 0;
}
Here is how the recursion works
We call v(i, j), it calls v(i - 1, j), which calls v(i - 2, j) and so on,
until we reach the values that are already calculated (if you do caching),
or the i and j that are on the border of our triangle.
Then it goes back up eventually to v(i - 1, j), which now calls v(i - 2, j - 1),
which goes all the way to the bottom again, and so on.
....................................................................
_ _ _ _ call v(i, j) _ _ _ _ _
/ \
/ \
/ \
call v(i - 1, j) v(i - 1, j - 1)
/ \ / \
/ \ / \
call v(i - 2, j) v(i - 2, j - 1) v(i - 2, j - 1) v(i - 2, j - 2)
....................................................................
If you need to get the value often, and if you have enough memory:
class PascalTriangle
# unlimited size cache
public
def initialize
#triangle = Array.new
end
def value(i, j)
triangle_at(i, j)
end
private
def triangle_at(i, j)
if i < j
return nil
end
if #triangle[i].nil?
#triangle[i] = Array.new(i + 1)
else
return #triangle[i][j]
end
if (i == 0 || j == 0 || i == j)
#triangle[i][j] = 1
return #triangle[i][j]
end
#triangle[i][j] = triangle_at(i - 1, j) + triangle_at(i - 1, j - 1)
end
end
Using ternary approach for optimization; only 1 return command needed.
int f(int i, int j) {
return (
(i <= 1 || !j || j == i) ? 1 :
(f(i - 1, j - 1) + f(i - 1, j))
);
}
see explanation