Here's the code I'm working with in the header file:
#ifndef TETRIS_TETRIMINO
#define TETRIS_TETRIMINO
const int TETRIMINO_GRID_SIZE = 4;
struct Location {
int row;
int col;
};
class Tetrimino {
private:
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE];
char color;
Location location;
public:
// constructor
Tetrimino(int type = 7); // valid type values are 0-6
//---------------------------------------------
//accessors
char getColor();
Location getLocation();
void getGrid(int gridOut[][TETRIMINO_GRID_SIZE]);
//---------------------------------------------
//mutators
void setLocation(Location newLocation);
void setLocation(int row, int col);
void rotateLeft();
void rotateRight();
void moveLeft();
void moveRight();
void moveDown();
void moveUp();
//---------------------------------------------
//others
void dataDump();
};
#endif
And here's the .cpp:
#include "tetrimino.h"
#include <iostream>
#include <ctime>
using namespace std;
//random number generator
int randNum()
{
int randNum;
int high = 6;
int low = 0;
srand(static_cast<unsigned int>(time(NULL)));
randNum = rand() % (high - low + 1) + low;
return randNum;
}
Tetrimino::Tetrimino(int type)
{
//check to see if type is 0-6, if not set to 7
if (type < 0 || type >= 7)
{
type = randNum();
}
//set associated type to a tetrimino
if (type == 0)
{
//set grid to i tetro
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
{
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
};
//set color to teal
color = 't';
//initialize starting position
location.row = 0;
location.col = 0;
}
else if (type == 1)
{
//set grid to j tetro
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 1, 1 },
{ 0, 0, 0, 0 }
};
//set color to blue
color = 'b';
//initialize starting position
location.row = 0;
location.col = 0;
}
else if (type == 2)
{
//set grid to L tetro
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
{
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 }
};
//set color to orange
color = 'o';
//initialize starting position
location.row = 0;
location.col = 0;
}
else if (type == 3)
{
//set grid to o tetro
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
};
//set color to yellow
color = 'y';
//initialize starting position
location.row = 0;
location.col = 0;
}
else if (type == 4)
{
//set grid to s tetro
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 }
};
//set color to green
color = 'g';
//initialize starting position
location.row = 0;
location.col = 0;
}
else if (type == 5)
{
//set grid to T tetro
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 }
};
//set color to purple
color = 'p';
//initialize starting position
location.row = 0;
location.col = 0;
}
else if (type == 6)
{
//set grid to z tetro
int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 1, 1 },
{ 0, 0, 0, 0 }
};
//set color to red
color = 'r';
//initialize starting position
location.row = 0;
location.col = 0;
}
};
//accessors
char Tetrimino::getColor()
{
return color;
}
Location Tetrimino::getLocation()
{
return location;
}
void Tetrimino::getGrid(int gridOut[][TETRIMINO_GRID_SIZE])
{
//loop goes through each row
for (int row = 0; row < TETRIMINO_GRID_SIZE; row++)
{
//goes through each col of current row
for (int column = 0; column < TETRIMINO_GRID_SIZE; column++)
{
cout << gridOut[row][column] << " ";
}
//new line between rows
cout << endl;
}
}
//mutators
//leaving these out of this for sanity
void main()
{
Tetrimino test(0);
cout << test.getColor() << endl;
test.getGrid(test.grid);
}
Ok, so obviously the code is incomplete. I'm super stuck and confused on how to print out the grid array from the Tetrimino class using the public function getGrid. The Header file was given to me pre-made (although I understand it) so I don't want to edit it. Why is the getGrid function requiring a parameter in the first place?
I can't simply call the grid I want to print like I attempted in main() because it's private. I'm just really.. yeah I know it's wrong but I have no idea how to go about doing it correct.
EDIT/UPDATE:
I removed the parameter from getGrid() and changed the gridOut to simply grid in the function. However, when I call the function using test.getGrid() the array that prints is:
-858993460 -858993460 -858993460 -858993460
-858993460 -858993460 -858993460 -858993460
-858993460 -858993460 -858993460 -858993460
-858993460 -858993460 -858993460 -858993460
The code I changed was:
void Tetrimino::getGrid()
{
//loop goes through each row
for (int row = 0; row < TETRIMINO_GRID_SIZE; row++)
{
//goes through each col of current row
for (int column = 0; column < TETRIMINO_GRID_SIZE; column++)
{
cout << grid[row][column] << " ";
}
//new line between rows
cout << endl;
}
}
The getGrid was changed to grid.
I'm now calling the function like this:
void main()
{
Tetrimino test(0);
test.getGrid();
}
As you mention, that the header file was provided to you, I guess, this is an assignment. getGrid method is meant to provide interface for outside caller to get a copy of the Tetrmino objects grid. As you cannot return an array from function, the getGrid method provides an output parameter.
Example usage:
void Tetrimino::getGrid(int gridOut[][TETRIMINO_GRID_SIZE]) {
for(int i = 0; i < TETRMINO_GRID_SIZE; i++) {
for(int j = 0; j < TETRMINO_GRID_IZE; j++ ) {
gridOut[i][j] = grid[i][j];
}
}
}
...
...
Tetrmino obj(3);
...
...
int grid[TETRIMINO_GRID_SIZE][TETRMINO_GRID_SIZE];
obj.getGrid(grid);
// now grid holds the copy of interal grid
for(int i = 0; i < TETRMINO_GRID_SIZE; i++) {
for(int j = 0; j < TETRMINO_GRID_IZE; j++ ) {
std::cout << grid[i][j] << " ";
}
std::cout << "\n";
}
std::cout << std::flush;
Edit:
To expand on the answer: why grid is not assigned?
The problem is, that within your constructor you are declaring a new int array with the same name as the class member. This means, that you are not initializing the member variable. C++ does not allow to assign to raw array after its initialization, you are left just with copying.
Change the new variable to gridNew or something similar and copy from gridNew to grid element by element just like you are now copying from grid to gridOut in getGrid method.
That method is simply wrong, it was designed to print one parameter not the internal data, just remove the input parameter and use the internal matrix.
Btw you shouldn't use std::endl to print only \n, use \n directly. std::endl will flush the fd and take more time.
Do not call your private member from your main and do not send any argument from your main. It is your member you do not need anything for print it out , you just use it and if you confusing with using it directly , use it with this keyword in your function
for (int row = 0; row < TETRIMINO_GRID_SIZE; row++)
{
//goes through each col of current row
for (int column = 0; column < TETRIMINO_GRID_SIZE; column++)
{
cout << this->grid[row][column] << " ";
}
//new line between rows
cout << endl;
}
Related
I have a 2d array like this:
arr = [0 3 1 0
1 2 0 2
0 0 2 0
1 2 0 0]
My aim is don't iterate over a column once we find maximum number in it.
In the first iteration, max number is 3 in 2nd column, so don't go to second column in future iterations.
Similarly in my 2nd iteration, max number is 2 in 4th column (Because we dont go to 2nd column anymore).
This is what i tried:
#include <iostream>
using namespace std;
int main()
{
//Input 2d array
int arr[4][4];
//Take the input
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
cin>>arr[i][j];
}
//Index array to store index of maximum number column
int index[4] = {-1,-1,-1,-1}
//Array to store max number in each row
int max_arr[4] = {0,0,0,0};
for(int i=0; i<4; i++)
{
int max_num = -1;
for(int j=0; j<4; j++)
{
if(j!=index[0] && j!=index[1] && j!=index[2] && j!=index[3])
{
if(max_num<arr[i][j])
{
max_num = arr[i][j];
index[j] = j;
}
}
}
max_arr[i] = max_num;
}
return 0;
}
The best way to go about this is to simply evaluate the array by columns. This can be done with a little math. In your case, you use a 4x4 array. Start at index 0, add 4, add 4, add 4, then subtract 11 (bringing you to position 1). Add 4, add 4, add 4, subtract 11 (bringing you to position 2). Etc...
Here is the code I used, which works and is doable for any size array!
#include <iostream>
int main()
{
constexpr size_t ARR_ROWS = 4;
constexpr size_t ARR_COLS = 4;
constexpr size_t ARR_SIZE = ARR_ROWS * ARR_COLS;
int arr[ARR_SIZE] {
0, 3, 1, 0,
1, 2, 0, 2,
0, 0, 2, 0,
1, 2, 0, 0
};
// Store max values for columns
int cols_max[ARR_COLS] { -1, -1, -1, -1 };
// Start at index 0, then at 4 (3 times) to evaluate first
// column. Next, subtract 11 from current index (12) to get
// to index 1 (start of column 2). Add 4 (3 times) to
// evaluate second column. Next, subtract 11 from current
// index (13) to get to index 2 (start of column 3). Etc...
size_t cur_index = 0;
size_t cur_col = 0;
const size_t subtract_to_start_next_col = ARR_SIZE - (ARR_COLS + 1);
while (cur_index < ARR_SIZE)
{
// Max function for 'cols_max'
if (cols_max[cur_col] < arr[cur_index])
cols_max[cur_col] = arr[cur_index];
if ( // When index is at the column's end (besides last value)
(cur_index >= ARR_SIZE - ARR_COLS) &&
(cur_index <= ARR_SIZE - 2)
)
{
cur_index -= subtract_to_start_next_col;
cur_col++;
}
else if (cur_index == ARR_SIZE - 1)
{ // When index is last value, add 1 to break loop
cur_index++;
}
else
{ // Nothing special, just go to next value in column
cur_index += ARR_COLS;
}
}
// Print columns' max values (optional)...
for (size_t i = 0; i < ARR_COLS; ++i)
{
std::cout
<< "Max for column " << (i + 1) << ": " << cols_max[i]
<< std::endl;
}
}
Feel free to ask if you have any questions!
You need 3 loops, first for iterations, second for rows, third for columns. If you have found max at column let's say 0, then you should blacklist that column and so on.
#include <iostream>
int main()
{
int m[ 4 ][ 4 ] = { { 0, 3, 1, 0 } ,
{ 1, 2, 0, 2 } ,
{ 0, 0, 2, 0 } ,
{ 1, 2, 0, 0 } };
constexpr int max_number_of_itr { 4 };
bool blacklisted[4] { false };
for ( auto itr = 0; itr < max_number_of_itr; ++itr )
{
auto max { -1 };
auto max_col_idx { -1 };
for ( auto row = 0; row < 4; ++row )
{
for ( auto col = 0; col < 4; ++col )
{
if ( blacklisted[ col ] )
continue;
auto val = m[ row ][ col ];
if ( val > max )
{
max = val;
max_col_idx = col;
}
}
}
blacklisted[ max_col_idx ] = true;
std::cout << "max is " << max << " col " << max_col_idx << " ignored." << std::endl;
}
}
index[ j ] = j;
change this to
index[ i ] = j;
Hey so I want to create a text version of minesweeper. I created a grid that outputs ones and zeros(mines are represented by 0 and anything that is not a mine is a 1). How would I go about checking how many mines are around each non-mine (or how many 0's are around each number 1). Then updating the numbers to show how many mines are adjacent to them.
If someone could at least tell me where to start I would appreciate it :)
#include "pch.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
string mystring;
int grid[5][5] = {
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1}
};
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
int rNum = (rand() % 10) + 1;
if (rNum == 1 || rNum == 2)
{
grid[i][j] = 0; // mines are 0
}
else grid[i][j] = 1; // non-mines are represented by 1
std::cout << setw(4) << grid[i][j] << setw(4);
}
std::cout << std::endl;
}
}
I did a very similar thing in Java; although instead of representing the bombs with 0s I used 9s, because it is possible for a non-mine to be surrounded by 0 mines, it is not possible for one to be surrounded by 9 or higher mines. Here is my method:
for(int x = 0; x < 5; x++) {
for(int y = 0; y < 5; y++) {
if(grid[x][y] != 9) {
byte count = 0;
for(int lx = -1; lx <= 1; lx++) { //think of lx and ly as temporary x y
if((x+lx) >= 0 && (x+lx) < 5) {
for(int ly = -1; ly <= 1; ly++) {
if((y+ly) >= 0 && (y+ly) <5) {
if(grid[x+lx][y+ly] == 9) {
count += 1;
}
}
}
}
}
grid[x][y] = count;
}
}
}
Basically what it does is it scrolls through each point on the grid, checking if it is a bomb. If it is not, it checks each of the 8 squares touching it(as long as they are in the bounds of the grid, don't want an undefined index error). Then if they are a bomb it adds one to the count. Finally, it sets the number on the tile equal to the count of touching bombs.
In my case I pass pointer to 2d array of type wchar_t but can be any type as you want. Assuming that you have 2d array, you can refer to each cell by [X,Y] but also you need to check if the cell have all neighbours (for example left top cell of table have only 3 neighbours):
void getNeighbours(wchar_t* scr,int x, int y)
{
// Left
if((x-1)>=0)
{
// value = scr[getIndex(x-1,y)];
}
// Right
if((x+1)<tableWidth)
{
// value = scr[getIndex(x+1,y)];
}
//Up
if((y-1)>=0)
{
// value = scr[getIndex(x,y-1)];
}
//Down
if((y+1)<tableHeight)
{
// value = scr[getIndex(x,y+1)];
}
// Left down
if((x-1)>=0 && ((y-1)>=0))
{
// value = scr[getIndex(x-1,y+1)];
}
// Right Down
if((x+1)<tableWidth && (y+1)<tableHeight)
{
// value = scr[getIndex(x+1,y+1)];
}
// Right UP
if((x+1)<tableWidth && (y-1)>=0)
{
// value = scr[getIndex(x+1,y-1)];
}
// Left Up
if((x-1)>=0 && (y-1)>=0)
{
// value = scr[getIndex(x-1,y-1)];
}
}
getIndex() function to get index of cell indicated by [X,Y]:
int getIndex(int x, int y)
{
return (tableWidth*y+x);
}
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.
C++ beginner here. I'm currently trying to make a sudoku solving program, so I have to check whether a value exists in the 9x9 box it's located in.
This is my code for checking if the element follows the rules:
//constants for rows and columns of the sudoku puzzle, can be changed
const int ROWS = 9;
const int COLS = 9;
bool follows_rule(int grid[ROWS][COLS], int rowIndex, int colIndex, int value){
for (int i = 0; i < COLS; i++){
if (grid[rowIndex][i] == value) //check if there are any other values on the same column
return false;
if (grid[i][colIndex] == value) //or the same row
return false;
}
//to-do: check if another equal value exists in the 9x9 box
return true;
}
//returns true if another element has the same value as "value", false otherwise
bool exists_in_2d_array(int grid[ROWS][COLS], int value){
for (int x = 0; x < ROWS / 3; x++)
{
for (int y = 0; y < COLS / 3; y++)
{
if (grid[x][y] == value)
{
return true;
}
}
}
return false;
}
My idea was to find out which 9x9 box the coordinates of the current element lead to, then put that 9x9 grid in another 2D array and check if the element's value exists somewhere else in the grid. I don't really know how, though.
The SUDOKU rules require that the digit is used only once:
Rule 1: in each row
Rule 2: in each column
Rule 3: in each 3x3 subgrid of the 9x9 grid
Function follows_rule() checks for a given grid position, if the value would be allowed or not. For the moment it checks only rules 1 and 2. I propose you the following code for rule 3:
bool follows_rule(int grid[ROWS][COLS], int rowIndex, int colIndex, int value){
for (int i = 0; i < COLS; i++){
if (grid[rowIndex][i] == value)
return false;
if (grid[i][colIndex] == value) // ATTENTION THIS IS OK BECAUSE ROWS==COLS !!
return false;
}
// Check if another equal value exists in the 3x3 box
int sgc = (colIndex / 3) * 3; // in wich subgrid are we ?
int sgr = (rowIndex / 3) * 3;
// check all the elements of the 3x3 grid startic at sgr, sgc
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (grid[sgr + i][sgc + j] == value)
return false;
return true;
}
You can test the 3x3 verification with the following code:
int sudoku[ROWS][COLS] = {
{ 1, 0, 0, 0, 0, 0, 0, 8, 0 },
{ 0, 0, 2, 0, 0, 0, 0, 0, 0 },
{ 0, 3, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 3, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 5, 0, 0, 0 },
{ 0, 0, 0, 0, 8, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
if (follows_rule(sudoku, 1, 0, 1) == false
&& follows_rule(sudoku, 1, 0, 4) == true
&& follows_rule(sudoku, 5, 5, 8) == false
&& follows_rule(sudoku, 5, 5, 1) == false
&& follows_rule(sudoku, 5, 5, 7) == true)
cout << "Test ok !" << endl;
else cout << "Tests failed" << endl;
Accepted answer does not calculate the subgrids correctly , sgc and and sgr needs to be multiplied with 3 too after division to crrectly identify the subgrid vertices
public boolean isValidEntry(char[][] board, int row , int col,char val)
{
for(int i = 0 ; i < 9 ;i++){
if(board[row][i] == val)
return false;
}
for(int j = 0 ; j < 9 ;j++){
if(board[j][col] == val)
return false;
}
int sgc = col / 3; // in wich subgrid are we ?
int sgr = row / 3;
// check all the elements of the 3x3 grid startic at sgr, sgc
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++)
if (board[(3*sgr) + i][(3*sgc) + j] == val)
return false;
}
return true;
}
I need to write recursive function in c++ that finds largest area of number '1' in 2d array that contains only 1 or 0.
Example:
int Arr[5][8] =
{
{ 0, 0, 0, 0, 1, 1, 0, 0, },
{ 1, 0, 0, 1, 1, 1, 0, 0, },
{ 1, 1, 0, 1, 0, 1, 1, 0, },
{ 0, 0, 0, 1, 1, 1, 1, 0, },
{ 0, 1, 1, 0, 0, 0, 0, 0, },
};
Visual example: http://s23.postimg.org/yabwp6h23/find_largest.png
Largest area of this array is 12, second largest is 3 and third largest is 2.
I was thinking to do this with something similar to flood fill algorithm, but just can't figure out how.
bool visited[5][8];
int i,j;
// variables for the area:
int current_area = 0, max_area = 0;
int Arr[5][8]={ // type your map of values here
}
// functions
void prepare_visited_map() {
for(i=0;i<5;i++) {
for(j=0;j<8;j++) visited[i][j] = false;
}
}
// recursive function to calculate the area around (x,y)
void calculate_largest_area(int x, int y) {
if(visited[x][y]) return;
// check if out of boundaries
if(x<0 || y<0 || x>=5 || y>=8) return;
// check if the cell is 0
if(!Arr[x][y]) {
visited[x][y] = true;
return;
}
// found a propper cell, proceed
current_area++;
visited[x][y] = true;
// call recursive function for the adjacent cells (north, east, south, west)
calculate_largest_area(x,y-1);
calculate_largest_area(x+1,y);
calculate_largest_area(x,y+1);
calculate_largest_area(x-1,y);
// by the end of the recursion current_area will hold the area around the initial cell
}
// main procedure where the above functions are used
int mian() {
// calculate the sorrounding area of each cell, and pick up the largest of all results
for(i=0;i<5;i++) {
for(j=0;j<8;j++) {
prepare_visited_map();
calculate_largest_area(i,j);
if(current_area > max_area) max_area = current_area;
}
}
printf("Max area is %d",max_area");
}
Hope this was helpful :)
I was thinking to do this with something similar to flood fill algorithm
I think that's a pretty good way to do it. Apply flood fill to any 1, counting the ones and replacing them with zeros.
Repeat until the grid consists entirely of zeroes.
The following will print out the sizes of the connected components in no particular order:
#include <iostream>
constexpr int N = 5;
constexpr int M = 8;
int arr[N][M] =
{
{ 0, 0, 0, 0, 1, 1, 0, 0, },
{ 1, 0, 0, 1, 1, 1, 0, 0, },
{ 1, 1, 0, 1, 0, 1, 1, 0, },
{ 0, 0, 0, 1, 1, 1, 1, 0, },
{ 0, 1, 1, 0, 0, 0, 0, 0, },
};
int fill(int arr[N][M], int r, int c) {
int count = 0;
if (r < N && arr[r][c]) {
for (int i = c; i >= 0 && arr[r][i]; --i) {
arr[r][i] = 0;
count += fill(arr, r + 1, i) + 1;
}
for (int i = c + 1; i < M && arr[r][i]; ++i) {
arr[r][i] = 0;
count += fill(arr, r + 1, i) + 1;
}
}
return count;
}
int print_components(int arr[N][M]) {
for (int r = 0; r < N; ++r) {
for (int c = 0; c < M; ++c) {
if (arr[r][c]) {
std::cout << fill(arr, r, c) << std::endl;
}
}
}
}
int main() {
print_components(arr);
}
something like,
int max_area = 0;
foreach y
foreach x
if (pos[y][x] == 1 && !visited[y][x])
{
int area = 0;
Queue queue = new Queue();
queue.push(new Point(x, y));
visited[y][x] = true;
while (!queue.empty())
{
Point pt = queue.pop();
area++;
foreach neightboor of pt (pt.x±1, pt.y±1)
if (pos[neightboor.y][neightboor.x] == 1 && !visited[neightboor.y][neightboor.x])
{
visited[neightboor.y][neightboor.x] = true;
queue.push(new Point(neightboor.x, neightboor.y));
}
}
if (area > max_area)
max_area = area;
}
Quick approach, but I don't know if there is a way to do this in a sane way (recursive
call for each element does not scale for C++ because call stack is limited)
int maxy = 5
int maxx = 8
int areasize(int x, int y) {
if (x < 0 || y < 0 || x > maxx || y > maxy || !Arr[y][x])
return 0;
Arr[y][x] = 0;
return 1
+ areasize(x + 1, y)
+ areasize(x - 1, y)
+ areasize(x, y + 1)
+ areasize(x, y - 1);
}
maxarea = 0;
for (int y = 0; y < maxy; y++) {
for (int x = 0; x < maxx; x++) {
maxarea = std::max(maxarea, areasize(x, y));
}
}