Character / int equality evaluating incorrectly - c++

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);

Related

Recursive function throws unhandled exception at 0x79B20AD2 (ucrtbased.dll)

I write minesweeper and the current task is to write a function that would uncover the areas that have no mines neighbouring to them. In the original minesweeper if you click within the area with no mines, it would open up an area until there are mines alongside its borders. For that I wrote the function unravel(). Here is the code:
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <string>
using namespace std;
#define Str1D vector<string>
#define Str2D vector<Str1D>
#define Int1D vector<int>
#define Int2D vector<Int1D>
void unravel(Str2D &fogofwar, Int2D &display, int x, int y) {
for (int minusrows = -1; minusrows < 2; minusrows++){ // going through the
// neighbouring cells (+ the cell itself)
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (x + minusrows > 0 && y + minuscolumns > 0 && x + minusrows < fogofwar.size() && y + minuscolumns < fogofwar[0].size()){ // checking
// if within borders
if (x > 0 && y > 0 && x < fogofwar.size() && y < fogofwar[0].size()) { // checking if the oririginal
// values are within borders
fogofwar[x + minusrows][y + minuscolumns] = to_string(display[x + minusrows][y + minuscolumns]); // revealing the
// neighbouring cells
if (display[x + minusrows][y + minuscolumns] == 0) { // if the cell is 0 on the display,
// open it and the 8 neighbouring to it cells
if (not (minusrows == 0 && minuscolumns == 0)) { // if it's not the same cell, of course,
// otherwise it's an endless cycle
unravel(fogofwar, display, x + minusrows, y + minuscolumns);
}
}
}
}
}
}
}
int main() {
int row, column, prob;
bool running = true;
cout << "Input width and height: ";
cin >> row >> column;
cout << endl << "Input mines probability (%): ";
cin >> prob;
cout << endl;
srand (time(NULL));
Int2D field(row + 1, Int1D(column + 1));
Int2D display(row + 1, Int1D(column + 1));
Str2D fogofwar(row + 1, Str1D(column + 1, "*"));
field[0][0] = 0; // field of mines
display[0][0] = 0; // display of neighbouring mines
fogofwar[0][0] = to_string(0); // what the player will see
for (int i = 1; i < row + 1; i++) { //assigning coordinates
field[i][0] = i;
display[i][0] = i;
fogofwar[i][0] = to_string(i);
}
for (int j = 1; j < column + 1; j++) { //assigning coordinates
field[0][j] = j;
display[0][j] = j;
fogofwar[0][j] = to_string(j);
}
for (int i = 1; i < row + 1; i++){ // filling the field with mines
for (int j = 1; j < column + 1; j++){
int x = rand() % 100;
if (x < prob) {
field[i][j] = 1;
}
else{
field[i][j] = 0;
}
}
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // printing field
for (int j = 0; j < column + 1; j++){
cout << " " << field[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // assigning the display of amount of neighbouring mines
for (int j = 0; j < column + 1; j++){
int count = 0;
if (i > 0 && j > 0){
for (int minusrows = -1; minusrows < 2; minusrows++){
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (i + minusrows > 0 && i + minusrows < row + 1 && j + minuscolumns > 0 && j + minuscolumns < column + 1){
if (field[i + minusrows][j + minuscolumns] == 1){
count++;
}
}
}
}
display[i][j] = count;
}
cout << " " << display[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
while (running) {
for (int i = 0; i < row + 1; i++){
for (int j = 0; j < column + 1; j++){
cout << " " << fogofwar[i][j] << " ";
}
cout << endl;
}
cout << endl;
int x, y;
cout << endl << "Input the target cell (x, y): ";
cin >> x >> y;
cout << endl;
unravel(fogofwar, display, x, y);
}
return 0;
}
If I delete the recursivity by changing unravel(fogofwar, display, x + minusrows, y + minuscolumns); to continue; within the function unravel(), it works as intended. But I need to open up the entire area where there are 0's on the display. Any way to skirt the error or fix it for good?
First of all, I am unable to reproduce the error with the information in question. Please try to specify the complete usecase along with what values you are getting into error with.
However, there is an obvious problem in the implementation of unravel.
You go over the same cell multiple times, until the memory exceeds total memory of course (I believe this is the point your program crashes)
You should maintain the slots already visited. You can do this in multiple ways. I am providing one of the ways to handle this.
Try the following code:-
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <string>
using namespace std;
#define Str1D vector<string>
#define Str2D vector<Str1D>
#define Int1D vector<int>
#define Int2D vector<Int1D>
void unravel(Str2D &fogofwar, Int2D &display, int x, int y, vector<vector<bool> > &visited) {
for (int minusrows = -1; minusrows < 2; minusrows++){ // going through the
// neighbouring cells (+ the cell itself)
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (x + minusrows > 0 && y + minuscolumns > 0 && x + minusrows < fogofwar.size() && y + minuscolumns < fogofwar[0].size()){ // checking
// if within borders
if (x > 0 && y > 0 && x < fogofwar.size() && y < fogofwar[0].size()) { // checking if the oririginal
// values are within borders
if (x > 0 && y > 0 && x < visited.size() && y < visited[0].size()) {
cout.flush();
}
visited[x][y] = true;
fogofwar[x + minusrows][y + minuscolumns] = to_string(display[x + minusrows][y + minuscolumns]); // revealing the
// neighbouring cells
if (display[x + minusrows][y + minuscolumns] == 0) { // if the cell is 0 on the display,
// open it and the 8 neighbouring to it cells
if (not visited[x + minusrows][y + minuscolumns]) { // if it's not the same cell, of course,
// otherwise it's an endless cycle
unravel(fogofwar, display, x + minusrows, y + minuscolumns, visited);
}
}
}
}
}
}
}
int main() {
int row, column, prob;
bool running = true;
cout << "Input width and height: ";
cin >> row >> column;
cout << endl << "Input mines probability (%): ";
cin >> prob;
cout << endl;
srand (time(NULL));
Int2D field(row + 1, Int1D(column + 1));
Int2D display(row + 1, Int1D(column + 1));
Str2D fogofwar(row + 1, Str1D(column + 1, "*"));
field[0][0] = 0; // field of mines
display[0][0] = 0; // display of neighbouring mines
fogofwar[0][0] = to_string(0); // what the player will see
for (int i = 1; i < row + 1; i++) { //assigning coordinates
field[i][0] = i;
display[i][0] = i;
fogofwar[i][0] = to_string(i);
}
for (int j = 1; j < column + 1; j++) { //assigning coordinates
field[0][j] = j;
display[0][j] = j;
fogofwar[0][j] = to_string(j);
}
for (int i = 1; i < row + 1; i++){ // filling the field with mines
for (int j = 1; j < column + 1; j++){
int x = rand() % 100;
if (x < prob) {
field[i][j] = 1;
}
else{
field[i][j] = 0;
}
}
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // printing field
for (int j = 0; j < column + 1; j++){
cout << " " << field[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // assigning the display of amount of neighbouring mines
for (int j = 0; j < column + 1; j++){
int count = 0;
if (i > 0 && j > 0){
for (int minusrows = -1; minusrows < 2; minusrows++){
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (i + minusrows > 0 && i + minusrows < row + 1 && j + minuscolumns > 0 && j + minuscolumns < column + 1){
if (field[i + minusrows][j + minuscolumns] == 1){
count++;
}
}
}
}
display[i][j] = count;
}
cout << " " << display[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
while (running) {
for (int i = 0; i < row + 1; i++){
for (int j = 0; j < column + 1; j++){
cout << " " << fogofwar[i][j] << " ";
}
cout << endl;
}
cout << endl;
int x, y;
cout << endl << "Input the target cell (x, y): ";
cin >> x >> y;
cout << endl;
vector<vector<bool> > visited(row+1, vector<bool>(column+1, false));
unravel(fogofwar, display, x, y, visited);
}
return 0;
}
The change is that I am maintaining a visited array, and I never go back to the spot I have already gone to before in unravel.

Finding all saddle points in a matrix c++

I'm working on a code that finds all saddle points in a matrix. Both smallest in their row and biggest in their column, and biggest in their row and smallest in their column fall under the definition (of my university) of a saddle point. Being a beginner I managed to get half of it done (finding saddle points which are smallest in their row and biggest in their column) by copying parts of what we've done in class and typing it myself. I have been stuck on it for quite some time and can't figure how to add the saddle points which are biggest in their row and smallest in their column to the program.
This is what I have so far:
#include <iostream>
#include <cstdlib>
using namespace std;
int a[10][10];
int x, y;
int pos_max(int j) //saddle points check
{
int max = 0;
for (int i = 1; i <= x - 1; i++) {
if (a[i][j] > a[max][j]) {
max = i;
}
}
return max;
}
int main() {
cout << "Enter the number of rows: ";
cin >> x;
cout << "Enter the number of columns: ";
cin >> y;
cout << "----------------------------" << endl;
for (int i = 0; i <= x - 1; i++) //input of the matrix
for (int j = 0; j <= y - 1; j++) {
cout << "a[" << i + 1 << ", " << j + 1 << "] = ";
cin >> a[i][j];
}
cout << "----------------------------\n";
for (int i = 0; i <= x - 1; i++) //visualization of the matrix
{
for (int j = 0; j <= y - 1; j++)
cout << a[i][j] << " ";
cout << endl;
}
cout << "----------------------------\n";
int r;
int flag = 0;
int i = y;
for (int j = 0; j <= y - 1; j++) {
r = pos_max(j);
for (i = 0; i <= y - 1; i++) {
if (a[r][i] < a[r][j]) {
break;
}
}
if (i == y) {
cout << "Saddle points are: ";
cout << "a[" << r + 1 << ", " << j + 1 << "] = " << a[r][j] << "\n";
flag = 1;
}
}
if (flag == 0) {
cout << "No saddle points\n";
}
cout << "----------------------------\n";
return 0;
}
First, there is a logical error with your code. In the pos_max function, it will return the index of the element which is maximum in the column. There can be a case when there are multiple maximum with the same value in the column, however, it returns the one which is not the minimum in the row, hence your program won't be able to print that saddle point.
To solve this, you can either return an array of all indices which are maximum in a column and then check for each of those points if it's minimum in their respective column, but I think it's not a very elegant solution. In any case, you will again have to write the entire code for the other condition for saddle points, minimum in column and maximum in row.
Hence, I would suggest a change in strategy. You create 4 arrays, max_row, max_col, min_row, min_col, where each array stores the minimum / maximum in that row / column respectively. Then you can traverse the array and check if that point satisfies saddle point condition.
Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
int a[10][10];
int max_row[10], max_col[10], min_row[10], min_col[10];
int x, y;
bool is_saddle(int i, int j) {
int x = a[i][j];
return (max_row[i] == x && min_col[j] == x) || (min_row[i] == x && max_col[j] == x);
}
int main() {
/* code to input x, y and the matrix
...
*/
/* code to visualize the matrix
...
*/
/* populating max and min arrays */
for (int i = 0; i <= x-1; ++i) {
max_row[i] = a[i][0], min_row[i] = a[i][0];
for (int j = 0; j <= y-1; ++j) {
max_row[i] = max(max_row[i], a[i][j]);
min_row[i] = min(min_row[i], a[i][j]);
}
}
for (int j = 0; j <= y-1; ++j) {
max_col[j] = a[0][j], min_col[j] = a[0][j];
for (int i = 0; i <= x-1; ++i) {
max_col[j] = max(max_col[j], a[i][j]);
min_col[j] = min(min_col[j], a[i][j]);
}
}
/* Check for saddle point */
for (int i = 0; i <= x-1; ++i) {
for (int j = 0; j <= y-1; ++j) {
if (is_saddle(i, j)) {
cout << "Saddle points are: ";
cout << "a[" << i + 1 << ", " << j + 1 << "] = " << a[i][j] << "\n";
flag = 1;
}
}
}
if (flag == 0) {
cout << "No saddle points\n";
}
cout << "----------------------------\n";
return 0;
}
#include <iostream>
using namespace std;
int getMaxInRow(int[][5], int, int, int);
int getMinInColumn(int[][5], int, int, int);
void getSaddlePointCordinates(int [][5],int ,int );
void getInputOf2dArray(int a[][5], int, int);
int main()
{
int a[5][5] ;
int rows, columns;
cin >> rows >> columns;
getInputOf2dArray(a, 5, 5);
getSaddlePointCordinates(a,rows,columns);
}
void getInputOf2dArray(int a[][5], int rows, int columns)
{
for (int i = 0; i < rows; i = i + 1)
{
for (int j = 0; j < columns; j = j + 1)
{
cin >> a[i][j];
}
}
}
void getSaddlePointCordinates(int a[][5],int rows,int columns)
{
int flag = 0;
for (int rowNo = 0; rowNo < 5; rowNo++)
{
for (int columnNo = 0; columnNo < 5; columnNo++)
{
if (getMaxInRow(a, rows, columns, rowNo) == getMinInColumn(a, rows, columns, columnNo))
{
flag = 1;
cout << rowNo << columnNo;
}
}
}
if (flag == 0)
cout << "no saddle point";
cout << "\n";
}
int getMaxInRow(int a[][5], int row, int column, int rowNo)
{
int max = a[rowNo][0];
for (int i = 1; i < column; i = i + 1)
{
if (a[rowNo][i] > max)
max = a[rowNo][i];
}
return max;
}
int getMinInColumn(int a[][5], int row, int column, int columnNo)
{
int min = a[0][columnNo];
for (int i = 1; i < row; i = i + 1)
{
if (a[i][columnNo] < min)
min = a[i][columnNo];
}
return min;
}
just take the reference arr(ref[size]) // memorization method to check the minimum and maximum value in it.
Here is the Code Implementation with time complexity O(n *n) & space complexity O(n):
#include <bits/stdc++.h>
using namespace std;
#define size 5
void util(int arr[size][size], int *count)
{
int ref[size]; // array to hold all the max values of row's.
for(int r = 0; r < size; r++)
{
int max_row_val = arr[r][0];
for(int c = 1; c < size; c++)
{
if(max_row_val < arr[r][c])
max_row_val = arr[r][c];
}
ref[r] = max_row_val;
}
for(int c = 0; c < size; c++)
{
int min_col_val = arr[0][c];
for(int r = 1; r < size; r++) // min_val of the column
{
if(min_col_val > arr[r][c])
min_col_val = arr[r][c];
}
for(int r = 0; r < size; r++) // now search if the min_val of col and the ref[r] is same and the position is same, if both matches then print.
{
if(min_col_val == ref[r] && min_col_val == arr[r][c])
{
*count += 1;
if((*count) == 1)
cout << "The cordinate's are: \n";
cout << "(" << r << "," << c << ")" << endl;
}
}
}
}
// Driver function
int main()
{
int arr[size][size];
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
cin >> arr[i][j];
}
int count = 0;
util(arr, &count);
if(!count)
cout << "No saddle points" << endl;
}
// Test case -> Saddle Point
/*
Input1:
1 2 3 4 5
6 7 8 9 10
1 2 3 4 5
6 7 8 9 10
0 2 3 4 5
Output1:
The cordinate's are:
(0,4)
(2,4)
(4,4)
Input2:
1 2 3 4 5
6 7 8 9 1
10 11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Output2:
No saddle points
*/

Output not correct for my C++ program

So, I have the following problem:
From the file tabl.in a number n will be read (n<=50).
After that a square array with n rows and n columns will be read; all the numbers in the array will be composed by a maximum of 2 digits each.
Shown in the file tabl.out, the modulo between the sum of numbers found on the second diagonal of the array and 10, if the sum is palindrome (true=1, false=0), and the arithmetic mean of elements situated below of the main diagonal.
Will be writing functions for:
reading the array
calculation of the operation sum of secondary diagonal%10
checking if the previous result it is palindrome
calculation of the arithmetic mean below main diagonal
Example:
tabl.in:
4
5 8 2 12
1 0 3 16
1 2 1 11
5 7 2 19
tabl.out:
2 1 3
where
(12+3+2+5)%10 = 22%10 = 2
22 is palindrome = 1
1+2+2+1+7+5 = 18, 18/6=3
My code so far is:
#include <fstream>
using namespace std;
ifstream fin("tabl.in");
ofstream fout("tabl.out");
void readn(int Arr[][51], int n) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
fin >> Arr[i][j];
}
int sumsec(int Arr[][51], int n) {
int s = 0;
float r;
for (int i = 1; i <= n; i++)
s = s + Arr[i][n - i + 1];
r = s % 10;
return r;
}
void pald(int Arr[][51], int n) {
int s = 0, pal = 0;
for (int i = 1; i < n; i++)
s = s + Arr[i][n - i + 1];
while (s != 0) {
pal = pal * 10 + s % 10;
s = s / 10;
}
if (pal == s)
fout << "1 ";
else
fout << "0 ";
}
int ambmd(int Arr[][51], int n) {
int s = 0, k;
float ame;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i - 1; j++) {
s = s + Arr[i][j];
k++;
}
}
ame = s / k;
return ame;
}
int main() {
int Arr[51][51], n;
float r, ame;
fin >> n;
readn(Arr, n);
r = sumsec(Arr, n);
fout << r << " ";
pald(Arr, n);
ame = ambmd(Arr, n);
fout << ame;
}
But I have an issue with the palindrome() function: my output file will have 2 0 3 written to it for the given array from the example, instead of 2 1 3. What am I doing wrong?
Your pald function would work, if you compute s the same way as you do in sumsec and if s would still contain the sum, after you compute pal.
In your case, while (s != 0) {...}, followed by if (pal == s) {...} could be re-written as if (pal == 0), which is clearly not the intended solution. Just save your sum before computing pal, then compare with the saved sum.
Also, change your loop condition for computing s to for (int i = 1; i <= n; i++).
int s = 0, pal = 0, sum = 0;
for (int i = 1; i <= n; i++)
s = s + Arr[i][n - i + 1];
sum = s;
while (s != 0) {
pal = pal * 10 + s % 10;
s = s / 10;
}
if (pal == sum)
fout << "1 ";
else
fout << "0 ";
You should also consider the various comments for code improvements, like not re-computing the sum in the pald function.

Puzzle related to sorting a 2-D array in ascending order

A randomly generated 4x4 2-D array is given to the user, of which one element is definitely 0. Considering 0 to be an empty location, the user will have to exchange the remaining 15 elements with 0 repeatedly until they get the array in ascending order, with 0 as the last element.
At this point, they're allowed to exchange any element with 0.
But how do I modify this code to ensure that are only able to exchange those elements with 0 that are adjacent to it (either above, below or beside it) ?
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int check_asc(int a[][4])
{
int i, j, previous = a[0][0];
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if(i == 3 && j == 3)
{
if (a[i][j] == 0)
return 1;
}
else if (a[i][j] < previous)
{
return 0;
}
previous = a[i][j];
}
}
return 1;
}
void swap(int a[][4], int &xpos, int &ypos)
{
int arr, temp;
cout << "\n\nEnter number to be swapped with 0: ";
cin >> arr;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (a[i][j] == arr)
{
temp = a[xpos][ypos];
a[xpos][ypos] = a[i][j];
a[i][j] = temp;
xpos = i;
ypos = j;
return;
}
}
}
}
int check_rep(int a[][4], int assign)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (assign == a[i][j])
return 0;
}
}
return 1;
}
void main()
{
int a[4][4], assign, xpos = 0, ypos = 0, asc_result, rep_result;
srand((unsigned)time(NULL));
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
{
if (i == 0 && j == 0)
a[i][j] = 0;
else
{
do {
assign = rand() % 50;
rep_result = check_rep(a, assign);
} while (rep_result == 0);
a[i][j] = assign;
}
}
cout << "\n\nArrange the 4x4 matrix into ascending order. (Consider 0 as a blank space)" << endl;
for (int i = 0; i < 4; i++)
{
cout << endl;
for (int j = 0; j < 4; j++)
cout << a[i][j] << '\t';
}
do {
swap(a, xpos, ypos);
system("cls");
for (int i = 0; i < 4; i++)
{
cout << endl;
for (int j = 0; j < 4; j++)
cout << a[i][j] << '\t';
}
asc_result = check_asc(a);
} while (asc_result == 0);
cout << "\n\tYou win"<<endl;
system("pause");
}
Simple, just extend your swap function with a piece of code that will check whether the location of the element to be swapped is adjacent to the location of 0:
void swap(int a[][4], int &xpos, int &ypos)
{
...
if (a[i][j] == arr &&
((i == xpos && (j == ypos - 1 || j == ypos + 1)) ||
(j == ypos && (i == xpos - 1 || i == xpos + 1))))
{
temp = a[xpos][ypos];
a[xpos][ypos] = a[i][j];
a[i][j] = temp;
xpos = i;
ypos = j;
return;
}
An improvement would be to separate the check condition and inform the user in case when the element is not adjacent to 0.
Rough Algorithm
1) create a function find location, it will return a structure Point that has x, y integer fields, it will find the x, y location of any piece based on the pieces value, i.e. lets say 0 is entered, if it is located in the top left corner (0,0), a point (0, 0) will be returned
2) create a function that takes in 2 points, the location of the '0' and the location of the piece we wish to swap lets call it S, if S.x = 0.x and 0.y - 1 = S.y or S.y - 0.y + 1 then you know that said piece is directly above or below the 0, now of course you have ot add a few conditions for boundaries so as we dont check outside the grid. Have this function return an int 1 if the piece S is located above/below/beside, 0 if not.
3) if 1 is returned your allowed to do the flip, if 0 is returned find another piece

