How is uncommenting a cout line changing the final answer? - c++

I have the following code
#include <bits/stdc++.h>
using namespace std;
int main() {
int r = 0, c = 0;
int best = 0;
cin >> r >> c;
int myGrid[r + 2][c + 2] = {};
for (int i = 1; i < r + 1; i++) {
for (int j = 1; j < c + 1; j++) {
cin >> myGrid[i][j];
}
}
bool stillIn = false;
int di[] = {-1,-1, -1, 0, 0, 1, 1, 1};
int dj[] = {-1,0, 1, -1, 1, -1, 0, 1};
for (int i = 1; i < r + 1; i++) {
for (int J = 1; J < c + 1; J++) {
stillIn = false;
for (int k = 0; k < 8; k++) {
// cout << myGrid[i][J] << " " << endl;
if (myGrid[i][J] == myGrid[di[k]][dj[k]]) {
stillIn = true;
}
}
if (stillIn == true) {
best = myGrid[i][J];
}
}
}
cout << best;
return 0;
}
If I run the code with the following input:
4 3
0 1 0
1 2 0
1 5 1
2 3 4
It prints 4. However, if I uncomment line 28, which is
// cout << myGrid[i][J] << " " << endl;
Then it gives me 1, which is the correct answer. Why is this happening!? How does using cout change the final answer?
Thanks in advance for any help.

You have undefined behavior(UB) because you are indexing out of bounds on this line
myGrid[di[k]][dj[k]]
because di and dj contain values of -1.
If you have UB, then anything can happen, such as a cout statement exisiting or not, changing the program in weird ways.
Also variable length arrays are not allowed in standard c++.

Related

Error when traversing the matrix in a spiral, starting from the central element [duplicate]

