UVA Online Judge Runtime Error on 706 LCD Display - c++

I am new to C++ programming and trying to solve some problems on UVa Online Judge our prof gave us.
Right now I am on the 706 LCD Display (https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=16&page=show_problem&problem=647).
In my IDE (VS2015 Community) everything works fine and as expected but when I'm trying to submit my code I get a runtime error. Unfortunately they don't show more details about it.
I tried to run my code in several online c++ compilers (such as http://cpp.sh/) and never expirienced an error.
This is my code
#include <iostream>
#include <cmath>
// set the "borders" for each number
#define ZERO 1+2+4+16+32+64;
#define ONE 4+32;
#define TWO 1+4+8+16+64
#define THREE 1+4+8+32+64
#define FOR 2+4+8+32
#define FIVE 1+2+8+32+64
#define SIX 1+2+8+16+32+64
#define SEVEN 1+4+32
#define EIGHT 1+2+4+8+16+32+64
#define NINE 1+2+4+8+32+64
using namespace std;
// draw the digits line by line. some lines (first, middle, last) only represents horizontal lines, where all other lines represent vertical lines
// in every line for every digit is checked wheter the lines on the current position must be drawn or not.
void drawDigits(int* digits, int cDigits, int height, int width) {
int middle = (height >> 1);
for (int i = 0; i < height; ++i) {
for (int j = 0; j < cDigits; ++j) {
if (i == 0) {
if (digits[j] & 1) {
cout << " ";
for (int y = 0; y < width - 2; ++y) cout << "-";
cout << " ";
}
else {
for (int y = 0; y < width; ++y) cout << " ";
}
}
else if (i < middle) {
if (digits[j] & 2) {
cout << "|";
for (int y = 0; y < width - 2; ++y) cout << " ";
}
else {
for (int y = 0; y < width - 1; ++y) cout << " ";
}
if (digits[j] & 4) {
cout << "|";
}
else {
cout << " ";
}
}
else if (i == middle) {
if (digits[j] & 8) {
cout << " ";
for (int y = 0; y < width - 2; ++y) cout << "-";
cout << " ";
}
else {
for (int y = 0; y < width; ++y) cout << " ";
}
}
else if (i < height - 1) {
if (digits[j] & 16) {
cout << "|";
for (int y = 0; y < width - 2; ++y) cout << " ";
}
else {
for (int y = 0; y < width - 1; ++y) cout << " ";
}
if (digits[j] & 32) {
cout << "|";
}
else {
cout << " ";
}
}
else {
if (digits[j] & 64) {
cout << " ";
for (int y = 0; y < width - 2; ++y) cout << "-";
cout << " ";
}
else {
for (int y = 0; y < width; ++y) cout << " ";
}
}
if (j != cDigits - 1) cout << " ";
}
cout << endl;
if (i == height - 1) cout << endl;
}
}
// a given number (c-string) is prepared for drawing
// find out the length of the 'number' and assign for each digit the defined value in the ditigs-array
void drawLCD(int size, char* number) {
if (size < 1 || size > 10) return;
int length = 0;
while (*(number + length) != '\0') {
++length;
}
int* digits = new int[length];
for (int i = 0; i < length; ++i) {
int t = 0;
switch (*(number++) - '0') {
case 0:
t = ZERO;
break;
case 1:
t = ONE;
break;
case 2:
t = TWO;
break;
case 3:
t = THREE;
break;
case 4:
t = FOR;
break;
case 5:
t = FIVE;
break;
case 6:
t = SIX;
break;
case 7:
t = SEVEN;
break;
case 8:
t = EIGHT;
break;
case 9:
t = NINE;
break;
default:
t = ZERO;
}
digits[i] = t;
}
drawDigits(digits, length, 2 * size + 3, size + 2);
}
void callDraws(int cNums, int* size, char** numbers) {
for (int i = 0; i < cNums; ++i) {
drawLCD(size[i], numbers[i]);
}
}
// gets the integer value from a number in a c-string
int getInt(char* str) {
int length = 0;
int res = 0;
while (*(str + length) != '\0') {
++length;
}
for (int i = 0; i < length; ++i) {
res += (int)pow(10, length - (i + 1)) * (*(str++)-'0');
}
return res;
}
int main() {
char* n = new char[10];
int counter = 0;
int* size = new int[1000];
char** numbers = new char*[1000];
for (int i = 0; i < 1000; ++i) {
size[i] = 0;
numbers[i] = "";
}
while (cin >> n) {
if (size[counter] <= 0) {
int nn = getInt(n);
if (nn <= 0) break;
size[counter] = nn;
}
else {
numbers[counter++] = n;
n = new char[10];
}
}
callDraws(counter, size, numbers);
return 0;
}
When I enter a 'return 0' before the call to callDraws() the code terminates. So the error must be somewhere in printing the digits.
Where is this runtime error or how can I find it?
Thanks in advance.

Related

How do I make a function to check for the winning move in tic-tac-toe if the user chooses the size of the game board?

I have changed a Tic-Tac-Toe program from using a normal 3x3 grid to a grid-size chosen by the user (between 3 and 9). I am using a global constant 'SIZE' to hold the value the user chooses. My issue is adapting my winMove(); function so that it adjusts to check for the winning move based on the current board size chosen by the user(SIZE). I have tried different loops but can't get it to work. Right now it will only work with a 3x3 board.
I am still learning c++ and I have been stuck on this for a few days so I'm hoping a friendly person can help. This is my full program so far, hope it's not too much of a mess!
#include <iostream>
using namespace std;
struct TicTacToe
{
char **board;
};
void makeBoard(TicTacToe&);
void deallocBoard(TicTacToe&);
void printBoard(TicTacToe);
bool isDraw(TicTacToe);
void convertInput(char, char, int&, int&);
char winMove(TicTacToe, int, int);
bool validateSIZE(int);
int SIZE = 1;
int main(){
while(SIZE < 3 || SIZE > 9)
{
cout << "Enter number between 3 and 9 for the length of board.\n";
cout << "Example: 4 will make a board with 4 rows and 4 columns: ";
cin >> SIZE;
validateSIZE(SIZE);
}
TicTacToe game;
makeBoard(game);
char winner = 0;
char turn = 'X';
char rowIn, colIn;
int row, column;
while(!winner && !isDraw(game))
{
printBoard(game);
cout << "\nPlayer " << turn << "'s move (input format: a1): ";
cin >> rowIn >> colIn;
convertInput(rowIn, colIn, row, column);
if (game.board[row][column]==' ')
{
game.board[row][column] = turn;
if (turn == 'X')
{turn = 'O';}
else
{turn = 'X';}
winner = winMove(game, row, column);
}
else
cout << "Taken, try again!\n";
}
printBoard(game);
if (winner == 'X' || winner == 'O')
{cout << " Congrats, the winner is " << winner << '.' << endl;}
else
{cout << " Game ends in a draw." << endl;}
cout << endl << "Game Over!" << endl << endl;
deallocBoard(game);
return 0;
}
// Need help with this function.
char winMove(TicTacToe gameIn, int i, int j)
{
//row win
if (gameIn.board[i][0]==gameIn.board[i][1] &&
gameIn.board[i][0]==gameIn.board[i][2])
{
return gameIn.board[i][j];
}
//column win
if (gameIn.board[0][j]==gameIn.board[1][j] &&
gameIn.board[0][j]==gameIn.board[2][j])
{
return gameIn.board[i][j];
}
//left diagonal win
if (gameIn.board[0][0] != ' ' &&
gameIn.board[0][0] == gameIn.board[1][1] &&
gameIn.board[0][0] == gameIn.board[2][2])
{
return gameIn.board[i][j];
}
//right diagonal win
if (gameIn.board[0][2] != ' ' &&
gameIn.board[0][2] == gameIn.board[1][1] &&
gameIn.board[0][2] == gameIn.board[2][0])
{
return gameIn.board[i][j];
}
return 0;
}
bool validateSIZE(int SIZE)
{
if(SIZE < 3 || SIZE > 9)
{
cout << "\n\nNumber must be between 3 and 9!\nTry again!\nPlease ";
return false;
}
return true;
};
void makeBoard(TicTacToe& gameIn)
{
gameIn.board = new char*[SIZE];
for(int i = 0; i < SIZE; i++)
{gameIn.board[i] = new char[SIZE];}
for(int j =0; j < SIZE; j++)
for(int k = 0; k < SIZE; k++)
{gameIn.board[j][k] = ' ';}
}
void deallocBoard(TicTacToe& gameIn)
{
for(int i = 0; i < SIZE; i++)
delete [] gameIn.board[i];
delete [] gameIn.board;
gameIn.board = NULL;
}
void printBoard(TicTacToe gameIn)
{
int temp = 1;
cout << " ";
while(temp < SIZE + 1)
{
cout << temp << " ";
temp++;
}
temp = 1;
cout << endl;
for(int i = 0; i < SIZE; i++)
{
cout << char(i + 'a') << '|';
for(int j = 0; j < SIZE; j++)
{
cout << gameIn.board[i][j] << '|';
}
cout << endl;
}
}
bool isDraw(TicTacToe gameIn)
{
bool full = true;
for(int i = 0; full && i < SIZE; i++)
for(int j = 0; full && j < SIZE; j++)
full = gameIn.board[i][j] != ' ';
return full;
}
void convertInput(char rowIn, char colIn, int& row, int& column)
{
row = toupper(rowIn) - 'A';
column = colIn - '1';
}
You can easily use 2 for loops to iterate every starting point and its direction to preform victory checking. Something that would look like this:
// hor ver diagonals
// dx[4] = {1, 0, 1, 1};
// dy[4] = {0, 1, 1, -1};
// check horizontal win
for(int i = 0; i < SIZE; ++i)
{
bool win = true;
for(int j = 1; j < SIZE; ++j)
{
if(gameIn.board[j][i] != gameIn.board[j - 1][i])
{
win = false;
break;
}
}
if(win == true){return ;}
}
// check vertical win
.
.
.
// check diagonal 1 win
for(int i = 1; i < SIZE; ++i)
{
if(gameIn.board[i][i] != gameIn.board[i - 1][i - 1])
break;
if(i == SIZE - 1)return ;
}
// check diagonal 2 win
for(int i = 1; i < SIZE; ++i)
{
if(gameIn.board[i][SIZE - i - 1] != gameIn.board[i - 1][SIZE - i])
break;
if(i == SIZE - 1)return ;
}
I'll leave the vertical win for you.

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
*/

Two-Dimensional Array Searching Algorithm Optimisation

I have been given a "Sand box" of variable length and width. I've been given instructions to find a "shovel" of static size, which may be oriented either horizontally or vertically. I implement the following algorithm in order to search the least amount of times to find one valid location (one which corresponds to a "part of the object") in the grid:
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; j < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
In this case, the "Sand box" will be tested by the function as described below.
I completely recreate this scenario with a "Sand box" whose size is fixed (though easily manipulated) whose shovel is still randomly placed and oriented within the following code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
const int ROW = 12;
const int COL = 16;
char sandbox[ROW][COL];
bool probeSandBoxTwo(char c, int i);
void displayResults(int sCount, bool found, int x, int y);
void displaySandbox();
void displaySearchPattern();
void fillSandbox();
void placeShovel();
int main() {
fillSandbox();
placeShovel();
displaySandbox();
//define your variables here
bool found;
int nShift,
sCount,
shovelSize,
x,
y;
found = false;
nShift = 0;
shovelSize = 4;
sCount = 0;
for(int i = 0; i < ROW && !found; i++) {
for(int j = 0; j < COL && !found; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
x = i;
y = j + nShift;
sCount++;
cout << "Search conducted at (" << i << ", " << (j + nShift) << ")" << endl;
}
if(nShift >= shovelSize - 1 || nShift > ROW) {
nShift = 0;
} else {
nShift++;
}
}
displayResults(sCount, found, x, y);
displaySearchPattern();
}
bool probeSandBoxTwo(char c, int i) {
if(sandbox[c-'A'][i-1] == 'X') {
return true;
} else {
return false;
}
}
void displayResults(int sCount, bool found, int x, int y) {
cout << endl;
cout << "Total searches: " << sCount << endl;
cout << endl;
if(found) {
cout << "Shovel found at coordinates: (" << x << ", " << y << ")" << endl;
}
}
void displaySandbox() {
cout << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
cout << sandbox[i][j];
}
cout << endl;
}
cout << endl;
}
void displaySearchPattern() {
int nShift = 0;
int shovelSize = 4;
cout << endl << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
if(!((j + nShift) % shovelSize)) {
cout << 'o';
} else {
cout << '.';
}
}
if(nShift >= shovelSize - 1 || nShift > COL) {
nShift = 0;
} else {
nShift++;
}
cout << endl;
}
}
void fillSandbox() {
for(int i = 0; i < ROW; i++) {
for(int j = 0; j < COL; j++) {
sandbox[i][j] = '.';
}
}
}
void placeShovel() {
srand(time(NULL));
int shovelRow,
shovelCol,
shovelSize = 4;
if(rand() % 2) {
//horizontal
shovelRow = rand() % ROW + 1;
shovelCol = rand() % (COL - (shovelSize - 1)) + 1;
for(int i = shovelCol - 1; i < shovelSize + (shovelCol - 1); i++) {
sandbox[shovelRow - 1][i] = 'X';
}
} else {
//vertical
shovelRow = rand() % (ROW - (shovelSize - 1)) + 1;
shovelCol = rand() % COL + 1;
for(int i = shovelRow - 1; i < shovelSize + (shovelRow - 1); i++) {
sandbox[i][shovelCol - 1] = 'X';
}
}
}
In this code, I also graphically display the pattern (when run) with which my algorithm searches.
Is this truly the optimal search pattern for such a scenario, is my implementation correct, and if so, why might I be having incorrect results returned?
A given test driver reports the following results:
The source code for this result (and its test driver).
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; (j + nShift) < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
This corrects an error in the conditional portion of the for loop header which did not account for the index-shifting variable nShift.

