Neighbours algorithm - arrays

Hi a have a code like these:
for (int row = 0; row < a.length; row++) {
for (int col = 0; col < a[row].length; col++) {
// Do something with a[row][col];
}
}
But i want to make an operation in a grid (8-neighbours) for every a[row][col] , however when im at the corners i will have problems (i don't know how to check if im in a corner), i was thinking in code a lot of if - conditionals, but i dont know the effective way to do this..
If there is a perse method for do this types of traversal neighbours arrays i would very greatful if you could give me a link, I've spent all day looking for information and I can't find anything.

You can use these arrays which represent the changes in the indexes when you look at the neighbors from a given position:
int dx[] = {-1,0,1,1,1,0,-1,-1};
int dy[] = {-1,-1,-1,0,1,1,1,0};
At position (row, col), dx[i] represents a change in row and dy[i] represents a change in col. You can use each position in the array to look at the neighbors.
Make a helper function that checks if a position is safe:
boolean isValidPosition(int x, int y) {
return 0 <= x && x < a.length && 0 <= y && y < a[x].length;
}
Then iterate over all 8 positions and you will have access to the neighbors via a[row + dx[i]][col + dy[i]].
for (int row = 0; row < a.length; row++) {
for (int col = 0; col < a[row].length; col++) {
for (int i = 0; i < 8; i++) {
if (isValidPosition(row + dx[i], col + dy[i])) {
// Do something with a[row + dx[i]][col + dy[i]];
}
}
}
}

Related

adding an array table (bidimensional) to a List (Java)

I am doing a Bingo program and now, the section of the bingoCard, to do this I am using an a bidimensional array but I need to shuffle the numbers of each row. For the shuffle part I saw that the setList is much better, but I don't know how to relate the List with the array here is a part of the code:
public static Integer[][] bingoCard(){
Integer [][] bingoCard= new Integer[3][9];
for(int x =0; x<bingoCard.length; x++){
for(int y =0; y<bingoCard[x].length; y++){
if(y <5){
int random = (int)(Math.random()*90+1);
System.out.print((bingoCard[0][y] = random) + " ");
}
if(y >4 && y <9){
System.out.print((bingoCard[0][y] = 0) + " ");
}
}
System.out.println();
}
List<Integer[]> list =Arrays.asList(bingoCard);
Collections.shuffle(list);
list.toArray(bingoCard);
return bingoCard;
}
Any question please ask me!!
Thanks.
In your code, when you do List<Integer[]> list = Arrays.asList(bingoCard), you are converting the outer array into a List and then shuffling its contents. The effect of this will be that the order of the 3 rows are shuffled rather than the contents of the 3 rows which is what you want. You could achieve this by shuffling the contents of each row within your for-loop. Or, after constructing the 2D array, you can loop over each row again and shuffle them.
Also, you have another small bug. When you assign the value, you are doing bingoCard[0][y] = ... but it should be bingoCard[x][y]. Otherwise, you are only assigning the first row new values on each iteration.
I would recommend not converting the array to a List just to shuffle it and then converting it back. Instead, you can use Random.nextInt to pick indexes of the array to assign. That would look something like this:
public static Integer[][] bingoCard(){
int numRows = 3;
int numCols = 9;
int randomNumbersPerRow = 5;
int randomNumberBound = 90;
Random random = new Random();
Integer[][] bingoCard = new Integer[numRows][numCols];
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < numCols; col++) {
// Initialize all spots to 0
bingoCard[row][col] = 0;
}
for (int i = 0; i < randomNumbersPerRow; i++) {
// Choose a spot to assign a random number
int indexToAssign = random.nextInt(numCols);
// Make sure we haven't already chosen it
while (bingoCard[row][indexToAssign] != 0) {
indexToAssign = random.nextInt(numCols);
}
int numToAssign = random.nextInt(randomNumberBound) + 1;
bingoCard[row][indexToAssign] = numToAssign;
}
}
// Print the bingo card
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < numCols; col++) {
System.out.printf("%2d ", bingoCard[row][col]);
}
System.out.println();
}
return bingoCard;
}

Setting a 2D array value overwrites another in C

When creating a 2D array and setting the value of some element, other elements get set too, what could be the reason behind such anomaly?
Following is the code example.
#include <stdio.h>
#define MAX_X 240
#define MAX_Y 2
char grid[MAX_X][MAX_Y];
int main()
{
int i,j,row,col;
col = MAX_X;
row = MAX_Y;
// Init 2D array
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
grid[i][j] = '.';
}
}
grid[0][121] = 'X'; // << [ISSUE HERE] `X` is written into 2 elements instead of 1
// Display 2D array
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%c", grid[i][j]);
}
printf("\n");
}
}
Note:
Issue showed up on g++, and was reproduced using this snippet on online gdb's compiler
You define grid as grid[240][2] which means 240 rows x 2 columns, and as #wildplasser mention you swap the col and row assignment. It should be:
row = MAX_X;
col = MAX_Y;