This question already has answers here:
Print 2-D Array in clockwise expanding spiral from center
(4 answers)
Closed 2 years ago.
What is the error in the loops. For example, with a 4x4 matrix, starting at element 13 of the array new_matrix[13] gives incorrect values. With other dimensions matrices the same error.
int *helix_center (int** matrix, int size) {
int* new_matrix = new int[size * size];
int count = 0;
int step = 1;
int sup_var = size / 2;
int sup_var_2 = sup_var;
new_matrix[count] = matrix[sup_var][sup_var_2];
count++;
while( step < size ) {
for (int j = 0; ((j < step) && (step < size)); j++) {
if (sup_var_2 != 0)
new_matrix[count] = matrix[sup_var][--sup_var_2];
count++;
}
for (int j = 0; ((j < step) && (step < size)); j++) {
if(sup_var != 0)
new_matrix[count] = matrix[--sup_var][sup_var_2];
count++;
}
step++;
for (int j = 0; ((j < step) && (step < size)); j++) {
new_matrix[count] = matrix[sup_var][++sup_var_2];
count++;
}
for (int j = 0; ((j < step) && (step < size)); j++) {
new_matrix[count] = matrix[++sup_var][sup_var_2];
count++;
}
step++;
}
return new_matrix;
}
Tried to reproduce it, added some simple main with additional prints:
#include <iostream>
int* helix_center(int matrix[4][4], int size)
{
int* new_matrix = new int[size * size];
int count = 0;
int step = 1;
int sup_var = size / 2;
int sup_var_2 = sup_var;
new_matrix[count] = matrix[sup_var][sup_var_2];
std::cout << count << std::endl;
count++;
while (step < size) {
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
if (sup_var_2 != 0)
new_matrix[count] = matrix[sup_var][--sup_var_2];
count++;
}
std::cout << "=====" << std::endl;
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
if (sup_var != 0)
new_matrix[count] = matrix[--sup_var][sup_var_2];
count++;
}
std::cout << "=====" << std::endl;
step++;
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
new_matrix[count] = matrix[sup_var][++sup_var_2];
count++;
}
std::cout << "=====" << std::endl;
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
new_matrix[count] = matrix[++sup_var][sup_var_2];
count++;
}
step++;
}
return new_matrix;
}
int main()
{
int matrix[4][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
int* output = helix_center(matrix, 4);
std::cout << output[13] << std::endl;
return 0;
}
Code yields the following:
0
1
=====
2
=====
3
4
=====
5
6
7
8
9
=====
10
11
12
=====
=====
1414422387
So, as you can see, we never go past 12, thus these indices are not being initialized. Quite a lot going on in your code, kinda hard to track counter's changes.
Here's a great implementation of what you're trying to do:
https://stackoverflow.com/a/33701500/5430833
Tweaked it a bit so instead of printing, it puts values to the output buffer:
#include <iostream>
#include <cmath>
#include <vector>
int* print_spiral (int** matrix, int size)
{
int* new_matrix = new int[size * size];
int x = 0; // current position; x
int y = 0; // current position; y
int d = 0; // current direction; 0=RIGHT, 1=DOWN, 2=LEFT, 3=UP
int c = 0; // counter
int s = 1; // chain size
// starting point
x = ((int)floor(size/2.0))-1;
y = ((int)floor(size/2.0))-1;
for (int k=1; k<=(size-1); k++)
{
for (int j=0; j<(k<(size-1)?2:3); j++)
{
for (int i=0; i<s; i++)
{
new_matrix[c] = matrix[x][y];
c++;
switch (d)
{
case 0: y = y + 1; break;
case 1: x = x + 1; break;
case 2: y = y - 1; break;
case 3: x = x - 1; break;
}
}
d = (d+1)%4;
}
s = s + 1;
}
return new_matrix;
}
int main()
{
std::vector<std::vector<int>> v{ { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
int **p = new int *[v.size()];
for ( size_t i = 0; i < v.size(); i++ ) p[i] = v[i].data();
int* output = print_spiral(p, 4);
for(int i = 0; i < 16; i++) {
std::cout << output[i] << std::endl;
}
return 0;
}
Which yields the following:
6
7
11
10
9
5
1
2
3
4
8
12
16
15
14
0
Which is what you expect, I believe.

Knight tour all answers in c++

For knight tour problem, I came up with this answer; however, it just prints one answer. I don't know how to print all answers. I know I should change the output of find tour into void to avoid finishing but I don't know how. Can anyone modify it?
#include <iostream>
using namespace std;
const int ROW_COUNT = 6;
const int COL_COUNT = 6;
const int POSSIBLE_MOVES = 8;
int row_delta[POSSIBLE_MOVES] = {2, 1, -1, -2, -2, -1, 1, 2};
int col_delta[POSSIBLE_MOVES] = {-1, -2, -2, -1, 1, 2, 2, 1};
int board[ROW_COUNT][COL_COUNT];
void print_board() {
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COL_COUNT; j++) {
if (board[i][j] < 10)
cout << ' ';
cout << board[i][j] << ' ';
}
cout << endl;
}
cin.get();
}
bool find_tour(int move_no, int current_row, int current_col) {
// uncomment the following two lines for debugging:
//cout << move_no << endl;
//print_board();
if (move_no == ROW_COUNT * COL_COUNT)
return true;
for (int move = 0; move < POSSIBLE_MOVES; move++) {
int new_row = current_row + row_delta[move];
int new_col = current_col + col_delta[move];
if (new_row < 0 || new_row >= ROW_COUNT || new_col < 0 || new_col >= COL_COUNT)
continue;
if (board[new_row][new_col] != 0)
continue;
board[new_row][new_col] = move_no + 1;
if (find_tour(move_no + 1, new_row, new_col))
return true;
board[new_row][new_col] = 0;
}
return false;
}
void solve(int init_row, int init_col) {
for (int row = 0; row < ROW_COUNT; row++)
for (int col = 0; col < COL_COUNT; col++)
board[row][col] = 0;
board[init_row][init_col] = 1;
if (find_tour(1, init_row, init_col))
print_board();
else
cout << "Failed to find a tour!\n";
}
int main() {
solve(2, 3);
}
Following from my comment, this code should work:
#include <iostream>
using namespace std;
const int ROW_COUNT = 6;
const int COL_COUNT = 6;
const int POSSIBLE_MOVES = 8;
int row_delta[POSSIBLE_MOVES] = {2, 1, -1, -2, -2, -1, 1, 2};
int col_delta[POSSIBLE_MOVES] = {-1, -2, -2, -1, 1, 2, 2, 1};
int board[ROW_COUNT][COL_COUNT];
void print_board() {
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COL_COUNT; j++) {
if (board[i][j] < 10)
cout << ' ';
cout << board[i][j] << ' ';
}
cout << endl;
}
cin.get();
}
find_tour(int move_no, int current_row, int current_col) {
// uncomment the following two lines for debugging:
//cout << move_no << endl;
//print_board();
if (move_no == ROW_COUNT * COL_COUNT)
{
print_board();
return;
}
for (int move = 0; move < POSSIBLE_MOVES; move++) {
int new_row = current_row + row_delta[move];
int new_col = current_col + col_delta[move];
if (new_row < 0 || new_row >= ROW_COUNT || new_col < 0 || new_col >= COL_COUNT)
continue;
if (board[new_row][new_col] != 0)
continue;
board[new_row][new_col] = move_no + 1;
find_tour(move_no + 1, new_row, new_col);
board[new_row][new_col] = 0;
}
}
void solve(int init_row, int init_col) {
for (int row = 0; row < ROW_COUNT; row++)
for (int col = 0; col < COL_COUNT; col++)
board[row][col] = 0;
board[init_row][init_col] = 1;
find_tour(1, init_row, init_col);
}
int main() {
solve(2, 3);
}