2D Arrays with 'Creature' Movement Error (C++)

For this assignment, I have to make a creature 'C' be on a environment (20x20 array) and have it move.
The first time, it works and moves the creature, but the second time+, it doesn't.
So here's the code. Yes, I'm aware it's pretty messy, but I'm still kinda new to c++ (I wouldn't mind corrections :D). Also, as part of the assignment, the creature has to be in a LifeForm class.
Click here for a cpp.sh link to run.
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
class LifeForm{
public:
int x, y;
char array[20][20];
string name(){
return "Control";
}
char symbol(){
return 'C';
}
void xy(){
x = (rand() % 18) + 1; //random position in x
y = (rand() % 18) + 1; //random position in y
array[x][y] = symbol();
}
void step(){
for (int a = 0; a < 20; a++){
for(int b = 0; b < 20; b++){
array[a][b] = '0';
}
}
array[x + 1][y + 1] = symbol();
if (x > 19 || x < 2 || y > 19 || y < 2){
cout << "The creature cannot move any further without leaving the environment!" << endl;
array[x][y] = '0';
array[x - 1][y - 1] = symbol();
}
system("pause");
system("cls");
find(array);
for (int a = 0; a < 20; a++){
for (int b = 0; b < 20; b++){
cout << array[a][b] << " ";
}
cout << endl;
}
}
void step10(){
//todo
}
void find(char array[][20]){
for (int a = 0; a < 20; a++){
for (int b = 0; b < 20; b++){
if (array[a][b] != '0'){
cout << "Found Creature '" << name() << "' in row " << a + 1 << ", column " << b + 1 << "." << endl;
}
}
}
}
};
int main(){
LifeForm creature;
srand((unsigned) time(0)); //randomize
for (int a = 0; a < 20; a++){ //initilize array to all 0's
for (int b = 0; b < 20; b++){
creature.array[a][b] = '0';
}
}
creature.xy();
creature.find(creature.array);
for (int a = 0; a < 20; a++){ //display the array
for (int b = 0; b < 20; b++){
cout << creature.array[a][b] << " ";
}
cout << endl;
}
creature.step();
string a;
bool abc;
do{
cout << "\n--- What would you like to do? --------------" << endl;
cout << "S for Step | S10 for Step 10 | E for Exit" << endl;
cout << "---------------------------------------------" << endl;
cin >> a;
if (a == "S" || a == "s") {
creature.step();
abc = true;
}else if (a == "S10" || a == "s10") {
creature.step10();
abc = true;
}else{
abc = false;
system("pause");
}
}while(abc == true);
}
So, as you can see, I'm trying to get the creature to move more then once when the user chooses to, but it stays at the same position.
In the method step you never update the current position of the Creature. In this line array[x + 1][y + 1] = symbol(); you update the array. But you should rewrite it to this:
x++;
y++;
array[x][y] = symbol();
By doing this, you ensure that the current position of the creature is updated correctly when you change the representation of the position (The array you draw on the screen).