Okay so I am making the game of life in C and I can't figure out how to count the neighbors from the matrix..
Here is my current code
http://pastebin.com/8fTdbpfs
Sorry I think it just looks better on pastebin.
For cell at location (i,j), i.e. i row, j column, coordinates of all its eight neighbors are
(i-1,j-1) | (i-1,j) | (i-1,j+1)
----------+---------+----------
(i, j-1) | (i ,j) | (i ,j+1)
----------+---------+----------
(i+1,j-1) | (i+1,j) | (i+1,j+1)
In a two-dimensional array array[row][col], you could access them by array[i][j]. Of course, you need to make sure every coordinates are valid before you try to access cell at that coordinate, you can using the following condition to make this check:
// for coordinate (i, j) in array[row][col]
if ((0 <= i) && (i < row) && (0 <= j) && (j < col)) {
/* access array[i][j] */
}
Related
I have an integer matrix of n rows by m cols representing a game board, and have written two functions that allow me to retrieve and set values within the matrix.
let get_val board (row, col) =
if row < 0
|| col < 0
|| (Array.length data) < (row + 1)
|| (Array.length data.(row)) < (col + 1)
then None
else if (board.(row).(col)) = (-1)
then None
else Some (board.(row).(col)) ;;
let set_val board (row, col) i =
if row < 0
|| col < 0
|| (Array.length data) < row+1
|| (Array.length data.(row)) < col+1
|| i < 0
then invalid_arg "set: invalid arguments"
else board.(row).(col) <- i;
board ;;
let board = Array.make_matrix 4 4 ;;
All positions are set to -1 initially to represent an empty square. Basically, if I try to retrieve a value outside of the board, I get a None. If the location is valid and not an empty square, I get can retrieve the value at that matrix as a Some type. I would like to increment a position by 1 in a board by using these two functions.
My first attempt in the board by 1 by doing the following:
let board = set_val board (2, 2) ((get_val board (2, 2)) + 1)
However, I run into the type issue,
This expression has type int option but an expression was expected of type int
, which I understand is because "get_val" returns a Some type, and 1 is an integer. I also tried:
let board = set_val board (2, 2) ((get_val board (2, 2)) + (Some 1))
, but board is an integer matrix. The constraints of the problem require me to return a Some/None from "get_val", but I need a way to retrieve the values from the function "get" as an int, not a Some. I've looked into how to convert from an Option to an int, but came up with nothing, since I'm not allowed access to the Option module. I suspect I'm not looking up the correct thing, but have run out of places to look. How would I be able to use the result of "get_val" in a way that I can increment the new value for a position on the board?
The best/idiomatic Ocaml way to do this is using pattern matching.
let board = match (S.get grid (row, col)) with
| None -> S.set grid (row, col) 1
| Some v -> S.set grid (row, col) (v+1)
Apparently, this way you can strip the Some part of the v and just get the actual value.
I'm building a heatmap-like rectangular array interface and I want the 'hot' location to be at the top left of the array, and the 'cold' location to be at the bottom right. Therefore, I need an array to be filled diagonally like this:
0 1 2 3
|----|----|----|----|
0 | 0 | 2 | 5 | 8 |
|----|----|----|----|
1 | 1 | 4 | 7 | 10 |
|----|----|----|----|
2 | 3 | 6 | 9 | 11 |
|----|----|----|----|
So actually, I need a function f(x,y) such that
f(0,0) = 0
f(2,1) = 7
f(1,2) = 6
f(3,2) = 11
(or, of course, a similar function f(n) where f(7) = 10, f(9) = 6, etc.).
Finally, yes, I know this question is similar to the ones asked here, here and here, but the solutions described there only traverse and don't fill a matrix.
Interesting problem if you are limited to go through the array row by row.
I divided the rectangle in three regions. The top left triangle, the bottom right triangle and the rhomboid in the middle.
For the top left triangle the values in the first column (x=0) can be calculated using the common arithmetic series 1 + 2 + 3 + .. + n = n*(n+1)/2. Fields in the that triangle with the same x+y value are in the same diagonal and there value is that sum from the first colum + x.
The same approach works for the bottom right triangle. But instead of x and y, w-x and h-y is used, where w is the width and h the height of rectangle. That value have to be subtracted from the highest value w*h-1 in the array.
There are two cases for the rhomboid in the middle. If the width of rectangle is greater than (or equal to) the height, then the bottom left field of the rectangle is the field with the lowest value in the rhomboid and can be calculated that sum from before for h-1. From there on you can imagine that the rhomboid is a rectangle with a x-value of x+y and a y-value of y from the original rectangle. So calculations of the remaining values in that new rectangle are easy.
In the other case when the height is greater than the width, then the field at x=w-1 and y=0 can be calculated using that arithmetic sum and the rhomboid can be imagined as a rectangle with x-value x and y-value y-(w-x-1).
The code can be optimised by precalculating values for example. I think there also is one formula for all that cases. Maybe i think about it later.
inline static int diagonalvalue(int x, int y, int w, int h) {
if (h > x+y+1 && w > x+y+1) {
// top/left triangle
return ((x+y)*(x+y+1)/2) + x;
} else if (y+x >= h && y+x >= w) {
// bottom/right triangle
return w*h - (((w-x-1)+(h-y-1))*((w-x-1)+(h-y-1)+1)/2) - (w-x-1) - 1;
}
// rhomboid in the middle
if (w >= h) {
return (h*(h+1)/2) + ((x+y+1)-h)*h - y - 1;
}
return (w*(w+1)/2) + ((x+y)-w)*w + x;
}
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
array[x][y] = diagonalvalue(x,y,w,h);
}
}
Of course if there is not such a limitation, something like that should be way faster:
n = w*h;
x = 0;
y = 0;
for (i=0; i<n; i++) {
array[x][y] = i;
if (y <= 0 || x+1 >= w) {
y = x+y+1;
if (y >= h) {
x = (y-h)+1;
y -= x;
} else {
x = 0;
}
} else {
x++;
y--;
}
}
What about this (having an NxN matrix):
count = 1;
for( int k = 0; k < 2*N-1; ++k ) {
int max_i = std::min(k,N-1);
int min_i = std::max(0,k-N+1);
for( int i = max_i, j = min_i; i >= min_i; --i, ++j ) {
M.at(i).at(j) = count++;
}
}
Follow the steps in the 3rd example -- this gives the indexes (in order to print out the slices) -- and just set the value with an incrementing counter:
int x[3][3];
int n = 3;
int pos = 1;
for (int slice = 0; slice < 2 * n - 1; ++slice) {
int z = slice < n ? 0 : slice - n + 1;
for (int j = z; j <= slice - z; ++j)
x[j][slice - j] = pos++;
}
At a M*N matrix, the values, when traversing like in your stated example, seem to increase by n, except for border cases, so
f(0,0)=0
f(1,0)=f(0,0)+2
f(2,0)=f(1,0)+3
...and so on up to f(N,0). Then
f(0,1)=1
f(0,2)=3
and then
f(m,n)=f(m-1,n)+N, where m,n are index variables
and
f(M,N)=f(M-1,N)+2, where M,N are the last indexes of the matrix
This is not conclusive, but it should give you something to work with. Note, that you only need the value of the preceding element in each row and a few starting values to begin.
If you want a simple function, you could use a recursive definition.
H = height
def get_point(x,y)
if x == 0
if y == 0
return 0
else
return get_point(y-1,0)+1
end
else
return get_point(x-1,y) + H
end
end
This takes advantage of the fact that any value is H+the value of the item to its left. If the item is already at the leftmost column, then you find the cell that is to its far upper right diagonal, and move left from there, and add 1.
This is a good chance to use dynamic programming, and "cache" or memoize the functions you've already accomplished.
If you want something "strictly" done by f(n), you could use the relationship:
n = ( n % W , n / H ) [integer division, with no remainder/decimal]
And work your function from there.
Alternatively, if you want a purely array-populating-by-rows method, with no recursion, you could follow these rules:
If you are on the first cell of the row, "remember" the item in the cell (R-1) (where R is your current row) of the first row, and add 1 to it.
Otherwise, simply add H to the cell you last computed (ie, the cell to your left).
Psuedo-Code: (Assuming array is indexed by arr[row,column])
arr[0,0] = 0
for R from 0 to H
if R > 0
arr[R,0] = arr[0,R-1] + 1
end
for C from 1 to W
arr[R,C] = arr[R,C-1]
end
end
I have this assigment in university where I'm given the code of a C++ game involving pathfinding. The pathfinding is made using a wave function and the assigment requires me to make a certain change to the way pathfinding works.
The assigment requires the pathfinding to always choose the path farthest away from any object other than clear space. Like shown here:
And here's the result I've gotten so far:
Below I've posted the part of the Update function concerning pathfinding as I'm pretty sure that's where I'll have to make a change.
for (int y = 0, o = 0; y < LEVEL_HEIGHT; y++) {
for (int x = 0; x < LEVEL_WIDTH; x++, o++) {
int nCost = !bricks[o].type;
if (nCost) {
for (int j = 0; j < 4; j++)
{
int dx = s_directions[j][0], dy = s_directions[j][1];
if ((y == 0 && dy < 0)
|| (y == LEVEL_HEIGHT - 1 && dy > 0)
|| (x == 0 && dx < 0)
|| (x == LEVEL_WIDTH - 1 && dx > 0)
|| bricks[o + dy * LEVEL_WIDTH + dx].type)
{
nCost = 2;
break;
}
}
}
pfWayCost[o] = (float)nCost;
}
}
Also here is the Wave function if needed for further clarity on the problem.
I'd be very grateful for any ideas on how to proceed, since I've been struggling with this for quite some time now.
Your problem can be reduced to a problem known as minimum-bottle-neck-spanning-tree.
For the reduction do the following:
calculate the costs for every point/cell in space as the minimal distance to an object.
make a graph were edges correspond to the points in the space and the weights of the edges are the costs calculated in the prior step. The vertices of the graph corresponds to the boundaries between cell.
For one dimensional space with 4 cells with costs 10, 20, 3, 5:
|10|20|3|5|
the graph would look like:
A--(w=10)--B--(w=20)--C--(w=3)--D--(w=5)--E
With nodes A-E corresponding to the boundaries of the cells.
run for example the Prim's algorithm to find the MST. You are looking for the direct way from the entry point (in the example above A) to the exit point (E) in the resulting tree.
This question already has an answer here:
Wrapping in Conway's Game of Life C++
(1 answer)
Closed 7 years ago.
I am trying to write a program that implements Conway's game of life on a 20x60 cell board. The grid will wrap around so the left side will be connected to (neighbouring) the right side and the top will be connected to the bottom.
Thus any cell with position (0, col), will have a neighbour at (maxRow, col). Any cell with position (row, 0) will have a neighbour at (row, maxCol).
The following function is supposed to count the number of neighbouring cells. It works for coordinates not on the edges, but not for ones that are. For instance, if there are points at (0, 10), (0, 11), and (0, 12) and (0, 10) is passed into the function, it will return a high number as neighbor count instead of 1.
{
int i, j;
int count = 0;
for (i = row - 1; i <= row + 1; i++)
for (j = col - 1; j <= col + 1; j++)
count += grid[i][j]; }
if (row==maxrow-1 || row==0)
count = count+ grid [(row-(maxrow-1))*-1][col-1]+grid[(row-(maxrow-1))*-1][col]+grid[(row-(maxrow-1))*-1][col+1];
if (col==0 || col==maxcol-1)
count=count +grid[row-1][(col-(maxcol-1))*-1]+grid[row][(col-(maxcol-1))*-1]+grid[row+1][(col-(maxcol-1))*-1];
count -= grid[row][col];
return count;
}
You can apply this formula to indices:
(x + max) % max
It will make -1 = 7 (wrap around) and 8 will be 0.
I have a c[N][M] matrix where I apply a max-sum operation over a (K+1)² window. I am trying to reduce the complexity of the naive algorithm.
In particular, here's my code snippet in C++:
<!-- language: cpp -->
int N,M,K;
std::cin >> N >> M >> K;
std::pair< unsigned , unsigned > opt[N][M];
unsigned c[N][M];
// Read values for c[i][j]
// Initialize all opt[i][j] at (0,0).
for ( int i = 0; i < N; i ++ ) {
for ( int j = 0; j < M ; j ++ ) {
unsigned max = 0;
int posX = i, posY = j;
for ( int ii = i; (ii >= i - K) && (ii >= 0); ii -- ) {
for ( int jj = j; (jj >= j - K) && (jj >= 0); jj -- ) {
// Ignore the (i,j) position
if (( ii == i ) && ( jj == j )) {
continue;
}
if ( opt[ii][jj].second > max ) {
max = opt[ii][jj].second;
posX = ii;
posY = jj;
}
}
}
opt[i][j].first = opt[posX][posY].second;
opt[i][j].second = c[i][j] + opt[posX][posY].first;
}
}
The goal of the algorithm is to compute opt[N-1][M-1].
Example: for N = 4, M = 4, K = 2 and:
c[N][M] = 4 1 1 2
6 1 1 1
1 2 5 8
1 1 8 0
... the result should be opt[N-1][M-1] = {14, 11}.
The running complexity of this snippet is however O(N M K²). My goal is to reduce the running time complexity. I have already seen posts like this, but it appears that my "filter" is not separable, probably because of the sum operation.
More information (optional): this is essentially an algorithm which develops the optimal strategy in a "game" where:
Two players lead a single team in a N × M dungeon.
Each position of the dungeon has c[i][j] gold coins.
Starting position: (N-1,M-1) where c[N-1][M-1] = 0.
The active player chooses the next position to move the team to, from position (x,y).
The next position can be any of (x-i, y-j), i <= K, j <= K, i+j > 0. In other words, they can move only left and/or up, up to a step K per direction.
The player who just moved the team gets the coins in the new position.
The active player alternates each turn.
The game ends when the team reaches (0,0).
Optimal strategy for both players: maximize their own sum of gold coins, if they know that the opponent is following the same strategy.
Thus, opt[i][j].first represents the coins of the player who will now move from (i,j) to another position. opt[i][j].second represents the coins of the opponent.
Here is a O(N * M) solution.
Let's fix the lower row(r). If the maximum for all rows between r - K and r is known for every column, this problem can be reduced to a well-known sliding window maximum problem. So it is possible to compute the answer for a fixed row in O(M) time.
Let's iterate over all rows in increasing order. For each column the maximum for all rows between r - K and r is the sliding window maximum problem, too. Processing each column takes O(N) time for all rows.
The total time complexity is O(N * M).
However, there is one issue with this solution: it does not exclude the (i, j) element. It is possible to fix it by running the algorithm described above twice(with K * (K + 1) and (K + 1) * K windows) and then merging the results(a (K + 1) * (K + 1) square without a corner is a union of two rectangles with K * (K + 1) and (K + 1) * K size).