Rotating a 2-d array by 90 degrees - arrays

A frequent question that props up during array manipulation exercises is to rotate a two dimensional array by 90 degrees. There are a few SO posts that answer how to do it in a variety of programming languages. My question is to clarify one of the answers that is out there and explore what sort of thought-process is required in order to get to the answer in an organic manner.
The solution to this problem that I found goes as follows:
public static void rotate(int[][] matrix,int n)
{
for( layer = 0;layer < n/2;++layer){
int first = layer;
int last = n -1 - layer;
for(int i = first;i<last;++i){
int offset = i - first;
int top = matrix[first][i];
matrix[first][i] = matrix[last-offset][first];
matrix[last-offset][first] = matrix[last][last-offset];
matrix[last][last-offset] = matrix[i][last];
matrix[i][last] = top;
}
}
}
I have somewhat of an idea what the code above is trying to do, it is swapping out the extremities/corners by doing a four-way swap and doing the same for the other cells separated by some offset.
Stepping through this code I know it works, what I do not get is the mathematical basis for the above given algorithm. What is the rationale behind the 'layer','first','last' and the offset?
How did 'last' turn out to be n-1-layer? Why is the offset i-first? What is the offset in the first place?
If somebody could explain the genesis of this algorithm and step me through the thought process to come up with the solution, that will be great.
Thanks

The idea is to break down the big task (rotating a square matrix) into smaller tasks.
First, a square matrix can be broken into concentric square rings. The rotation of a ring is independent from the rotation of other rings, so to rotate the matrix just rotate each of the rings, one by one. In this case, we start at the outermost ring and work inward. We count the rings using layer (or first, same thing), and stop when we get to the middle, which is why it goes up to n/2. (It is worth checking to make sure this will work for odd and even n.) It is useful to keep track of the "far edge" of the ring, using last = n - 1 - layer. For instance, in a 5x5 matrix, the first ring starts at first=0 and ends at last=4, the second ring starts at first=1 and ends at last=3 and so on.
How to rotate a ring? Walk right along the top edge, up along the left edge, left along the bottom edge and down along the right edge, all at the same time. At each step swap the four values around. The coordinate that changes is i, and the number of steps is offset. For example, when walking around the second ring, i goes {1,2,3} and offset goes {0,1,2}.

Related

Lower memory usage when searching for optimal route from one point of matrix to another

I have following problem:
Tourist wants to create an optimal route for the hike. He has a
terrain elevation map at a certain scale - an NxM-sized matrix
containing the elevation values ​​at the corresponding terrain points.
Tourist wants to make a route from the start point to the end point in
such a way that the total change in altitude while passing the route
is minimal. The total change in altitude on the route is the sum of
the changes in altitude modulo on each segment of the route. For example, if there is a continuous ascent or descent from the starting
point of the route to the end point, then such a route will be
optimal.
For simplicity, let's assume that you can only walk along the lines of
an imaginary grid, i.e. from position (i, j), which is not on the edge
of the card, you can go to position (i-1, j), (i + 1, j), (i, j-1),
(i, j + 1). You cannot go beyond the edge of the map.
On standard input: non-negative integers N, M, N0, M0, N1, M1 are entered. N is the number of rows in the heightmap, M is the number of columns. Point (N0, M0) is the starting point of route, point (N1, M1) is the end point of the route. Point coordinates are numbered starting
from zero. The points can be the same. It is known that the total
number of matrix elements is limited to 1,100,000.
After numbers height map is entered in rows - at first the first line, then
the second, and so on. Height is a non-negative integer not exceeding
10000.
Print to standard output the total change in elevation while
traversing the optimal route.
I came to conclusion that it's about shortest path in graph and wrote this
But for m=n=1000 program eats too much (~169MiB, mostly heap) memory.
Limits are as following:
Time limit: 2 s
Memory limit: 50M
Stack limit: 64M
I also wrote C++ program doing same thing with priority_queue(just to check, problem must be solved in C), but it still needs ~78MiB (mostly heap)
How should I solve this problem (use another algorithm, optimize existing C code or something else)?
You can fit a height value into a 16-bit unsigned int (uint_16_t, if using C++11). To store 1.1M of those 2-byte values requires 2.2M of memory. So far so good.
Your code builds an in-memory graph with linked lists and lots of pointers. Your heap-based queue also has a lot of pointers. You can greatly decrease memory usage by relying on a more-efficient representation - for example, you could build an NxM array of elements with
struct Cell {
uint_32_t distance; // shortest distance from start, initially INF
uint_16_t height;
int_16_t parent; // add this to cell index to find parent; 0 for `none`
};
A cell at row, col will be at index row + N*col in this array. I strongly recommend building utility methods to find each neighbor, which would return -1 to indicate "out of bounds" and a direct index otherwise. The difference between two indices would be usable in parent.
You can implement a (not very efficient) priority queue in C by calling stdlib's "sort" on an array of node indices, and sorting them by distance. This would cut a lot of additional overhead, as each pointer in your program probably takes 8 bytes (64-bit pointers).
By avoiding a lot of pointers, and using an in-memory description instead of a graph, you should be able to cut down memory consumption to
1.1M Cells x 8 bytes/cell = 8.8M
1.1M indices in the pq-array x 4 bytes/index = 4.4M
For a total of around 16 Mb w/overheads - well under stated limits. If it takes too long, you should use a better queue.