Pixel distance flood-fill

Problem statement:
Input is a rectangular bitmap like this:
0001
0011
0110
The task is to find for each black (0) "pixel", the distance to the
closest white (1) "pixel". So, the output to the above should be:
3 2 1 0
2 1 0 0
1 0 0 1
I have a working solution to the problem, which I posted here, asking for advice on performance improvement. In effort to implement #Jerry Coffin's solution (suggested in an answer to the question) I wrote the following code, which, unfortunately, produces garbage output. For example, the output for the input from the problem statement is
1 1 1 0
11 11 0 0
110 0 0 1
Why doesn't the code work?
#include <iostream>
#include <string>
#include <queue>
using namespace std;
const unsigned short MAX = 200;
typedef unsigned short coordinate;
typedef pair<coordinate,coordinate> coordinates;
//Converts char[] to unsigned int
coordinate atou(char* s) {
coordinate x = 0;
while(*s) x = x*10 + *(s++) - '0';
return x;
}
//Returns array of immediate neighbours of pixel of coordinates c
coordinates* neighbours_of(coordinates c) {
static coordinates neighbours[7];
coordinate i = c.first;
coordinate j = c.second;
neighbours[0] = coordinates(i+1,j);
neighbours[1] = coordinates(i+1,j+1);
neighbours[2] = coordinates(i,j+1);
neighbours[3] = coordinates(i-1,j+1);
neighbours[4] = coordinates(i-1,j);
neighbours[5] = coordinates(i-1,j-1);
neighbours[6] = coordinates(i,j-1);
neighbours[7] = coordinates(i+1,j-1);
return neighbours;
}
int main() {
unsigned short test_cases, wave_number, initial_wave_size;
coordinate m, n, i, j;
int A[MAX][MAX];
coordinates* directions;
string row;
queue<coordinates> ones;
queue<coordinates> wave;
coordinates current_coordinates;
bool found_some_zero;
cin >> test_cases;
while(test_cases--) {
//Input
cin >> n;
cin >> m;
for(i = 0; i < n; i++) {
cin >> row;
for(j = 0; j < m; j++) {
if(row[j] == '1') {
A[i][j] = -1;
ones.push(coordinates(i,j));
} else A[i][j] = atou(&row[j]);
}
}
//Initilization
wave = ones;
wave_number = 1;
found_some_zero = true;
//Filling algorithm
while(found_some_zero) {
found_some_zero = false;
initial_wave_size = wave.size();
while(initial_wave_size--) {
current_coordinates = wave.front();
directions = neighbours_of(current_coordinates);
//Try all directions
for(int k = 0; k < 8; k++) {
i = directions[k].first;
j = directions[k].second;
//If on screen and not yet visited
if(i < n && j < m && A[i][j] == 0) {
//Mark visited
A[i][j] = wave_number;
//(i,j) will be part the next wave
wave.push(coordinates(i,j));
found_some_zero = true;
}
}
wave.pop();
}
wave_number++;
}
//-1 to 0
while(!ones.empty()) {
current_coordinates = ones.front();
i = current_coordinates.first;
j = current_coordinates.second;
A[i][j] = 0;
ones.pop();
}
//Output
for(i = 0; i < n; i++) {
for(j = 0; j < m; j++)
cout << A[i][j] << " ";
cout << endl;
}
}
return 0;
}
The input loop is buggy. Instead of
if(row[j] == '1') {
A[i][j] = -1;
ones.push(coordinates(i,j));
} else A[i][j] = atou(&row[j]);
you need to do
if(row[j] == '1') {
A[i][j] = -1;
ones.push(coordinates(i,j));
} else A[i][j] = 0;
Also, neighbors[7] should be neighbors[8], and you should use only the four cardinal directions if you want to match the specified output exactly.