Accessing data in neighbor cells

I have a matrix M of size m x n which is saved as a one dimensional array N of length m * n. Every cell of this array contains some integer variables which are the ID of data points. The amount of integer variables in every cell changes over time.
N[0] = {1,4,5,7}
N[1] = {2,9,3,1,7,4}
N[2] = {7,1,3,9,8}
N[3] = {6,4,2}
...
I access these elements by using an index function which returns
idx = x + y * n
Given some index idx I want to use all integer variables of the neighbor cells and the central cell with index idx to access an array of data points D of size s. Size s can be very large.
To make my point clear: Instead of such a loop over all data points
for(int i=0; i<s; i++)
// Do something with D[i]
I want something like (but more compact)
// Access central cell
idx = x + y*n;
num_Elements = Number_of_Elements_Cell(x,y);
for(int i=0; i<num_Elements; i++)
// Do something with D[N[idx][i]]
// Access right cell
idx = (x+1) + y*n;
num_Elements = Number_of_Elements_Cell(x+1,y);
for(int i=0; i<num_Elements; i++)
// Do something with D[N[idx][i]]
// Access left cell
idx = (x-1) + y*n;
num_Elements = Number_of_Elements_Cell(x-1,y);
for(int i=0; i<num_Elements; i++)
// Do something with D[N[idx][i]]
and so on. For all cells I have to do that 9 times.
My question: Is there a better way to do that given the structure N?
I'm not sure i understand your question well ....
but you could try :
for (int i=-1 ; i <= 1 ; i++){
for (int j = -1 ; j <=1 ; j++){
idx = (x+i) + (y+j)*n;
// Check if idx is not out of bounds
num_Elements = Number_of_Elements_Cell(x+i,y+j);
for(int k=0; k<num_Elements; k++)
// Do something with D[N[idx][k]]
}
}
Note that your index could very well be out-of-bounds which such a method, so you'll have to implement a test to prevent that.
That's the way to simply iterate on a cell and its 8 neighbors using a double for loop.
If it's not what you expect, let me know, i'll edit/delete.
I'm not sure but maybe you're looking for something like this:
var distinctDataPoints = new List<int>();
for(int z = x - 1, z <= x + 1, z++)
{
if(z < 0 || z > m)
continue;
for(int t = y-1, t <= y + 1, t++)
{
if(t < 0 || t > n)
continue;
idx = z + t * n;
for(int i = 0; i < num_Elements; i++)
{
if(!distinctDataPoints.Contains(N[idx][i])
distinctDataPoints.Add(N[idx][i])
}
}
}
for(int dpIdx = 0; dpIdx < distinctDataPoints.Count; dpIdx++)
{
//Do something with D[dpIdx]
}

C Programming Zig-Zag Practice

I have an exercise in Objective-C making use of for, if-else and printf to print a Zig-Zag like this in the console:
Please see image:
I have tried a code with C programming and print a triangle then try to edit this one, but can't do anything more to get my Zig-Zag.
I have solve my problems already. Thank you guys so much.
for (int i = 0; i < 5; i++) {
for(int j = 1; j<= 21; j++ ){
if(j<=9){
if(j - i == 5 || j+ i == 5){
printf("*") ;
}else{
printf(" ");
}
}else{
if(j+i == 13 || j - i == 13 || j + i == 21){
printf("*") ;
}
else{
printf(" ");
}
}
}
printf("\n");
}
OK, attempt 2 based on your updated question. Let's start with the basic structure. Set some consts for the width and height - we will refer to these in multiple places, so consts make for nice easy changes - and create a loop with basic logic to start to get the display you want.
const int numRows = 5;
const int numCols = 21;
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
if (col == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
This gives us:
X
X
X
X
X
which is the wrong way up and only gives us one "downstroke", but it is a good start. Let's use the modulus function to make the pattern repeat. The repeat happens on the 9th character, which suggests we need to use ((numRows - 1) * 2) for our modulus.
const int modulusVal = ((numRows - 1) * 2);
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
int modCol = (col % modulusVal);
if (modCol == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
So now we get:
X X X
X X X
X X X
X X X
X X X
which is starting to get a lot closer to what we want. So, on to the upstrokes. The downstrokes are displayed when modCol is in the range of row, which is 0-4. When modCol is past this range, we bring it back into range by subtracting the number of rows from it.
Then we "invert" it by subtracting it from the highest value that row can be, which is numRows - 1. This means that when modCol is 0 it will become 4, when it is 1 it will become 3, when it is 2 it will be unchanged.
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
int modCol = (col % modulusVal);
if (modCol >= numRows)
{
modCol -= numRows;
modCol = ((numRows - 1) - modCol);
}
if (modCol == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
Now we get:
X X X
X X X
X X X X X
X X X X X
XX XX X
Close, but no cigar. Column 5 is being treated as column 0, but we need it to be treated as column 1. Make this change to fix it:
modCol = ((numRows - 1) - (modCol + 1));
Output:
X X X
X X X X X
X X X X X
X X X X X
X X X
This has the pattern we want, but starts at the top left when we want the bottom left. Easy fix. Invert modCol after it has been calculated in the same we we invert it when it is greater/equal than/to numRows.
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
int modCol = (col % modulusVal);
if (modCol >= numRows)
{
modCol -= numRows;
modCol = ((numRows - 1) - (modCol + 1));
}
modCol = ((numRows - 1) - modCol);
if (modCol == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
Finally we get the output we want:
X X X
X X X X X
X X X X X
X X X X X
X X X
I hope this helps and is reasonably easy to understand.
I'm not familiar with console programming using Objectionable C and you haven't explained exactly what you've tried, what has worked and what has not.
Assuming your problem is the code to choose the appropriate position to display the '+' character and not displaying text at a particular location on the console, here's what I would do:
int currentY = MIN_Y;
int incrementY = 1;
for (int currentX = MIN_X; currentX <= MAX_X; ++currentX)
{
SetCursorPosition(currentX, currentY);
printf("+");
currentY += incrementY;
if (currentY == MAX_Y)
{
incrementY = -1;
}
else if (currentY == MIN_Y)
{
incrementY = 1;
}
}
This assumes you have a function for SetCursor() and consts/defines for MIN/MAX X/Y.
The 'if' statement could be optimised to:
if (currentY == MAX_Y || currentY == MIN_Y)
{
incrementY -= incrementY;
}
but you required the use of the 'else' statement. Hopefully this code is pretty self explanatory and of some use to you.

Syntax Errors in Code [C] - Eight Queens Puzzle

Sorry for the vague title, I wasn't really sure how to explain. I'm trying to solve the Eight Queens puzzle.
For those unfamiliar with the eight queens puzzle:
This program is supposed to find a possible way that 8 queens can
be placed on an 8x8 chessboard so that the queens cannot
capture one another -- that is, so that no column, row, or
diagonal is occupied by more than one queen.
The way I have it mapped out in my head is:
1) I'll set the whole array: chess[8][8] = {2}
2) Go to the beginning of the array, and as long as chess[i][j] == 2, it will be reassigned to 1. Then as soon as that happens, I have another program block called set_illegal, which will go and set the diagonals, row, and column to 0. (For that reason I will have to have chess[8][8] be a global variable.)
3) After set_illegal is finished, the test program will jump back into the loop of assign_q and the process will start all over again.
4) After this it will print out the solution. Unfortunately I didn't code this find multiple solutions... so it will only display 1 solution (kind of nooby programming lol...)
Any input is much appreciated!!
#include <stdio.h>
#include <stdlib.h>
#define N 8
int chess[N][N] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, row1, column1;
//the reason for row1 and column1 is so that set_row, set_column, and set_diagonal
//will have a spot to start. Also I could have assigned all the elements in the array to 2 using a loop, but I was feeling a little lazy...
void assign_q(int **chess[N][N]**);
int main()
{
int row, column;
assign_q(chess);
for (row = 0; row < N; row++) //prints the whole table
{
for (column = 0; column < N; column++)
printf("%d ", chess[row][column]);
printf("\n");
}
return 0;
}
void set_illegal(void);
void assign_q(int chess[N][N])
{
int row, column;
for (column = 0; column < N; column++)
{
for (row = 0; row < N; row++)
{
if (chess[row][column] == 2) //if the element of the array is equal to 2, then it will set it to 1
{
chess[row][column] = 1;
row1 = column;
column1 = column;
set_illegal(); //goes through the column, row, and diagonal to set them all illegal
break;
}
}
}
}
void set_column(void);
void set_row(void);
void set_diagonal(void);
void set_illegal()
{
set_column();
set_row();
set_diagonal();
}
void set_column()
{
int row;
for (row = 0; row < N; row++)
chess[row][column1] = 0; //sets the column illegal
}
void set_row()
{
int column;
for (column = 0; column < N; column++)
chess[row1][column] = 0; //sets the row illegal
}
void set_diagonal()
{
int row, column;
for (row = row1 + 1, column = column1 + 1; row < N && column < N; row++, column++)
chess[row][column] = 0; //sets diagonals in the slope of -1 downwards illegal
for (row = row1 - 1, column = column1 - 1; row >= 0 && column >= 0; row--, column--)
chess[row][column] = 0; //sets diagonals in the slope of -1 upwards illegal
for (row = row1 - 1, column = column1 + 1; row >= 0 && column < N; row--, column++)
chess[row][column] = 0; //sets diagonals in the slope of +1 upwards illegal
for (row = row1 + 1, column = column1 - 1; row < N && column >= 0; row++, column--)
chess[row][column] = 0; //sets diagonals in the slope of +1 downwards illegal
}
After the change in bold, the only error I get is that the program doesnt actually work ahahaha. Anyways I'll figure that one out. Thanks for all the help!
void assign_q(int chess) - I think you want a board here, not a single field.

Resources