Find all lines within a circle, for many circles. Optimization

I'm working on a program in which I need to find all lines which are in a circles located at some cartesian point of some radius.
At the moment, for every circle, I am iterating over all the lines and checking if the line enters/contacts the circle at any point.
The code essentially looks like this.
for (int i = 0; i < num_circles; i++)
{
for (int j = 0; j < num_lines; j++)
{
if(lineIntersectWithCircle(circle[i], lines[j]))
{
//Append line[j] to a list of lines intersecting with circle[i];
//some code
}
}
}
I've been thinking of many way to optimize this, but I'm having trouble.
I have sorted the circles by minimum Cartesian distance and sorted lines by maximum distance away. This way you can somewhat optimize, but it's quite minimal because once you reach the point where line[j].max > circle[i].min, you still have to iterate through all the rest of the lines.
I am fine with my intersection checking method, I just would like to minimize the amount of times I need to call it.
Is there a good way of doing this?
Cheapest way is just check the bounding extents/rectangles of the two shapes (line and circle) prior to the more expensive intersection test. Chances are that you can even compute the extents on the fly of the line/circle, not precompute, and still get a decent performance boost unless your line/circle intersection is already dirt cheap.
A really effective approach but one that requires a bit more work is to just create a grid. You can use the bounding rectangles computed above to cheaply see which grid cells your shapes intersect.
struct GridNode
{
// Points to the index of the next node in the grid cell
// or -1 if we're at the end of the singly-linked list.
int next_node;
// Points to the index of the shape being stored.
int shape;
};
struct GridCell
{
// Points to the first node or -1 if the cell is empty.
int first_node;
};
struct Grid
{
// Stores the cells in the grid. This is just illustrative
// code. You should dynamically allocate this with adjustable
// grid widths and heights based on your needs.
struct GridCell cells[grid_width * grid_height];
// Stores the nodes in the grid (one or more nodes per shape
// inserted depending on how many it intersects). This is
// a variable-sized array you can realloc needed (ex: double
// the size when you're out of room).
struct GridNode* nodes;
// The maximum number of nodes we can store before realloc.
int node_cap;
// The number of nodes inserted so far. realloc when this
// exceeds node_cap.
int node_num;
};
... something to this effect. This way, most of the time you can insert elements to the grid doing nothing more than just some integer (emulating pointers) operations and adding some grid node entries to this variable-sized nodes array. Heap allocations occur very infrequently.
I find in practice this outperforms quad-trees if you have many dynamic elements moving from one cell to the next like in a 2D video game where everything is moving around all the time while we need rapid collision detection, and can even rival quad-trees for searching if you are careful with the memory layout of the nodes to minimize cache misses when iterating through grid cells that intersect the shape you are testing against. You can even do a post-pass after the grid is constructed to rearrange the memory of each node for cache-friendly list iteration based on how efficient you need the intersection searches to be. If you want to get fancy, you can use Bresenham to figure out exactly what grid cells a line intersects, e.g., but given the quadratic complexity of what you're doing, you stand to improve exponentially without bothering with that and just doing it in a very simple way with bounding rectangles.
Basically to find an intersection, first grab the bounding rect of the shape. Then see which cells it intersects in the grid. Now check for intersection with the shapes contained in the grid cells the original shape intersects. This way you can work towards constant-time complexity except for gigantic shapes (worst-case with O(n)) which are hopefully a rare case.
I even find use for these in 3 dimensions when things are moving around a lot. They're often cheaper than the octree, BVH, and kd-tree variants which provide extensive search acceleration but at the cost of more expensive builds and updates, and if you use this strategy of a singly-linked list for each grid cell which doesn't have to individually allocate nodes, you can store it in a very reasonable amount of memory even with the 3rd dimension. I wouldn't use a 3-dimensional version of this for raytracing, but it can be very useful for 3D collision detection, like detecting collision between particles moving every single frame.
As with anything it depends on your use case. If you have a fixed number of lines or infrequently added, you may want to precompute some of the calculations needed to find out if any part of the line is within radius distance of the center of the circle
Starting with the equation for the shortest distance between a line and a point and comparing that distance is less than the radius of the circle:
//abs(Cx*(y1-y0)-Cy*(x1-x0)+x1*y0-y1*x0)/sqrt((y1-y0)*(y1-y0)+(x1-x0)*(x1-x0))<R
//pull out some constants and cache these as they are initialized
//int y10 = y1-y0, //add to the line struct
// x10 = x1 -x0,
// delta = x1*y0-y1*x0,
// sides = (y10)*(y10)+(x10)*(x10);
// R2 = R*R; //add to the circle struct
//now the equation factors down to
//abs(Cx*(y10)-Cy*(x10)+delta)/sqrt(sides)< R //replace constants
//abs(Cx*(y10)-Cy*(x10)+delta) < sqrt(sides) * R //remove division
//pow(Cx*(y10)-Cy*(x10)+delta , 2.0) < sides * R * R //remove sqrt()
//int tmp = Cx*(y10)-Cy*(x10)+delta //factor out pow data
//tmp * tmp < sides * R2 //remove pow() and use cache R squared
//now it is just a few cheap instructions
Now the check should be just 4 integer multiplies, 2 add/subtract and a compare.
lineIntersectWithCircle(size_t circle, size_t line){
struct circle C = circle_cache[circle]; //these may be separate arrays
struct line L = line_cache[line]; //from your point data
long tmp = C.x * L.y10 - C.y * L.x10 + L.delta;
return (tmp*tmp < L.sides * C.R2);
}
... but you may want to check my math - its been a while. Also I assumed the points would be integers - change to float as needed - it should still be relatively fast.
If that isn't fast enough you can add additional data for the bounding boxes of the circle and line
bool lineIntersectWithCircle(size_t circle, size_t line){
struct circle C = circle_cache[circle]; //these may be separate arrays
struct line L = line_cache[line]; //from your point data
//if the bounding boxes don't intersect neither does the line
//this may not be _that_ helpful and you would need to:
// figure out the bounding boxes for each line/circle
// and cache additional data
if (C.leftx > L.rightx || L.leftx > C.rightx) //a box is to the side
return 0;
if (C.topy < L.boty || L.topy < C.boty) //a box is below/above
return 0;
//the bounding boxes intersected so check exact calculation
long tmp = C.x * L.y10 - C.y * L.x10 + L.delta;
return (tmp*tmp < L.sides * C.R2);
}