Character / int equality evaluating incorrectly

Background info: I'm writing a C++ program to solve sudoku puzzles, and I've hit a major road block. The general flow of the program is like this:
Iterate through the grid and check if a 0 can be replaced with a number. (blanks are represented by 0s)
Check in 3 dimensions (vertical, horizontal, and in the box) which numbers are already there.
Determine if we can narrow that number down to one possibility, replace it, then move on.
Repeat until grid has no zeros
I'm running into issues at the second step, I'll post the whole program at the bottom, but only relevant code here.
int* check_v(string g, size_t x, size_t y){
int *ans = new int[9]; //array of possible ints
memset(ans, 0, sizeof(ans)); //set array to all 0s
size_t size = 0;
for(int i = 1; i < 10; i++){ //iterate through 1-10
//check if i is in the col, if it isn't then add i to ans
bool placeable = true;
for(size_t j = 0; j < 9; j++){ //iterate through ints in the col
size_t r = (j + x) % 9; //the string is a 9x9 grid of numbers
cout << get(g,r,y) << " == " << i << " is " << (get(g,r,y) - 0 == i - 0);
//this is my debug statement, because the if below isn't working.
if(get(g,r,y) - 0 == i - 0){ //if i is equal to a num in the grid,
placeable = false;//we know it can't be that number
}
}
if(placeable) ans[size++] = i; //only add i if we didn't find it in the grid
}
return ans;
}
This is one of the methods that checks the column for each number to see what numbers are/aren't there yet.
Here's the relevant get() method:
char get(string g, size_t x, size_t y){
return g.at(x * 9 + y);
}
Where g is a string of numbers 0-9 81 letters long. It's a 9x9 grid, but put into one long string.
So the get(g,r,y) returns a char like '6', and i is an int. I do '6' - 0 to make them both ints, and compare them. However, it's always false! Even when i = 6 and get(g,r,y) = '6'. Am I doing my comparisons wrong? I must have a typo somewhere and I just don't see it. Here's some sample output from that cout call, and I'll post the whole file for context.
//output
0 == 1 is 0
3 == 1 is 0
8 == 1 is 0
2 == 1 is 0
5 == 1 is 0
7 == 1 is 0
4 == 1 is 0
9 == 1 is 0
6 == 1 is 0 //this is all right, there aren't any 1s in the col
0 == 2 is 0
3 == 2 is 0
8 == 2 is 0
2 == 2 is 0 //but this is wrong! why isn't this true?
5 == 2 is 0
7 == 2 is 0
4 == 2 is 0
9 == 2 is 0
6 == 2 is 0
Now here's the entire file to give you the whole picture.
using namespace std;
#include <iostream>
#include <cstring>
void print(string g){
for(size_t i = 0; i < 9; i++){
for(size_t j = 0; j < 9; j++){
cout << g.at(i * 9 + j);
}
cout << endl;
}
}
void set(string & g, size_t x, size_t y, char z){
size_t i = x * 9 + y;
string beg = g.substr(0,i);
string end = g.substr(i+1,g.length());
g = beg + z + end;
}
char get(string g, size_t x, size_t y){
return g.at(x * 9 + y);
}
int* check_v(string g, size_t x, size_t y){
int *ans = new int[9];
memset(ans, 0, sizeof(ans));
size_t size = 0;
for(int i = 1; i < 10; i++){
bool placeable = true;
for(size_t j = 0; j < 9; j++){
size_t r = (j + x) % 9;
cout << get(g,r,y) << " == " << i << " is " << (get(g,r,y) - 0 == i - 0) << endl;
if(get(g,r,y) - 0 == i - 0){
placeable = false;
}
}
if(placeable) ans[size++] = i;
}
return ans;
}
int* check_b(string g, size_t x, size_t y){
int *ans = new int[9];
memset(ans, 0, sizeof(ans));
size_t size = 0;
x = x / 3 * 3;
y = y / 3 * 3;
for(size_t i = 0; i < 3; i++){
bool placeable = true;
for(size_t j = 0; j < 3; j++)
if(get(g,x + i, y + j) == static_cast<char>(i))
placeable = false;
if(placeable) ans[size++] = i;
}
return ans;
}
int* check_h(string g, size_t x, size_t y){
int *ans = new int[9];
memset(ans, 0, sizeof(ans));
size_t size;
for(size_t i = 1; i < 10; i++){
bool placeable = true;
for(size_t j = 0; j < 9; j++){
cout << get(g,x,(j + y) % 9) << " == " << i << endl;
if(get(g,x,(y + j) % 9) == static_cast<char>(i)){
placeable = false;
}
}
if(placeable) ans[size++] = i;
}
return ans;
}
void check(string g, size_t x, size_t y){
int *n_v = check_v(g, x, y);
int *n_h = check_h(g, x, y);
int *n_b = check_b(g, x, y);
int n_y[9] = {0};
int n;
size_t size = 0;
cout << "vert: ";
for (int i = 0; i < 9; i++)
cout << n_v[i];
cout << endl << "hor: ";
for (int i = 0; i < 9; i++)
cout << n_h[i];
cout << endl << "box: ";
for (int i = 0; i < 9; i++)
cout << n_b[i];
cout << endl;
if(n_v[0] == 0 || n_h[0] == 0 || n_b[0] == 0)
cout << "Error, no number works in slot " << x << ", " << y << endl;
else{
if(n_v[1] == 0)
n = n_v[0];
else if(n_h[1] == 0)
n = n_h[0];
else if(n_b[1] == 0)
n = n_b[0];
}
for(size_t i = 0; i < 9; i++){
bool possible = true;
for(size_t j = 0; possible && j < 9; j++){
if(n_h[j] != n_v[i])
possible = false;
}
for(size_t j = 0; possible && j < 9; j++){
if(n_b[j] != n_v[i])
possible = false;
}
if(possible)
n_y[size++] = n_v[i];
}
if(n_y[1] == 0)
n = n_y[0];
if(n != 0){
char c = n;
set(g,x,y,c);
}
}
int main(){
//initializations
size_t dim = 9;
string data = "";
string one_row;
for (size_t r = 0; r < dim ; r = r + 1) {
cin >> one_row;
data += one_row;
}
//start solving
bool cont = true;
while(cont){
cont = false;
for(size_t i = 0; i < data.length(); i ++){
if(data.at(i) == '0'){
cont = true;
cout << "Checking at point " << i / 9 << ", " << i % 9 << endl;
string old = data;
check(data, i / 9, i % 9);
if(old.compare(data) != 0)
print(data);
}
}
}
print(data);
}
This:
if(get(g,r,y) - 0 == i - 0)
Doesn't work. If get returns a char, it's a character from a string representing the CODE of the number. You're subtracting an integer 0 from that, which is not subtracting anything. What you want is either
if(get(g,r,y) - '0' == i)
Or
if(get(g,r,y) == i + '0')
Which assumes ascii (not unicode or something else).
What you're attempting to do is "convert" between an ascii CHARACTER and an integer. You do that conversion to one or the other, not both. The difference between 0 and '0' is that the first is an integer zero, the second is a character of 0 as would be found in a string.
(get(g,r,y) - 0 == i - 0);
This is wrong. Use it instead.
(get(g,r,y) - '0' == i - 0);

