I have code that I already have four basic directions (Up, Down, Left, Right). However, I want to have them go in diagonal directions as well, so it will add up to eight directions. How would I do that? What I see from it, I basically have to have two directions change at the same time, but I don't know how to do that.
Code:
// problem with backtracking using stack
#include <cstring>
#include <iostream>
#include <stack>
using namespace std;
#define N 4
#define M 5
class node {
public:
int x, y;
int dir;
node(int i, int j)
{
x = i;
y = j;
// Initially direction
// set to 0
dir = 0;
}
};
// maze of n*m matrix
int n = N, m = M;
// Coordinates of food
int fx, fy;
bool visited[N][M];
bool isReachable(int maze[N][M])
{
// Initially starting at (0, 0).
int i = 0, j = 0;
cout << '[' << i << ':' << j << ']';
stack<node> s;
node temp(i, j);
s.push(temp);
while (!s.empty()) {
// Pop the top node and move to the
// left, right, top, down or retract
// back according the value of node's
// dir variable.
temp = s.top();
int d = temp.dir;
i = temp.x, j = temp.y;
// Increment the direction and
// push the node in the stack again.
temp.dir++;
s.pop();
s.push(temp);
// If we reach the Food coordinates
// return true
if (i == fx and j == fy) {
return true;
}
// Checking the Up direction.
if (d == 0) {
if (i - 1 >= 0 and maze[i - 1][j] == 1 and
!visited[i - 1][j]) {
cout <<'['<< i - 1 << ':'<<j << ']' ;
node temp1(i - 1, j);
visited[i - 1][j] = true;
s.push(temp1);
}
}
// Checking the left direction
else if (d == 1) {
if (j - 1 >= 0 and maze[i][j - 1] == 1 and
!visited[i][j - 1]) {
cout << '[' << i << ':' << j-1 << ']' ;
node temp1(i, j - 1);
visited[i][j - 1] = true;
s.push(temp1);
}
}
// Checking the down direction
else if (d == 2) {
if (i + 1 < n and maze[i + 1][j] == 1 and
!visited[i + 1][j]) {
cout << '[' << i + 1 << ':' << j << ']' ;
node temp1(i + 1, j);
visited[i + 1][j] = true;
s.push(temp1);
}
}
// Checking the right direction
else if (d == 3) {
if (j + 1 < m and maze[i][j + 1] == 1 and
!visited[i][j + 1]) {
cout << '[' << i << ':' << j + 1<< ']' ;
node temp1(i, j + 1);
visited[i][j + 1] = true;
s.push(temp1);
}
}
// If none of the direction can take
// the rat to the Food, retract back
// to the path where the rat came from.
else {
visited[temp.x][temp.y] = false;
s.pop();
}
//system("pause");
}
// If the stack is empty and
// no path is found return false.
return false;
}
// Driver code
int main()
{
// Initially setting the visited
// array to true (unvisited)
memset(visited, false, sizeof(visited));
// Maze matrix
int maze[N][M] = {
{ 1, 0, 1, 1, 0 },
{ 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 1 }
};
// Food coordinates
fx = 2;
fy = 3;
if (isReachable(maze)) {
cout << "Path Found!" << '\n';
}
else
cout << "No Path Found!" << '\n';
return 0;
}```
By combining the conditions you already have... You have the following for checking the second dimension:
if (j + 1 < m and maze[i][j + 1] == 1 and !visited[i][j + 1])
If you want to increment both at once you would do something like:
if (i + 1 < n and j + 1 < m and maze[i + 1][j + 1] == 1 and !visited[i + 1][j + 1])
Since you have 4 diagonals, you would do similar checkings for the other 3 diagonals. Be careful with copy and paste not to forget to increment/decrement both i and j.
Let's assume a board, with row 0 and column 0 in the upper left corner.
Also, assume the present position is at <row, column>.
There are 8 locations relative to the present position (unless you are near the edge of the board).
+---------------------+---------------------+--------------------+
| row - 1, column - 1 | row - 1, column + 0 | row - 1, column + 1|
+---------------------+---------------------+--------------------+
| row + 0, column - 1 | row, column | row + 0, column + 1|
+---------------------+---------------------+--------------------+
| row + 1, column - 1 | row + 1, column + 0 | row + 1, column + 1|
+---------------------+---------------------+--------------------+
Before making a move, check the validity of the next move.
The next move would be based on the above table.
I have to implement the CSR matrix data structure in C++ using 3 dynamic arrays (indexing starts at 0) and I've got stuck. So I have to implement 2 functions:
1) modify(int i, int j, TElem e) - modifies the value of (i,j) to e or adds if (if it does not exist) or deletes it if e is null.
2) element(int i, int j) const - returns the value found on (i,j)
I wanted to test my code in the next way:
Matrix m(4,4); m.print(); It will print:
Lines: 0 0 0 0 0
Columns:
Values:
(And this is fine)
Now if I want to modify: m.modify(1,1,5); //The element (1,1) will be set to 5
The output of m.print(); will be:
Lines: 0 1 1 1 1
Columns: 1
Values: 5 (which again is fine)
And now if I want to print m.element(1, 1) it will return 0 and m.element(0, 1) will return 5.
This is my implementation of element(int i, int j) :
int currCol;
for (int pos = this->lines[i]; pos < this->lines[i+1]; pos++) {
currCol = this->columns[pos];
if (currCol == j)
return this->values[pos];
else if (currCol > j)
break;
}
return NULL_TELEM;
The constructor looks like this:
Matrix::Matrix(int nrLines, int nrCols) {
if (nrLines <= 0 || nrCols <= 0)
throw exception();
this->nr_lines = nrLines;
this->nr_columns = nrCols;
this->values = new TElem[100];
this->values_capacity = 1;
this->values_size = 0;
this->lines = new int[nrLines + 1];
this->columns = new TElem[100];
this->columns_capacity = 1;
this->columns_size = 0;
for (int i = 0; i <= nrLines; i++)
this->lines[i] = NULL_TELEM;
}
This is the "modify" method:
TElem Matrix::modify(int i, int j, TElem e) {
if (i < 0 || j < 0 || i >= this->nr_lines || j >= nr_columns)
throw exception();
int pos = this->lines[i];
int currCol = 0;
for (; pos < this->lines[i + 1]; i++) {
currCol = this->columns[pos];
if (currCol >= j)
break;
}
if (currCol != j) {
if (!(e == 0))
add(pos, i, j, e);
}
else if (e == 0)
remove(pos, i);
else
this->values[pos] = e;
return NULL_TELEM;
}
And this is the inserting method:
void Matrix::add(int index, int line, int column, TElem value)
{
this->columns_size++;
this->values_size++;
for (int i = this->columns_size; i >= index + 1; i--) {
this->columns[i] = this->columns[i - 1];
this->values[i] = this->values[i - 1];
}
this->columns[index] = column;
this->values[index] = value;
for (int i = line; i <= this->nr_lines; i++) //changed to i = line + 1;
this->lines[i]++;
}
Can somebody help me, please? I can't figure out why this happens and I really need to finish this implementation these days.
It just can't pass the next test. And if I want to print the elements i have (4,0)=0 (4,1)=0 ... (4,8)=0 and (4,9)=3. Now this looks pretty weird why it happens.
void testModify() {
cout << "Test modify" << endl;
Matrix m(10, 10);
for (int j = 0; j < m.nrColumns(); j++)
m.modify(4, j, 3);
for (int i = 0; i < m.nrLines(); i++)
for (int j = 0; j < m.nrColumns(); j++)
if (i == 4)
assert(m.element(i, j) == 3);
//cout << i << " " << j << ":" << m.element(i, j)<<'\n';
else
assert(m.element(i, j) == NULL_TELEM);
}
When you call modify(1, 1, 5) with an empty matrix (all zeros), that results in a call to add(0, 1, 1, 5). That increments columns_size and values_size (both to 1), the for loop body will not execute, you update columns[0] to 1 and values[0] to 5, then increment all the lines values starting at element lines[1], setting them all to 1 (lines[0] will still be 0). But lines[1] should indicate the element we just added, so it should be 0, since the value is found using columns[0].
The for loop at the end of add should start at element line + 1.
We have to make Connect4 in C++ as our last assignment for one of my classes. As of right now I have a fairly functional version. I had a really promising idea for a recursive solution for checking if the game is over but the issue is it only checks starting from the token it is starting at. For example if the most recently placed token has 3 of the same kind in any direction that is valid it works, but if it has 2 in one direction and 1 the opposite way it doesn't work. Does anyone have any ideas for how I could edit my function to incorporate the 2nd situation or should I just scrap it and rewrite it differently. Here is my code.
//TODO implement checking spots other than start
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
int runGame(int, int, int);
void promptUser(int**, int[], int, int, int);
void genRanMove(int**, int[], int, int);
bool checkGameOver(int**, int, int, int, int, int, int, int, int);
void showBoard(int**, int, int);
void playAgain();
using namespace std;
int main(int argc, char *argv[]) {
if (argc < 4) {
cerr << "Not enough input, syntax is 1/2 players, # columns, and # of rows" << endl;
exit(0);
}
if (argc == 4 && (argv[1][0] == '1' || argv[1][0] == '2') && (argv[2][0] >= '1' && argv[2][0] <= '9') && (argv[3][0] >= '1' && argv[3][0] <= '9')) {
cout << "\n\nYou have chosen to play Connect 4 in " << argv[1][0] << " player mode and with " << argv[2][0] << " columns and with " << argv[3][0] << " rows.\n" << endl;
}
else {
cerr << "Improper syntax, syntax is 1/2 players, # columns, and # of rows" << endl;
exit(0);
}
cout << "Welcome to Connect 4, each player will take a turn choosing a column to select, a metaphorical coin will fall down to the highest availible row.\nThe game ends when a player has gotten 4 of their coins in a row horizontally, vertically, or diagonally.\nPlayer 1 will always use 1's and Player 2 will always be 2's.\nThe AI will always be 3's.\nEmpty slots will be shown as 0's.\n\n" << endl;
srand(time(NULL));
int winner = runGame(argv[1][0] - '0', argv[2][0] - '0', argv[3][0] - '0');
if (winner == 1 || winner == 2) {
cout << "Winner was player # " << winner << endl;
}
else if (winner == 3)
cout << "You let the AI win :(" << endl;
else if (winner == -1)
cout << "The game ended in a tie" << endl;
playAgain();
}
/******************************************************
** Function: runGame
** Description: runsGame
** Parameters: gameMode columns rows
** Pre-Conditions:
** Post-Conditions: returns winning player, 1 or 2 for player # and 3 for ai
******************************************************/
int runGame(int gameMode, int columns, int rows) { //returns which player won
int holdPoints[2] = { 0, 0 };
switch (gameMode) {
case 1:
cout << "You have chosen to play against an AI" << endl;
break;
case 2:
cout << "You have chosen to play with another human player" << endl;
break;
}
int** board = new int*[columns];
for (int i = 0; i< columns; i++) {
board[i] = new int[rows];
}
for (int i = 0; i< columns; i++) {
for (int j = 0; j< rows; j++) {
board[i][j] = 0;
}
}
for (int i = 0; i< rows*columns/2; i++) { //check for number of possible moves in order to have a tie
showBoard(board, rows, columns);
promptUser(board, holdPoints, rows, columns, 1);
if (checkGameOver(board, holdPoints[0], holdPoints[1], 0, 1, 0, 1, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, 1, 0, 1, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, 0, 0, 1, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 0, -1, 0, 1, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, -1, 0, 1, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, 0, 0, 1, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, -1, 0, 1, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, 1, 0, 1, rows, columns)) {
return 1;
}
cout << "\n\n";
showBoard(board, rows, columns);
if (gameMode == 2) {
promptUser(board, holdPoints, rows, columns, 2);
if (checkGameOver(board, holdPoints[0], holdPoints[1], 0, 1, 0, 2, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, 1, 0, 2, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, 0, 0, 2, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 0, -1, 0, 2, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, -1, 0, 2, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, 0, 0, 2, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, -1, 0, 2, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, 1, 0, 2, rows, columns)) {
return 2;
}
}
else if (gameMode == 1) {
genRanMove(board, holdPoints, rows, columns);
if (checkGameOver(board, holdPoints[0], holdPoints[1], 0, 1, 0, 3, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, 1, 0, 3, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, 0, 0, 3, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 0, -1, 0, 3, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, -1, 0, 3, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, 0, 0, 3, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], 1, -1, 0, 3, rows, columns) || checkGameOver(board, holdPoints[0], holdPoints[1], -1, 1, 0, 3, rows, columns)) {
return 3;
}
}
//showBoard(board, rows, columns);
cout << "\n\n";
}
for (int i = 0; i < columns; i++) {
delete[] board[i];
}
delete[] board;
return -1; //signifies a tie
}
/******************************************************
** Function: promptUser
** Description: gets input from user for their turn, stores the resting place of their token in points
** Parameters: board and array to hold point,num columns
** Pre-Conditions:
** Post-Conditions:
******************************************************/
void promptUser(int** board, int point[], int numRows, int numColumns, int playerNum) {
int col, lowZero;
lowZero = -1;
cout << "What column would you like to choose" << endl;
cin >> col;
if (col<0 || col > numColumns -1) {
cout << "The # you chose must be >=0 and <= " << numColumns-1 << endl;
promptUser(board, point, numRows, numColumns, playerNum);
}
//now need to find the lowest possible row in the given column that has a 0
for (int i = 0; i < numRows; i++) {
if (board[col][i] == 0)
lowZero = i;
}
if (lowZero != -1) {
board[col][lowZero] = playerNum;
cout << "Player " << playerNum << " dropped a token in column " << col << " that rested at row " << lowZero << endl;
point[0] = col;
point[1] = lowZero;
return;
}
else {
cout << "Column " << col << " was full, please pick a new one" << endl;
promptUser(board, point, numRows, numColumns, playerNum);
}
}
/******************************************************
** Function: genRanMove
** Description: gets random column from "ai", stores the resting place of their token in points
** Parameters: board and array to hold point
** Pre-Conditions:
** Post-Conditions:
******************************************************/
void genRanMove(int** board, int point[], int numRows, int numColumns) {
cout << "AI is finding a column" << endl;
int col = rand() % numColumns;
int lowZero = -1;
for (int i = 0; i < numRows; i++) {
if (board[col][i] == 0)
lowZero = i;
}
if (lowZero != -1) {
board[col][lowZero] = 3;
cout << "AI dropped a token in column " << col << " that rested at row " << lowZero << endl;
point[0] = col;
point[1] = lowZero;
return;
}
//didnt find a row that works
genRanMove(board, point, numRows, numColumns);
}
/******************************************************
** Function: showBoard
** Description: prints he current gameboard
** Parameters: the board, numrows and numcolumns
** Pre-Conditions:
** Post-Conditions:
******************************************************/
void showBoard(int** board, int numRows, int numColumns) {
for (int i = 0; i < numColumns; i++) {
for (int j = 0; j < numRows; j++) {
cout << board[j][i] << " ";
}
cout << endl;
}
}
/******************************************************
** Function: playAgain
** Description: gets info to play again
** Parameters: n/a
** Pre-Conditions:
** Post-Conditions:
******************************************************/
void playAgain() {
int again;
int mode, rows, columns;
cout << "Would you like to play again? Type 1 if so." << endl;
cin >> again;
if (again) {
cout << "What mode? 1 for 1 player and 2 for 2 player" << endl;
cin >> mode;
cout << "How many rows?" << endl;
cin >> rows;
cout << "How many columns?" << endl;
cin >> columns;
if ((mode<=0 || mode >2) || rows<= 0 || columns<= 0) {
cout << "Improper inputs. Mode must be 1/2 and rows and columns must both be >0" << endl;
playAgain();
}
else {
runGame(mode, columns, rows);
}
}
}
/******************************************************
** Function: checkGameOver
** Description: checks if game is over by recursively checking spots around original
** Parameters: board, curr col, curr row, change col, change row, total found, and what number it is looking for in the board
** Pre-Conditions:
** Post-Conditions:
******************************************************/
bool checkGameOver(int** board, int currCol, int currRow, int changeCol, int changeRow, int totalFound, int numSearch, int numRows, int numColumns) {
if (totalFound == 4) //base case
return true;
if (currRow <0 || currRow >numRows - 1 || currCol<0 || currCol> numColumns - 1)
return false;
if (board[currCol][currRow] == numSearch)
totalFound++;
else
return false; // the checked index didnt contain the same # we wanted
return checkGameOver(board, currCol + changeCol, currRow + changeRow, changeCol, changeRow, totalFound, numSearch, numRows, numColumns);
}
... or should I just scrap it and rewrite it differently?
That's the option I'd be going for :-)
While a recursive solution may be clever, you're probably better off, for a game-space of this size, keeping the code simple and just checking every single possibility rather than trying to recurse out from the newly-populated cell(a).
You can do this in "specialist" chunks so you don't have to worry about going off the edge of the board at any point. To do this, you limit the starting cell for each type so that it ends on an edge cell of the board, something like (pseudo-code):
# Check four cells given start and direction.
def didWin(row, col, rdelta, cdelta):
# Check if start cell not populated.
if cell[row][col] == empty:
return false
# Check if any cell in sequence doesn't match.
for i = 1 to 3 inclusive:
if cell[row][col] != cell[row+rdelta*i][col+cdelta*i]:
return false
# Otherwise, it's a win
return true
def getWinner():
# Check all possible horizontals.
for row = 0 to 5 inclusive:
for col = 0 to 3 inclusive:
if didWin(row, col, 0, 1): # cdelta=1, right.
return cell[row][col]
# Check all possible verticals.
for col = 0 to 6 inclusive:
for row = 0 to 2 inclusive:
if didWin(row, col, 1, 0): # rdelta=1, down.
return cell[row][col]
# Check all right-downs.
for row = 0 to 2 inclusive:
for col = 0 to 3 inclusive:
if didWin(row, col, 1, 1): # r/cdelta=1, right-down.
return cell[row][col]
# Check all right-ups.
for row = 3 to 5 inclusive:
for col = 0 to 3 inclusive:
if didWin(row, col, 1, -1): # rdelta=1, cdelta=-1, right-up.
return cell[row][col]
# No winner.
return empty
(a) Another good reason for doing this is that, in an educational institution, they almost always value clarity of thought over cleverness. That clarity of thought will serve you well in the start of your career and, indeed, forty years into your career, such as where I am :-)
I'm trying to solve one problem, which I found on website https://open.kattis.com/problems/coast. Tl;dr version of problem is, that for given map of landscape, I should print out length of coastline (without inner islands).
My idea was, to solve this by adding additional layer and then start DFS, so the algorithm will walk through every possible tile in map, and then watch on every tile, how many borders are around the tile.
However, for specific input, is my algorithm not working. When I've submitted the solution on this site (open.kattis), it says, that my program is giving wrong answer in 9th of 26 tests (previous 8 test were ok), but without any further explanation.
Can somebody look at my program, and say me, why is it bad? Where did I do mistake? Thanks
#include <iostream>
#include <stack>
#include <sstream>
using namespace std;
int main() {
string line;
getline(cin, line);
int rows = 0;
int columns = 0;
stringstream stream(line);
stream >> rows;
stream >> columns;
int map[rows][columns];
for (int i = 0; i < rows; i++) {
getline(cin, line);
for (int j = 0; j < columns; j++) {
map[i][j] = line[j] - 48;
}
}
//parsed landscape into 2d array
// int rows = 5;
// int columns = 6;
// int map[rows][columns] = {
// {0, 1, 1, 1, 1, 0,},
// {0, 1, 0, 1, 1, 0,},
// {1, 1, 1, 0, 0, 0,},
// {0, 0, 0, 0, 1, 0,},
// {0, 0, 0, 0, 0, 0,},
// };
int bigMap[rows+2][columns+2];
bool visited[rows+2][columns+2];
//create bigger map, so DFS can start from corner and assume
//that there is water around everywhere
//also initialize array visited for DFS
//add 2 new rows, before and after existing one
for (int i = 0; i < columns+2; i++) {
bigMap[0][i] = 0;
bigMap[rows + 1][i] = 0;
visited[0][i] = false;
visited[rows + 1][i] = false;
}
//add 2 new columns, before and after existing
//copy original map to new one
for (int i = 0; i < rows; i++) {
bigMap[i+1][0] = 0;
bigMap[i+1][columns + 1] = 0;
visited[i+1][0] = false;
visited[i+1][columns + 1] = false;
for (int j = 0; j < columns; j++) {
bigMap[i+1][j+1] = map[i][j];
visited[i+1][j+1] = false;
}
}
rows += 2;
columns += 2;
//starting DFS
int x = 0, y = 0;
//visited[x][y] = true; <-- edit
pair <int, int> coordinates;
coordinates.first = x;
coordinates.second = y;
stack<pair <int, int> > st;
//first vertex in stack
st.push(coordinates);
//total sum of borders
int borders = 0;
while(!st.empty()) {
//check coordinates in each round
x = st.top().first;
y = st.top().second;
//navigate to new vertex (only if new vertex wasn't visited (visited[x][y] == 0) and only
//if there is water (bigMap[x][y] == 0) and check if new vertex is still in the map
//if there is no possible vertex, then we reached the end so then pop the vertex and
//look in another way
if (visited[x][y+1] == 0 && bigMap[x][y+1] == 0 && y + 1 < columns) {
y++;
coordinates.second = y;
st.push(coordinates);
} else {
if (visited[x+1][y] == 0 && bigMap[x+1][y] == 0 && x + 1 < rows) {
x++;
coordinates.first = x;
st.push(coordinates);
} else {
if (visited[x][y-1] == 0 && bigMap[x][y-1] == 0 && y > 0) {
y--;
coordinates.second = y;
st.push(coordinates);
} else {
if (visited[x-1][y] == 0 && bigMap[x-1][y] == 0 && x > 0) {
x--;
coordinates.first = x;
st.push(coordinates);
} else {
st.pop();
continue;
}
}
}
}
//visited new vertex, so look around him and count borders
visited[x][y] = true;
if (bigMap[x][y+1] == 1 && y + 1 < columns) borders++;
if (bigMap[x+1][y] == 1 && x + 1< rows) borders++;
if (bigMap[x][y-1] == 1 && y > 0) borders++;
if (bigMap[x-1][y] == 1 && x > 0) borders++;
}
cout << borders << endl;
return 0;
The issue is that you are reusing the variable coordinates each time around the loop without setting it to the correct value. Your if test cascade is assuming that coordinates is set to the current location. This is only true while you are descending in your dfs. Once you start ascending again, the coordinate will be pointing to the wrong place.
Simple solution, add
coordinates = st.top();
at the top of your loop.
Here is a sample map that it will currently get wrong.
5 6
000000
011100
001010
000100
000000
Answer should be 14, but currently you get 18 as the program reaches the lake at row 3, column 4.
To check that it is doing this, add a debugging line at the end of your loop, where it is adding the borders.
cout << "adding " << x << " " << y << "\n";
You can then verify if the program is considering any locations it shouldn't.
I think it will fail for {1,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}. This is because the walk through is prevented from completing due to setting visited=true for vertex 0,0. Set it false for 0,0 instead should improve things. Hope it helps.
I have to construct a 2d array with N,M rows and columns (N & M <= 5), then the user enters a certain index(location) like 2,3 (matrix[2][3]) it's assumed that the two numbers are in the bounds of the matrix. From then on I have to find the sum of the left and right diagonal that goes through the number, however the number is excluded from the sum.
So for example the 2d array is myArray[3][3]
*1* 15 *2*
2 *71* 8
*5* 22 *5*
So the user enters 1,1 that is myArray[1][1], in this case the number 71, the sum would be 1 + 5 + 2 + 5 ... And well my problem is how can i find those diagonals without going out of the bounds.
For the left top i would go:
row--
column--
while(row >= 0|| column >= 0)
For left bottom:
row++
colum++
while(row < N || column < M)
for right top:
row--
column++
while(row >= 0 || column < M)
for right bottom:
row++
column--
while(row < N || column >=0)
(this is bad written pseudo-code, sorry)
It works fine when I enter numbers that aren't in the top or bottom row, but in the cases that they are located there my program stops.
What you have is basically good pseudocode. My first thought was that you should be using &&'s instead of ||'s when determining if the location is out of bounds or not.
You also need some sort of way to exit early in case they give a bad location. Below is some code I wrote out quickly, and seems to work at a quick glance - I loop over every possible starting location including ones that are out of bounds.
#include <iostream>
const int N = 3;
const int M = 4;
int matrix[N][M] = {
{ 0, 1, 2, 3 },
{ 4, 5, 6, 7 },
{ 8, 9, 10, 11 }
};
int directional_sum(int row, int column, int row_inc, int column_inc)
{
int sum = 0;
if (row < 0 || column < 0 || row >= N || column >= M)
return sum;
int temp_row = row + row_inc;
int temp_column = column + column_inc;
while (temp_row >= 0 && temp_column >= 0 && temp_row < N && temp_column < M)
{
sum += matrix[temp_row][temp_column];
temp_row += row_inc;
temp_column += column_inc;
}
return sum;
}
int diagonal_sum(int row, int column)
{
int sum = 0;
sum += directional_sum(row, column, 1, 1);
sum += directional_sum(row, column, 1, -1);
sum += directional_sum(row, column, -1, 1);
sum += directional_sum(row, column, -1, -1);
return sum;
}
int main()
{
for (int i = -1; i <= N; i++)
{
for (int j = -1; j <= M; j++)
{
std::cout << "Sum for [" << i << ", " << j << "]: " << diagonal_sum(i, j) << std::endl;
}
}
return 0;
}