Can I speed up this function? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm trying to write John Conway's Game of Life in C, but I'm having trouble adding living cells to the board. The function I wrote to handle it is extremely slow.
Thought process: I want to add n living cells to the board randomly, so while cells left to set alive, get a random (x, y) pair, and if it's dead, make it living. That way I can guarantee n cells become alive.
Is my understanding of the problem incorrect, or am I just being inefficient? Why is it so slow, and how can I make it faster?
void add_cells( int board[BOARD_WIDTH][BOARD_HEIGHT], int n )
{
// Randomly set n dead cells to live state.
while ( n )
{
int randX = rand() % BOARD_WIDTH;
int randY = rand() % BOARD_HEIGHT;
if( board[randX][randY] == 0 )
{
board[randX][randY] = 1;
n--;
}
}
}
If let's say 70% of cells are alive, then it means that your program will have to find an other cell 7 times out of 10, which makes unecessary repetitions.
You could pop the selected cell out from a "remaining cells" array when you set it alive, and select your cell randomly in this array. I suggest to use a dynamicaly resizable container so you don't have to manipulate your entire "remaining cells" array each time you pop out a cell. This should help save you more time.
There are several issues that might explain some slowness in your problem:
Is the board initialized to 0 before calling add_cells()? If the board has random contents, finding dead cells might take an arbitrary long time, or potentially take forever if fewer than n cells are dead.
Are you sure the board is correctly defined? The 2D array seems more natural with y being the first dimension and x the second: using int board[BOARD_HEIGHT][BOARD_WIDTH] and swapping the index values for randX and randY.
Testing for (n > 0) would protect against an infinite loop if add_cells() is ever called with a negative n.
If n is large, finding dead cells can take a long time as shooting at random has a small chance of hitting one.
If n is larger than BOARD_WIDTH * BOARD_HEIGHT or if there are fewer than n dead cells, the loop will iterate forever.
If n is large or if the board has only a few dead cells, it would be more efficient to enumerate the dead cells and chose the target cells at random from the dead cells only. The drawback is such a method would be slower if n is small and the board has many dead cells.
The time complexity for n small compared to the number of dead cells is O(n), which is hard to beat and should be very fast on current hardware, but it tends towards O(n * BOARD_WIDTH * BOARD_HEIGHT) if n is large or close to the number of dead cells, which is much less efficient, and the function never finishes if n is greater than the number of dead cells.
If the board is known to be empty when add_cells() is called, if n is larger than BOARD_WIDTH * BOARD_HEIGHT / 2, it would be more efficient to set all cells alive and chose n cells to kill.
If the board is not necessarily empty, passing this function the number of live cells would help decide which approach is better and if there are at least n dead cells without the need for a lengthy loop to enumerate the dead cells.
If your board is contiguous in memory, you don't have to call rand() twice. You can just use rand() % (BOARD_WIDTH * BOARD_HEIGHT).
void add_cells(uint8_t board[BOARD_WIDTH][BOARD_HEIGHT], int n)
{
std::mt19937 eng;
uniform_int_distribution<int> dist(0, BOARD_WIDTH * BOARD_HEIGHT - 1);
while(n)
{
int index = dist(eng);
uint8_t* cell = (uint8_t*)board + index;
if(*cell == 0)
{
*cell = 1;
--n;
}
}
}
The modulo function is pretty slow, try (float)rand()/RAND_MAX*BOARD_WIDTH + 0.5
You can also use a faster rand, see here

