Consider an array
0000
0000
0000
Then a number generated in a complete random position in the array
0000
0000
00x0
What I want to do is knowing the position of the number, make it go through the array in a spiral order. I can't find something in c++, it's the only language I know.
I already know how to go in spiral order from element [0][0] to [1][2] (clockwise), but how do I do it if my initial position is random? Then, how do I go backwards, anti-clockwise? And so on, but the start should be from that random position(2 numbers generated random will be the positions).
This code only works if you point is in the center of your array. If you add correct bounds checking this should work as you describe. I made the assumption(based on your first example) that when you finish all existing elements you move to the outer set. ie
0000
0000
00x0
becomes
2222
2111
21x1
touching them in this order
6 7 8 9
11 1 2 3
10 5 X 4
with 2 represent the second circle and 1 the first circle.
the output from this program is (i just stored the"radius" in each element)
pre traversal
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
post traversal
2 2 2 2 2
2 1 1 1 2
2 1 0 1 2
2 1 1 1 2
2 2 2 2 2
// what is the maximum possible radius
int getMaxRadius(int x, int y, int size)
{
int toReturn = std::abs(size-x);
if(std::abs(size-y) > toReturn)
toReturn = std::abs(size -y);
return toReturn ;
}
//is the curernt element next to the current center
bool nextTo(int xCenter, int yCenter, int x, int y, int radius )
{
//if it
if(std::abs(xCenter - x) > radius || std::abs(yCenter - y) > radius)
{
return false;
}
return true;
}
void circular(int** array, int xCenter, int yCenter, int size)
{
int curRadius = 1;
int maxRadius = getMaxRadius(xCenter, yCenter,size);
while( curRadius<maxRadius)
{
//start to the top left of the cur radius
int curX = xCenter - curRadius;
int curY = yCenter - curRadius;
//go right
while(nextTo(xCenter, yCenter, curX, curY, curRadius ))
{
array[curX][curY] = curRadius;
curX ++;
}
curX--;//we went one too far
//go down
while(nextTo(xCenter, yCenter, curX, curY, curRadius ))
{
array[curX][curY] = curRadius;
curY ++;
}
curY--;//we went one too far
//go left
while(nextTo(xCenter, yCenter, curX, curY, curRadius ))
{
array[curX][curY] = curRadius;
curX --;
}
curX++;//we went one too far
//goUP
while(nextTo(xCenter, yCenter, curX, curY, curRadius ))
{
array[curX][curY] = curRadius;
curY --;
}
curY++;//we went one too far
curRadius ++;
}
}
Related
So in my program, I generate a random grid using 2D Arrays where all indexes are initialized to 0. Now, a certain percentage of random indexes are filled with -1 which means that they are impassable/ act like a wall. The user also inputs a certain target index say (i,j) from where he starts and his goal is to reach index (0,0) by taking the shortest path possible.
To find the shortest path, I have to check for the neighbours of each cell, starting from the target location. If they have neighbours, I increment the neighbour value by 1. Refer to my figure for more details. I got the code on how to calculate the shortest path, but I'm stuck with this incrementation part. I tried writing a code but it doesn't seem to work. Any help would be appreciated:-
GRID is generated in the following way:
1 is the user input location, and the goal is to reach X i.e 0,0
-X 0 0 0 0 0 0 0 0 -1
-0 0 0 -1 -1 0 0 0 0 0
-0 0 0 0 -1 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 -1
-0 0 0 0 0 0 0 1 0 0
Starting by incrementing
-X 0 0 0 0 0 0 0 0 -1
-0 0 0 -1 -1 0 0 0 0 0
-0 0 0 0 -1 3 3 3 3 3
-0 0 0 0 0 3 2 2 2 -1
-0 0 0 0 0 3 2 1 2 3
I have only showed it till 3, but it keeps on going until index 0,0 is reached.
void waveAlgorithm(int *array, int height, int width, int x, int y)
{
while (array != NULL)
{
// Assume that index 0 0 is never 1
if (currX == 0 && currY == 0){
break;
}
// Check South
int currX = x;
int currY = y + 1;
if (currX < width && currX > 0 && currY < height && currY >= 0)
{
if (*(array + currX * width + currY) == 0)
{
(*(array + currX * width + currY))++;
}
}
// Check North
currX = x;
currY = y - 1;
if (currX < width && currX > 0 && currY < height && currY >= 0)
{
if (*(array + currX * width + currY) != -1)
{
(*(array + currX * width + currY))++;
}
}
// Check West
currX = x - 1;
currY = y;
if (currX < width && currX > 0 && currY < height && currY >= 0)
{
if (*(array + currX * width + currY) != -1)
{
(*(array + currX * width + currY))++;
}
}
// Check East
currX = x + 1;
currY = y;
if (currX < width && currX > 0 && currY < height && currY >= 0)
{
if (*(array + currX * width + currY) != -1)
{
(*(array + currX * width + currY))++;
}
}
}
}
I am kinda stuck while implementing this program, especially for the the directions that are combinational i.e North East, South East, etc. I tried writing a recursive program but couldn't figure out how to increment the cells
waveAlgorithm(int *arr)
{
if(index is 0,0)
return;
waveAlgorithm(int[i+1][j]);
waveAlgorithm(int[i][j+1]);
waveAlgorithm(int[i-1][j]);
waveAlgorithm(int[i][j-1]);
}
I was writing a casual minesweeper, and wanted to realize a method to track an empty cells at the field, so I had wrote this algorothm:
//bigger array was taken to prevent out of range,when init mines and numbers
/*creating mines in 1 to FIELD_NUM range(0 -non-active field,1-active field)
* {
* 0 0 0 0 0 0
* 0 1 1 1 1 0
* 0 1 1 1 1 0
* 0 1 1 1 1 0
* 0 1 1 1 1 0
* 0 0 0 0 0 0
* }
*/
//view is a display vect,x and y are mouse interp. coord.
void MinerField::OpenCell(vector<vector<int>>& view, int x, int y)
{
if (gridLogic[x][y] == 9)
{
for (int i = 1; i <= FIELD_NUM; i++)
for (int j = 1; j <= FIELD_NUM; j++)
{
view[i][j] = gridLogic[i][j];
}
}
else
{
if (gridLogic[x][y] == 0)
OpenVoidCells(view, x, y);
else
view[x][y] = gridLogic[x][y];
}
}
And the second func,that is causing Stack-Overflow:
void MinerField::OpenVoidCells(vector<vector<int>>& view, int x, int y)
{
if (x >= (FIELD_NUM) || y >= (FIELD_NUM))//check out of range
return;
if (gridLogic[x][y] == 10 || gridLogic[x][y]==11 ||gridLogic[x][y]==-1)
return;
if ((gridLogic[x][y] <= 8) && (gridLogic[x][y] >= 1))
{
view[x][y] = gridLogic[x][y];
return;
}
view[x][y] = gridLogic[x][y];
OpenVoidCells(view,x + 1, y); //North;
OpenVoidCells(view,x - 1, y); //South
OpenVoidCells(view,x, y + 1); //East
OpenVoidCells(view, x, y - 1); //West
OpenVoidCells(view, x - 1, y - 1); //South-West
OpenVoidCells(view, x + 1, y + 1); //North-East
OpenVoidCells(view, x - 1, y + 1); //South-East
OpenVoidCells(view, x + 1, y - 1); //North-West
}
gridLogic vector is MinerField local and have the same size as view. Run fails with FIELD_NUM=10.
What can cause a stack overflow?
OpenVoidCells doesn't have anything to prevent visiting the same square over and over. It will go north, south, north, south, north, south ... forever, until you run out of stack. You need to keep track of visited squares and avoid re-checking them.
There is a figure that is represented by 1 values that are “connected” vertically, horizontally or diagonally in a 2 dementional array.
I need to save the index of the boundary of the figure (the row and column of the 0's that are connected to the figure, in any type of c++ container.
For instance, in the following 2d array, I should get the following indexes:
(0,2), (0,3), (0,4), (1,2), (1,4), (1,5), (2,2), (2,3), (2,5), (2,6)... etc.
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 1 1 1 0 0
0 0 0 0 1 1 0 0
0 0 0 1 1 1 0 0
0 0 0 1 1 0 0 0
0 0 0 1 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
What is the most efficient way to do so, on both space and time complexity?
void dfs(vector<vector<int>>& matrix, vector<vector<int>>& boundary, int rows, int cols, int i, int j){
if(!isValidCoordinate(i, j))
return;
if(isAnyNeighborOne(i, j)){
boundary.push_back({i, j});
matrix[i][j] = 2;
}
else
matrix[i][j] = 3;
//Explore eight directions
/* I didn't bother about x = 0 and y = 0.
* You can, if you want.
* Doesn't make a difference though.
*/
for(int x = -1; x < 2; x++){
for(int y = -1; y < 2; y++){
dfs(matrix, boundary, rows, cols, i + x, i + y);
}
}
}
vector<vector<int>> getBoundary(vector<vector<int>>& matrix){
vector<vector<int>> boundary;
int rows = matrix.size();
if(!rows)
return boundary;
int cols = matrix[0].size();
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
if(matrix[i][j] == 0){
dfs(matrix, boundary, rows, cols, i, j);
}
}
}
return boundary;
}
If you print the matrix at the end, you'll see the boundary with 2.
Whatever you see as 3, if you want, you can set it back to 0.
isValidCoordinate() and isAnyNeighborOne() is left to you as an exercise.
I use vector<vector<int>> for boundary. You can try using vector<pair<int,int>> as well.
With the above solution you'll get inner boundary as well as outer boundary. As an exercise, you can try only inner boundary or only outer boundary.
You can solve the same problem with BFS as well. If the matrix is of large size, stack might overflow due to recursive calls. Better to prefer BFS in such cases.
Time and space complexity of the above solution is O(rows * cols).
Description:
Given matrix [x] [y], with x- rows and y- number of columns . Filled random numbers from 0 to 5 inclusive .
Description of finding a solution : the solution is considered to be a set of matrix elements that are adjacent to each other ( diagonal neighborhood is not taken into account ) and the sum of the number are 10. Each element of the matrix can be used 1 time for a decision . The solution may have any number of digits. The decision must end any number other than zero .
Example:
given
0 1 2 3 4 5
1 2 3 4 5 0
2 3 4 5 1 2
Solution 1 : (1 - 2 - 3 - 4)
0 **1** 2 3 4 5
1 **2** 3 4 5 0
2 **3** **4** 5 1 2
i tried to do smth like this, but it is wrong, i dont know when i must stop,
Solution it is a class which contains mair of indexes, pls help me.
void xxx(int colCount, int rowCount, int currentRow, int currentCol, int** matrix, int sum, Solution *solution, int solCount) {
sum += matrix[currentRow][currentCol];
matrix[currentRow][currentCol] = -1;
if(sum > 10){
sum - = matrix[currentRow][currentCol];
return;
} else if(sum == 10){
solution[solCount].additem(currentRow, currentCol);
return xxx(5,5,currentRow - 1, currentCol, matrix, sum, solution, solCount+1);
} else {
//UP
if( currentRow > 0 && matrix [currentRow - 1][currentCol] != -1){
xxx(5,5,currentRow - 1, currentCol, matrix, sum, solution,solCount);
}
//LEFT
if(currentCol > 0 && matrix [currentRow][currentCol-1] != -1){
xxx(5,5,currentRow, currentCol - 1, matrix, sum, solution,solCount);
}
//DOWN
if(currentRow + 1 < colCount && matrix[currentRow + 1][currentCol] != -1){
xxx(5,5,currentRow + 1, currentCol, matrix, sum, solution,solCount);
}
//RIGHT
if(currentCol + 1 < rowCount && matrix[currentRow][currentCol + 1] != -1){
xxx(5,5,currentRow, currentCol + 1, matrix, sum, solution,solCount);
}
}
}
Given a matrix of size M and N, we want to fill in each row with integer value (>=0) so that it sums up to certain value.
Note that the dimension of M and N are pre-computed using certain formula, so that it is guaranteed to match the fill given the desired condition (i.e. sum_val below).
This is implemented in R under Partition library.
library(partitions)
# In this example, we impose condition
# that each rows must sum up to 2 in total
# And each row has 5 columns
sum_val <- 2
n <- 5
#The above two parameters are predefined.
t(as.matrix(compositions(sum_val, n)))
[,1] [,2] [,3] [,4] [,5]
[1,] 2 0 0 0 0
[2,] 1 1 0 0 0
[3,] 0 2 0 0 0
[4,] 1 0 1 0 0
[5,] 0 1 1 0 0
[6,] 0 0 2 0 0
[7,] 1 0 0 1 0
[8,] 0 1 0 1 0
[9,] 0 0 1 1 0
[10,] 0 0 0 2 0
[11,] 1 0 0 0 1
[12,] 0 1 0 0 1
[13,] 0 0 1 0 1
[14,] 0 0 0 1 1
[15,] 0 0 0 0 2
Is there any existing implementation in C++?
Recursive version
Here is a recursive solution. You have a sequence a where you keep track of the numbers you already have set. Each recursive call will assign valid numbers to one of these elements in a loop, before recursively calling that function for the remainder of the list.
void recurse(std::vector<int>& a, int pos, int remaining) {
if (remaining == 0) { print(a); return; }
if (pos == a.size()) { return; }
for (int i = remaining; i >= 0; --i) {
a[pos] = i;
recurse(a, pos + 1, remaining - i);
}
}
void print_partitions(int sum_val, int n) {
std::vector<int> a(n);
recurse(a, 0, sum_val);
}
Proof of concept run visible at http://ideone.com/oJNvmu.
Iterative version
Your comment below indicates a performance problem. While it seems very likely that I/O is eating most of your performance, here is an iterative solution which avoids the function call overhead of the recursive approach.
void print_partitions(int sum_val, int n) {
int pos = 0, last = n - 1;
int a[n]; // dynamic stack-allocated arrays are a gcc extension
for (int i = 1; i != n; ++i)
a[i] = 0;
a[0] = sum_val;
while (true) {
for (int i = 0; i != last; ++i)
printf("%3d ", a[i]);
printf("%3d\n", a[last]);
if (pos != last) {
--a[pos];
++pos;
a[pos] = 1;
}
else {
if (a[last] == sum_val)
return;
for (--pos; a[pos] == 0; --pos);
--a[pos];
int tmp = 1 + a[last];
++pos;
a[last] = 0;
a[pos] = tmp;
}
}
}
The general idea and the order in which things are printed is the same as for the recursive approach. Instead of maintaining a counter remaining, all the tokens (or whatever it is you are partitioning) are immediately dropped in the place where they belong for the next partition to be printed. pos is always the last non-zero field. If that is not the last, then you obtain the next partition by taking one token from pos and moving it to the place after that. If it is the last, then you take all tokens from that last place, find the last non-zero place before that and take one token from there as well, then dump all these tokens onto the place after the one where you took the single token.
Demo run at http://ideone.com/N3lSbQ.
You can implement it yourself:
such a partition is defined by 6 integers 0 <= x[0] <= x[1] <= x[2] <= x[3] <= 2;
the values in the corresponding row are just the differences x[0]-0, x[1]-x[0], x[2]-x[1], etc.
If the number of columns (5) is fixed, you have 4 nested loops;
it it is not, you can formulate the problem recursively.