I'm just getting started on a project and am having some trouble. The idea is to make an 8x8 array that randomly generates an array with ten blocks, one random starting point, and the top right corner being an 'exit'. Then the program will find the quickest path and the output will be the randomly generated array as well as the directions to the exit (i.e., Up, Up, Right, Right, Up, Left)
Obviously there are many steps that I have to take afterwards to get the array to do what I want, but I was wondering if anyone could help me figure out how to set one up so it looks something along the lines of (E=exit, X=block, Z=starting point)
0 0 0 0 X 0 0 E
0 0 X 0 0 0 0 0
0 0 0 0 0 0 X 0
0 X 0 0 X 0 0 0
0 0 0 0 0 0 0 X
X 0 0 X 0 Z 0 0
0 0 0 0 0 0 0 0
0 0 X 0 0 0 X 0
So far I have this program. It fortunately places the ten random -1s as well as the random starting point (I have it as '7' for now, but I will change it eventually), but I can't seem to guarantee that the upper right corner is not going to be one of the -1's that I need and then replaced by the 99 leaving the array with only nine -1's instead of the required ten.
#include <stdio.h>
#include <stdlib.h>
#define ROW 8
#define COLUMN 8
#define NUM 10
#define start 1
int main () {
int x, y;
int array[ROW][COLUMN];
for (x = 0; x < ROW; x++) {
for (y = 0; y < COLUMN; y++) {
array[x][y] = 0;
}
}
srand (time (NULL));
for (x = 0; x < NUM; x++) {
int t = rand () % ROW;
y = rand () % COLUMN;
if (array[t][y] != -1) {
array[t][y] = -1;
} else {
x--;
}
}
for (x = 0; x < start; x++)
{
int t = rand () % ROW;
y = rand () % COLUMN;
if (array[t][y] != 7) {
array[t][y] = 7;
} else { x--;
}
}
for (x = 0; x < ROW; x++) {
for (y = 0; y < COLUMN; y++) {
array[0][7] = 99;
printf ("%d ", array[x][y]);
}
printf ("\n");
}
return 0; }
any help would be greatly appreciated-I am a terrible programmer.
If I understand your question, then I would begin by initializing the array contents to zero (instead of -1) and I would also define the number of elements I want to randomly set to -1.
#include <stdio.h>
#include <stdlib.h>
#define ROW 8
#define COLUMN 8
#define NUM 10
int main (int argc, char *argv[]) {
int x, y;
int array[ROW][COLUMN];
for (x = 0; x < ROW; x++) {
for (y = 0; y < COLUMN; y++) {
array[x][y] = 0;
}
}
Then we can set NUM elements randomly to -1 like
srand (time (NULL));
for (x = 0; x < NUM; x++) {
int t = rand () % ROW;
y = rand () % COLUMN;
if (array[t][y] != -1) {
array[t][y] = -1;
} else {
x--;
}
}
Finally, we can print the results with something like
for (x = 0; x < ROW; x++) {
for (y = 0; y < COLUMN; y++) {
printf ("%d ", array[x][y]);
}
printf ("\n");
}
return 0;
I would have a 3-D array and have the first two dimensions randomized from 0-7 and the third dimension be randomized 0 and 1. 0 being a block and 1 being starting pointing. Having a for-loop for how many you want of each. Then fill the rest of the array with "0"'s
Related
I have a matrix of 0 and 1
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 1 1 0 1 1 1 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1
0 0 1 1 1 1 1 0 0 0
0 0 0 0 1 1 0 1 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
I want to calculate the shortest distance of each item from the non-empty edges. You can assume it as pixels of black and white (or empty). We want to calculate the distance of each black pixel from the edge of the black body (through a straight line; horizontal, vertical or diagonal).
The distance is calculated geometrically: the distance of Ai,j and Ai+1,j+1 is sqrt(2).
With the following code in C, I started to calculate the distance of each item from its horizontal and vertical edges (in four directions). Now I want to consider diagonal distance too (at any angle, not just 45°).
The straightforward approach is to calculate the distance of each item from each edge. However, as the matrix gets larger, the loops become painfully slow.
Since we have the distance from horizontal and vertical edges for each item, I look for a hack to find the shortest distance to the edge by examining neighbour items in fewer checks.
#include <stdlib.h>
#include <stdio.h>
int min(int a, int b, int c, int d)
{
int e = a < b ? a : b;
int f = c < d ? c : d;
int r = e < f ? e : f;
return r;
}
int main()
{
int width = 50;
int height = 50;
int points[width][height];
int distances[width][height][5]; // 0 left 1 right 2 bottom 3 top 4 min
// some random data
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
points[x][y] = rand() % 2;
}
}
// scanning in four direction to check if the previous neighbour exists
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
if (x > 0)
{
distances[x][y][0] = distances[x - 1][y][0] > 0 ? distances[x - 1][y][0] + 1 : 1;
}
else
{
distances[x][y][0] = 1;
}
}
}
for (int x = width - 1; x >= 0; x--)
{
if (points[x][y] > 0)
{
if (x < width - 1)
{
distances[x][y][1] = distances[x + 1][y][1] > 0 ? distances[x + 1][y][1] + 1 : 1;
}
else
{
distances[x][y][1] = 1;
}
}
}
}
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (points[x][y] > 0)
{
if (y > 0)
{
distances[x][y][2] = distances[x][y - 1][2] > 0 ? distances[x][y - 1][2] + 1 : 1;
}
else
{
distances[x][y][2] = 1;
}
}
}
for (int y = height - 1; y >= 0; y--)
{
if (points[x][y] > 0)
{
if (y < height - 1)
{
distances[x][y][3] = distances[x][y + 1][3] > 0 ? distances[x][y + 1][3] + 1 : 1;
}
else
{
distances[x][y][3] = 1;
}
}
}
}
// finding the minimum of four distances
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
distances[x][y][4] = min(distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3]);
printf("%d %d %d %d %d %d %d \n", x, y, distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3], distances[x][y][4]);
}
}
}
return 0;
}
If I understood correctly, given an arbitrary body as the ameba-like shown below, you would like to find the shortest distance from its containing points (for instance, the black point in the figure below) to the edges of the black body. This is the distance shown in blue. And you would like to hopefully take advantage of the orthogonal distances already calculated (black straight lines in the figure) to find it quickly.
Since the shape is arbitrary and not many assumptions can be made about it, the only thing I could think of is to confine the search for the shortest distance to the bounding square shown below in green. The value of the green square side is two times the shortest orthogonal distance found in your algorithm (from the black point to the green point).
Another possible approach would be to get instead a 1/8, 1/4 or so of the size of this green square and if no edges are found, keep increasing it until you find one with a few edges. It is guaranteed that at least the last green square will have at least one edge point, which is the orthogonal distance itself.
Playing with some strategy to grow the green square, maybe you can get a satisfactory performance heuristically.
This solution is easier said than done when it comes to put it in code, but I'm not quite sure I got the problem correctly so I stopped here.
One issue I found is that the term "black body" is not well defined, and the matrix shown in the question does not have any sparse points so it's not random at all as the posted code generates. Does the black body allow holes in it? Even the word "edge" is confusing to me because my English is not very good and the term reminds me of the term used in graph theory which is actually a line segment.
I tried the code and its output seems correct and clear. Just noticed some rubbish is coming out from the not initialized distances variable. Easier to get this if you reduce the size of points array to 10x10 or so.
EDIT:
Here is a possible implementation of the first method. The function that calculates the shortest distance to the edge, taking into account a bounding square, is the get_min_dist_to_edge function. All edges are added to a list to reduce unnecessary checks. To get the first point of the list inside the bounding square, there is no way other than iterating the list from the beginning. In a use case with too many edges, this list can get too large. A hash table containing the elements of the list mapped to its y coordinate would allow to find the first element inside the square much faster, at the expense of some memory.
#include "ameba.h"
#include <sys/queue.h>
#include <search.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
struct point_entry_t {
int x;
int y;
LIST_ENTRY(point_entry_t) entries;
};
LIST_HEAD(slisthead, point_entry_t)
edges_list_head = LIST_HEAD_INITIALIZER(edges_list_head);
void add_point_to_edges_list(int x, int y)
{
static int list_initialized = 0;
if (list_initialized == 0) {
LIST_INIT(&edges_list_head);
list_initialized = 1;
}
struct point_entry_t *entry = malloc(sizeof(*entry));
if (entry) {
entry->x = x;
entry->y = y;
LIST_INSERT_HEAD(&edges_list_head, entry, entries);
}
}
void clear_list(void)
{
while (!LIST_EMPTY(&edges_list_head)) {
struct point_entry_t *n1 = LIST_FIRST(&edges_list_head);
LIST_REMOVE(n1, entries);
free(n1);
}
}
int min(int a, int b, int c, int d)
{
int e = a < b ? a : b;
int f = c < d ? c : d;
int r = e < f ? e : f;
return r;
}
int calc_distances(unsigned char points[80][80], int distances[80][80][5])
{
int width = 80;
int height = 80;
// scanning in four direction to check if the previous neighbour exists
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
if (x > 0)
{
distances[x][y][0] = distances[x - 1][y][0] > 0 ? distances[x - 1][y][0] + 1 : 1;
}
else
{
distances[x][y][0] = 1;
}
}
}
for (int x = width - 1; x >= 0; x--)
{
if (points[x][y] > 0)
{
if (x < width - 1)
{
distances[x][y][1] = distances[x + 1][y][1] > 0 ? distances[x + 1][y][1] + 1 : 1;
}
else
{
distances[x][y][1] = 1;
}
}
}
}
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (points[x][y] > 0)
{
if (y > 0)
{
distances[x][y][2] = distances[x][y - 1][2] > 0 ? distances[x][y - 1][2] + 1 : 1;
}
else
{
distances[x][y][2] = 1;
}
}
}
for (int y = height - 1; y >= 0; y--)
{
if (points[x][y] > 0)
{
if (y < height - 1)
{
distances[x][y][3] = distances[x][y + 1][3] > 0 ? distances[x][y + 1][3] + 1 : 1;
}
else
{
distances[x][y][3] = 1;
}
}
}
}
// finding the minimum of four distances
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
distances[x][y][4] = min(distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3]);
if (distances[x][y][4] == 1)
add_point_to_edges_list(x, y);
}
}
}
}
void print_edges_and_points(int point_x, int point_y,
int min_dist_edge_x, int min_dist_edge_y,
int distances[80][80][5])
{
for (size_t y = 0; y < 80; y++) {
for (size_t x = 0; x < 80; x++) {
if ( x == min_dist_edge_x
&& y == min_dist_edge_y) {
printf("E");
} else if (distances[x][y][4] == 1) {
printf(".");
} else if ( x == point_x
&& y == point_y) {
printf("P");
} else {
printf(" ");
}
}
printf("\n");
}
}
static inline void get_boundaries(int x, int y, int distances[80][80][5],
int *boundary_start_x, int *boundary_finish_x,
int *boundary_start_y, int *boundary_finish_y)
{
*boundary_start_x = x - distances[x][y][4];
*boundary_start_y = y - distances[x][y][4];
*boundary_finish_x = x + distances[x][y][4];
*boundary_finish_y = y + distances[x][y][4];
if (*boundary_start_x < 0) *boundary_start_x = 0;
if (*boundary_start_y < 0) *boundary_start_y = 0;
if (*boundary_finish_x > 80) *boundary_finish_x = 80;
if (*boundary_finish_y > 80) *boundary_finish_y = 80;
}
float get_min_dist_to_edge(int x, int y, int distances[80][80][5],
int *edge_x, int *edge_y)
{
uint32_t min_sq_dist = INT_MAX;
int boundary_start_x; int boundary_finish_x;
int boundary_start_y; int boundary_finish_y;
get_boundaries(x, y, distances,
&boundary_start_x, &boundary_finish_x,
&boundary_start_y, &boundary_finish_y);
if (!LIST_EMPTY(&edges_list_head)) {
struct point_entry_t *entry = NULL;
LIST_FOREACH(entry, &edges_list_head, entries) {
if ( entry->y > boundary_finish_y
|| entry->x < boundary_start_x
|| entry->x > boundary_finish_x) {
continue;
} else if (entry->y < boundary_start_y) {
return sqrt(min_sq_dist);
}
int sq_dist = pow(abs(x - entry->x), 2) +
pow(abs(y - entry->y), 2);
if (sq_dist < min_sq_dist) {
*edge_x = entry->x;
*edge_y = entry->y;
min_sq_dist = sq_dist;
}
}
}
return -1;
}
int main(int nargs, char *argv[])
{
if (nargs != 3) {
printf("\tusage: %s <x> <y>\n", argv[0]);
return 0;
}
unsigned char (*points)[80] = (unsigned char (*)[80])ameba_bin;
int distances[80][80][5] = {0,}; // 0 left 1 right 2 bottom 3 top 4 min
int x = atoi(argv[1]);
int y = atoi(argv[2]);
int min_dist_edge_x = 0;
int min_dist_edge_y = 0;
calc_distances(points, distances);
float min_dist_edge = 0;
if ((min_dist_edge = get_min_dist_to_edge(x, y, distances, &min_dist_edge_x,
&min_dist_edge_y)) > 0) {
print_edges_and_points(x, y, min_dist_edge_x, min_dist_edge_y, distances);
printf("ortho distances for P (%d, %d): < %d, > %d, ^ %d, v %d\n", x, y,
distances[x][y][0], distances[x][y][1],
distances[x][y][2], distances[x][y][3]);
printf("min distance from P (%d, %d) to nearest edge point E (%d, %d) = %.02f\n", x, y,
min_dist_edge_x, min_dist_edge_y, min_dist_edge);
}
clear_list();
return 0;
}
Here is an output example:
$ gcc main.c -lm && ./a.out 35 40
.....
.... .....
.. ..
.. ..
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
E .
........ . .
. ... . .
.. ..... .
. .
. .
. .
. P .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.. .
. .
.. .
... .
... .
........... .
.... .
.. .
... .
... ..
.... ...
......
ortho distances for P (35, 40): < 31, > 37, ^ 28, v 24
min distance from P (35, 40) to nearest edge point E (27, 33) = 10.63
ameba.h was created using xxd -i over the output of a web-based tool that converts images to an ASCII table.
This problem is called "Euclidean Distance Transform". It can be solved exactly in O(NM) time. Here you can find a nice paper discussing the algorithm.
http://fab.cba.mit.edu/classes/S62.12/docs/Meijster_distance.pdf
It works also for other norms like Manhattan or Chessboard distance.
I have an array in 1D.
data[27]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27};
I need to convert this into a 3D array of the form using C:
data[3][3][3]
Can someone help me doing this?
I tried the following code. Not seems to be working:
#include <stdio.h>
int main()
{
int x;
int y;
int z;
int res;
int data;
int byte[] data={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; // Read 4096 bytes
byte[][][] res = new byte[3][3][3];
for (x = 0 ; x != 3 ; x++) {
for (y = 0 ; y != 3 ; y++) {
for (z = 0 ; z != 3 ; z++) {
res[x][y][z] = data[3*3*x + 3*y + z];
}
}
}
printf("Printing the 3D matrix\n");
for (x = 0 ; x != 16 ; x++) {
for (y = 0 ; y != 16 ; y++) {
for (z = 0 ; z != 16 ; z++) {
printf("%d\t",res[x][y][z]);
printf("\n");
}
}
}
return 0;
}
Your logic seems to be okay. The problem is with the declaration of the 1D and 3D arrays.
1) There id no datatype as byte in C
2) new is not a part of C. You cannot allocate memory using new
Try the following changes for your code to work
int main()
{
int x;
int y;
int z;
int data[] ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; // Read 4096 bytes
int res[3][3][3];
for (x = 0 ; x < 3 ; x++) {
for (y = 0 ; y < 3 ; y++) {
for (z = 0 ; z < 3 ; z++) {
res[x][y][z] = data[3*3*x + 3*y + z];
}
}
}
printf("Printing the 3D matrix\n");
//run the loop till maximum value of x, y & z
for (x = 0 ; x < 3 ; x++) {
for (y = 0 ; y < 3 ; y++) {
for (z = 0 ; z < 3 ; z++) {
printf("%d\t",res[x][y][z]);
printf("\n");
}
}
}
return 0;
}
I want to make a circular counter in C programming.
First variable can store value from 0-3.
Second variable asks the value from user (from 0-3).
Third variable asks user to move either left or right
If third variable is left
the second variable should move left:
3->2
2->1
1->0
0->3
Similarly if third variable is right
the second variable should move right:
0->1
1->2
2->3
3->0
#include <stdio.h>
int main(void)
{
int max = 3, num, i;
num = 0;
for (i = 0; i < 10; i++) {
printf("%d\n", num);
num = (num + 1) % (max + 1);
}
puts("--");
num = max;
for (i = 0; i < 10; i++) {
printf("%d\n", num);
num = (max - -num) % (max + 1);
}
return 0;
}
Output:
0
1
2
3
0
1
2
3
0
1
--
3
2
1
0
3
2
1
0
3
2
If you wrap at a power of two, then this technique will work.
#include <stdio.h>
typedef struct
{
unsigned int x : 2; /* Holds up to 4 values */
} SmallInt;
int main()
{
SmallInt up = {0};
SmallInt down = {0};
for (int z = 0; z < 10; z++)
{
printf("%d %d\n", up.x, down.x);
up.x++;
down.x--;
}
return 0;
}
I wrote a code to find median filtering (median window). But, I can't make scannig to every number. What can I use instead of size in the for loops. When I use size it ensures just 5 Also, what about boundries ? What can I do for boundries ? Thank you for all appreciated answers. (I've opened new topic because users said that every topic is based on one question.If I did mistake,please delete the question, I will suffix the current question)
<size of array>
<size filter>
<data>
8
3
0 0 0 0 0 0 0 0
0 5 0 0 6 0 0 0
0 0 0 0 0 7 0 0
0 0 0 0 5 0 0 0
0 0 0 5 6 0 0 0
0 0 8 5 5 0 0 0
0 0 0 7 0 0 9 0
0 0 0 0 0 0 0 0
Output:
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 0
0 0 0 5 5 0 0 0
0 0 0 5 5 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
#include <stdio.h>
int median(int a[100],int n);
int main()
{
int a[100][100];
int temp[100];
int i,j,k,count=0;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
scanf("%d", &a[i][j]);
for(k = 0; k < sizearray; k++)
for(i = 0; i < sizefilter; i++)
for(j = 0; j < sizefilter; j++)
{
temp[count] = a[i][j];
count++;
a[i][j] = median(temp, count);
}
printf("\n");
printf("\n");
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
{
printf("%d ", a[i][j]);
if(j == sizearray-1)
printf("\n");
}
return 0;
}
int median(int a[100],int n)
{
int i,j,t;
int result;
/* Sorting begins */
for (i = 1 ; i <= n-1 ; i++)
{ /* Trip-i begins */
for (j = 1 ; j <= n-i ; j++)
{
if (a[j] <= a[j+1])
{ /* Interchanging values */
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
else continue ;
}
} /* sorting ends */
/* calculation of median */
if ( n % 2 == 0)
return result = (a[n/2] + a[n/2+1])/2 ;
else
return result = a[n/2 + 1];
}
There are some logical errors in your code:
When you filter, you need four nested loops: The outer two iterate over columns and rows of the matrix, the inner two iterate over columns and rows of the filter area. (That shouldn't be news to you; you have already been told that in an answer to your previous question.)
The constraints of the filter area are simple: The left and top indices must not fall below zero and the right and bottom indicies must be smaller than sizearray. If they are not, adjust them.
You need two arrays, the original array a and a second array that contains the filtered values. You cannot filter in-place, because if you look upwards and to the left, you'll see only filtered values, whereas your filter should always look at the original values.
Your wrong filtering loops apart: You never reset count, which you should reset, of course, for every median value you calculate. You also calculate the median in the inner loop, which is too often. A solution to this is to make count local to the loop that accumulates filter values and determines the median.
Your sorting has index errors. Instead of comparing i with i + 1, compare with ´i - 1. Your indices start from 1, soi - 1` will always yield a valid index.
You buble-sort the array, which is fine for small arrays, but slow in general. The <stdlib.h> has qsort, which may be useful to you for general sorting.
Your median indices are also off by one towards the right.
There are also some stylistic issues:
Please make a habit of using braces for code blocks for for, while and if. Only very trivial code blocks in the innermost scope can be written without braces. In your case, a lot has to be done "between" the loops, and having braces there makes it easy to add stuff.
Yor variable result in median is superfluous. You assign it and then immediately lose the variable itself, because you return. Just returning is enough.
Below is a version of your code that gives the desired output:
#include <stdint.h>
#include <stdio.h>
int min(int a, int b)
{
return a < b ? a : b;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int median(int a[], int n)
{
int i, j;
for (i = 1 ; i < n ; i++) {
for (j = 1 ; j < n ; j++) {
if (a[j] < a[j - 1]) {
int t = a[j];
a[j] = a[j - 1];
a[j - 1] = t;
}
}
}
if (n % 2) return a[n / 2];
return (a[n / 2 - 1] + a[n / 2]) / 2 ;
}
int main()
{
int a[100][100];
int b[100][100];
int temp[100];
int i, j, ii, jj;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
scanf("%d", &a[i][j]);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
int imin = max(0, i - sizefilter / 2);
int imax = min(sizearray, i + sizefilter / 2 + 1);
int jmin = max(0, j - sizefilter / 2);
int jmax = min(sizearray, j + sizefilter / 2 + 1);
int count = 0;
for (ii = imin; ii < imax; ii++) {
for (jj = jmin; jj < jmax; jj++) {
temp[count] = a[ii][jj];
count++;
}
}
b[i][j] = median(temp, count);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
printf("%3d", b[i][j]);
}
printf("\n");
}
return 0;
}
I have a table with dimensions N and M, given by the user.
This table is filled only with 0s and 1s. So I get something like this:
0 0 0 1 0
1 1 0 0 0
0 0 0 0 1
0 0 0 0 0
0 1 1 0 0
My question is, how do I count the number of 1s surrounding a single one?
I started like this:
int nb_neighbours_M(int **tab, int i, int j, int n, int m)
{
int nb_neighbours = 0;`
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
}
}
}
The easiest way to do this is to have two arrays int drow[NUMBER_OF_DIRECTIONS] and int dcol[NUMBER_OF_DIRECTIONS], that store the change in coordinates for each of a cell's neighbours.
// North, East, South, West
int drow[NUMBER_OF_DIRECTIONS] = {-1, 0, 1, 0};
int dcol[NUMBER_OF_DIRECTIONS] = {0, 1, 0, -1};
int row, col; // the coordinates of the cell you want to check the neighbours of
int num_neighbours = 0;
for (int i = 0; i < NUMBER_OF_DIRECTIONS; i++) {
if (tab[row + drow[i]][col + dcol[i]] == 1) {
num_neighbours++;
}
}
In the example above, I only handle 4 directions, but you could easily adapt this snippet to handle 8 directions without modifying any actual code (which is a good thing™).
You should probably also add bounds-checking to this, since it doesn't do any.
By unrolling the loop you can have something like that.
int count_neighbours (int **a, int x, int y, int w, int h)
{
int res = 0;
int left = x <= 0;
int right = x >= w - 1;
int top = y <= 0;
int bottom = y >= h - 1;
if (!left && !top) res += a[x-1][y-1];
if (!right && !bottom) res += a[x+1][y+1];
if (!left && !bottom) res += a[x-1][y+1];
if (!right && !top) res += a[x+1][y-1];
if (!left) res += a[x-1][y];
if (!right) res += a[x+1][y];
if (!top) res += a[x][y-1];
if (!bottom) res += a[x][y+1];
return res;
}