Flood Fill Algorithm - Maze Navigation

I am trying to implement a version of the flood fill algorithm to help solve the shortest distance path of a maze for a micro mouse. It works the same way as the regular flood fill except that each adjacent non-filled place will be assigned a number representing the distance of that place to the start place. Each time the algorithm moves to a different cell the number is incremented by one. Here is an example of a maze with no wall starting in the bottom left hand corner.
2 3 4
1 2 3
0 1 2
Here is the current code I have ...
void nav_flood_rec(struct nav_array *array, int row, int column, int flood_num)
{
//Check the base case (not shown here)
if (base_case)
return;
//Assign the flood number
arrray->cells[row][column]->flood_number = flood_num;
//North
nav_flood_rec(array, row + 1, column, flood_num + 1);
//East
nav_flood_rec(array, row, column + 1, flood_num + 1);
//South
nav_flood_rec(array, row - 1, column, flood_num + 1);
//West
nav_flood_rec(array, row, column - 1, flood_num + 1);
}
The problem that I am having is that the recursion is not going one step at a time (kind of vague but let me explain). Instead of checking all directions and then moving on the algorithm will keep moving north and not check the other directions. It seems that I want to make the other recursive calls somehow yield until the other directions are checked. Does anyone have any suggestions?
You've implemented something analogous to a depth-first-search, when what you're describing sounds like you want a breadth-first-search.
Use a queue instead of a stack. You're not using a stack explicitly here, but recursion is essentially an implicit stack. A queue will also will solve the problem of stack overflows, which seems likely with that much recursion.
Also, as G.Bach says, you'll need to mark cells as visited so your algorithm terminates.
Wikipedia's article on the subject:
An explicitly queue-based implementation is shown in pseudo-code below. It is similar to the simple recursive solution, except that instead of making recursive calls, it pushes the nodes into a LIFO queue β€” acting as a stack β€” for consumption:
Flood-fill (node, target-color, replacement-color):
1. Set Q to the empty queue.
2. Add node to the end of Q.
4. While Q is not empty:
5. Set n equal to the last element of Q.
7. Remove last element from Q.
8. If the color of n is equal to target-color:
9. Set the color of n to replacement-color.
10. Add west node to end of Q.
11. Add east node to end of Q.
12. Add north node to end of Q.
13. Add south node to end of Q.
14. Return.
You call north() without testing any conditionals. Therefore, your recursion will, in order:
1) Test for base case
2) Set new flood number
3) Encounter //north and call nav_flood_rec()
4) REPEAT.
As you can see, you will never reach your other calls. You need to implement a test conditional, branch it, or something like that.
Not really sure what you're trying to do, but you could pass another struct as a parameter and have a value for each direction and then test them for equality... like...
struct decision_maker {
int north;
int south;
int west;
int east;
};
Then in your code:
/* assume dm is passed as a pointer to a decision_maker struct */
if (dm->north > dm->south) {
if (dm->south > dm->east) {
dm->east++; // increment first
// call east
} else if (dm->south > dm->west) {
dm->west++; // increment first
// call west
} else {
dm->south++;
// call south
} else {
dm->north++;
// call north
}
/*
* needs another check or two, like altering the base case a bit
* the point should be clear, though.
*/
It will get a little messy but it will do the job.

Entry level question about Matlab array operation

Hey guys. I have this question to ask. In C programming, if we want to store several values in an array, we implement that using loops like this:
j=0; //initialize
for (idx=1,idx less than a constant; idex++)
{
slope[j]=(y2-y1)/(x2-x1);
j++;
}
My question is in Matlab do we have any simpler way to get the same array 'slope' without manually increasing j? Something like:
for idx=1:constant
slope[]=(y2-y1)/(x2-x1);
Thank you!
Such operations can usually be done without looping.
For example, if the slope is the same for all entries, you can write
slope = ones(numRows,numCols) * (y2-y1)/(x2-x1);
where numRows and numCols are the size of the array slope.
If you have a list of y-values and x-values, and you want the slope at every point, you can call
slope = (y(2:end)-y(1:end-1))./(x(2:end)-x(1:end-1)
and get everything in one go. Note that y(2:end) are all elements from the second to the last, and y(1:end-1) are all elements from the first to the second to last. Thus, the first element of the slope is calculated from the difference between the second and the first element of y. Also, note the ./ instead of /. The dot makes it an element-wise operation, meaning that I divide the first element of the array in the numerator by the first element of the array in the denominator, etc.

Resources