C++: Pascal's triangle - weird results

This is my first question so don't be mad at me, if I did something wrong.
I have to make a C++ program which returns an element from a selected row, for example:
Triangle 4 0 1 2 3
should return elements: 0, 1, 2 and 3 from row number 4, but it returns strange things, like:
Element 0: 1
Element 1: 10179988
Element 2: 50792126
Element 3: 91425820
I have no idea why
Here's my code:
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class Pascal {
private:
int *tab;
public:
Pascal(int n) throw(string) {
if (n < 0)
throw (string)"";
tab = new int[n+1];
for(int i = 1; i <= n; i++) {
for(int k = i; k >=0; k--) {
if (k - 1 >= 0)
tab[k] += tab[k-1];
else
tab[k] = 1;
}
}
};
int element(int m) {
return tab[m];
}
};
int main(int argc, char* argv[]) {
int n = 0, m = 0, elem = 0;
try {
n = strtol(argv[1], NULL, 0);
Pascal *row;
for(int i = 2; i < argc; i++) {
try {
m = strtol(argv[i], NULL, 0);
row = new Pascal(n+1);
if (m <= n && m >= 0) {
elem = row->element(m);
cout << "Element " << m << ": "<< elem << endl;
} else
cout << m << " - bad element index" << endl;
} catch (string ex) {
cout << argv[i] << " - bad element index!" << endl;
continue;
}
delete[] row;
}
} catch (string e) {
cout << argv[1] << " - bad row index!" << endl;
return 0;
}
}
I'll be grateful for any answer
tab = new int[n+1];
for(int i = 1; i <= n; i++) {
for(int k = i; k >=0; k--) {
if (k - 1 >= 0)
tab[k] += tab[k-1];
else
tab[k] = 1;
}
}
first iteration: i=1, k=1, tab[1]+=tab[0];
second iteration: i=1, k=2, tab[2]+=tab[1];
So you are not properly initializing your array, you are simply adding whatever values are in memory...
I think replacing if (k - 1 >= 0) with if (k - 1 > 0) should solve your problem
Try
tab = new int[n+1];
for(int i = 0; i <= n; i++) {
tab[i] = 1;
for(int k = i; --k > 0; )
tab[k] += tab[k-1];
}

Wordsearch with directions saved in int array

I'm trying to develop a wordsearch which finds the word "OIE" (indicating how many times appears), based in an integer unidimensional array that saves the directions (8), but I get strange errors when I run this (and incorrect outputs).
This is the code:
int arrf[8] = {0, -1, -1, -1, 0, 1, 1, 1};
int arrc[8] = {-1, -1, 0, 1, 1, 1, 0,-1};
char s[] = "OIE";
int main() {
int n, m;
while (cin >> n >> m) {
int res = 0;
vector<vector<char> > S(n, vector<char>(m));
for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> S[i][j];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
for (int d = 0; d < 8; ++d) {
bool trobat = true;
for (int h = 0; h < 3 and trobat; ++h) {
int f = i + arrf[d], c = j + arrc[d];
if (f < 0 || f >= n || c < 0 || c >= m || S[f][c] != s[h])
trobat = false;
}
if (trobat) res++;
}
}
}
cout << res << endl;
}
}
Could somebody help me to fix this? I would appreciate.
Regards.
One error is that this line
int f = i + arrf[d], c = j + arrc[d];
should be
int f = i + h*arrf[d], c = j + h*arrc[d];
With your code it doesn't matter how many times you go round the inner loop you are still checking the same position.