Java 2D Array manipulation - java

I have to modify the below method:
private final static int NUM = 6;
public void fun(int[][] grid) {
for(int row = 0; row < NUM; row++) {
for(int col = 0; col < NUM; col++) {
if((grid[row][col] % 2) == 0) {
grid[row][col] = 0;
}
}
}
}
This method checks if it's a even number and if so it replaces its value with 0. Simple.
I now need to modify it so that it directs each cell to simultaneously replace its value with its number of diagonal neighbors that hold a value of 0.
I've thought about this for about an hour and tried many different solutions, most of which resulted in an out of bounds exception. I'm stumped and don't know how to accomplish this.
If the code is right, using the integers for the grid array below, it will reproduce the numbers shown in the bottom of the picture.

What is the problem, you just need to put if statements, like there can be maximum 4 possible neighbors so check that how many are equal to 0. But this is not enough you just need to add one more condition in each of the if statements. The condition would be that the neighbor you are trying to check is possible or not.
That is: Total 4 neighbors. If the coordinates of your main cell are x, y then:
1st Diagonal neighbor: x-1, y-1
2nd Diagonal neighbor: x-1, y+1
3rd Diagonal neighbor: x+1, y+1
4th Diagonal neighbor: x+1, y-1
These are all the 4 diagonal neighbors' coordinates but the last thing you need to check is whether they go out of bonds or not. For example for checking the 1st Diagonal neighbor I would do:
if((x-1)>0 && (y-1)>0){
//and then check here if that block is = `0`
}
and for other having say x+1 or y+1 you will need to check whether or not they are less than the NUM. Like if I want to check the 3rd Diagonal Neighbor:
if((x+1)<NUM && (y+1)<NUM){
//and then check here if that block is = `0`
}
Update: What do you mean by check here if that block is = 0?
If you want to check that is the diagonal neighboring blocks are equal to 0 or not then you will need to do it in a loop. Here is how:
public void fun(int[][] grid) {
for(int row = 0; row < NUM; row++) {
for(int col = 0; col < NUM; col++) {
if((grid[row][col] % 2) == 0) {
grid[row][col] = 0;
}
}
}
for(row = 0; row< NUM; row++){
for(int col = 0; col < NUM; col++) {
int count = 0;
// To check for the 1st Diagonal Neighbor
if((row-1)>0 && (col-1)>0){
if(grid[row-1][col-1]==0){
count++;
}
}
//Similarly for 2nd, 3rd and 4th Diagonal Neighbors
//and then
grid[row][col]=count;
}
}
}
Update 2:
For say the 3rd diagonal neighbor the code block would be like this:
if((row+1)<NUM && (col+1)<NUM){
if(grid[row+1][col+1]==0){
count++;
}
}
Answer
final private static int NUM = 6;
public void fun(int[][] grid) {
for(int row = 0; row < NUM; row++) {
for(int col = 0; col < NUM; col++) {
int counter = 0;
if((row - 1) > 0 && (col - 1) > 0) {
if(grid[row - 1][col - 1] == 0) {
counter++;
}
}
if((row - 1) > 0 && (col + 1) < NUM) {
if(grid[row - 1][col + 1] == 0) {
counter++;
}
}
if((row + 1) < NUM && (col - 1) > 0) {
if(grid[row + 1][col - 1] == 0) {
counter++;
}
}
if((row + 1) < NUM && (col + 1) < NUM) {
if(grid[row + 1][col + 1] == 0) {
counter++;
}
}
grid[row][col] = counter;
}
}
}

Related

How should I reconfigure the arrow "->" to not print when done with with my pathing?

I'm trying to create an optimal path to collect as many 1's as I can but after I execute my code, I still have an arrow pointing to nothing as there are no more places to go. How would I remove the arrow at the end of the code?
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner s1 = new Scanner(System.in);
int n = s1.nextInt();
int m = s1.nextInt();
int mat[][] = new int[n][m];
for (int i = 0; i < mat.length; i++){
for (int j = 0; j < mat[0].length; j++){
mat[i][j] = s1.nextInt();
}
}
int path[][] = new int[n][m];
for (int i = 0; i < path.length; i++){
Arrays.fill(path[i], -1);
}
int maxCoins = util(0, 0, mat, path);
System.out.println("Max coins:" + maxCoins);
int row = 0, column = 0;
System.out.print("Path:");
while(row < mat.length && column < mat[0].length){
System.out.print("(" + (row + 1) + "," + (column + 1) + ")");
System.out.print("->");
if(row < n - 1 && column < m - 1){
int down = path[row + 1][column];
int right = path[row][column + 1];
if(down > right){
row += 1;
continue;
}
else if (right > down){
column += 1;
continue;
}
else{
row += 1;
continue;
}
}
if(row + 1 < n){
row += 1;
}
else{
column += 1;
}
}
}
private static int util(int row,int column,int mat[][], int path[][]){
if(row >= mat.length || column >= mat[0].length){
return 0;
}
if(path[row][column]!= -1){
return path[row][column];
}
int right = util(row, column + 1, mat,path);
int down = util(row + 1, column, mat,path);
path[row][column]=Math.max(right, down);
if(mat[row][column] == 1){
path[row][column] += 1;
}
return path[row][column];
}
}
My current input looks like:
5 6
0 0 0 0 1 0
0 1 0 1 0 0
0 0 0 1 0 1
0 0 1 0 0 1
1 0 0 0 1 0
And output is:
Max coins:5
Path:(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(3,6)->(4,6)->(5,6)->
I am just trying to remove the one at the end but unsure where to insert my code:
System.out.print("->");
Cleanest way would be using a StringJoiner.
You can use it as follows
StringJoiner joiner = new StringJoiner("->");
joiner.add("a");
joiner.add("b");
System.out.println(joiner); //prints a->b - you can use toString if you want to return a joined String
You can also define a prefix and suffix for your joined String.
Or if you are familiar with Streams, there is Collectors.joining("->") available.
Three solutions that come to mind:
Add another check inside the loop, and put your sysout -> thingy after that check.
Usually code would generate some kind of list or similar data about the results and return it. It's a lot simpler to print lists, because you know the length etc.
Another common solution is to use StringBuilder and correct it before generating the output with toString()
You could just do something like this:
if (!(row == mat.length - 1 && column == mat[0].length - 1)) {
System.out.print("->");
}
Or a little cleaner:
if (arrowIsNotAtTheEnd(mat, row, column)) {
System.out.print("->");
}
// ...
private static boolean arrowIsNotAtTheEnd(int[][] mat, int row, int column) {
return !(row == mat.length - 1 && column == mat[0].length - 1);
}
For java 8 and above, the String class already has a convenient join method.
CharSequence[] path=new CharSequence[]{
"(1,1)","(2,1)","(2,2)","(2,3)","(2,4)","(3,4)","(3,5)","(3,6)","(4,6)","(5,6)"};
String output=String.join("->",path);
System.out.println(output);
//output: (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(3,6)->(4,6)->(5,6)

Detecting diagonal in a row win - tic-tac-toe, gomoku

Within a game on Gomoku a player has to get 5 in a row to win. Detecting diagonal win is a problem.
I have tried the code below which searches a 2d matrix from top right until it finds a player token we are looking for e.g. 1, it then proceeds to search from that point diagonally to find a winning row. This works fine providing the first '1' the algorithm comes across is a part of the winning line. If it is not, and just a random piece, the algorithm returns false as it does not continue searching.
How would Itake the last played move of the game and only search the diagonals relating to that move? Or possibly edit provided code to search the whole board.
public boolean is_diagonal_win_left(int player) {
int i = 0;
for (int col = board_size-1; col > (win_length - 2); col--) {
for (int row = 0; row < board_size-(win_length-1); row++) {
while (board_matrix[row][col] == player) {
i++;
row++;
col--;
if (i == win_length) return true;
}
i = 0;
}
}
return false;
}
//solved
public boolean is_diagonal_win_right(int player, int r, int c) {
int count = 0;
int row = r;
int col = c;
while ((row != 0) && (col != 0)) {
row--;
col--;
}
while ((row <= board_size - 1) && (col <= board_size - 1)) {
if (board_matrix[row][col] == player) count++;
row++;
col++;
}
return count == win_length;
}
You are correct: searching the board for the first counter is invalid; searching the entire board is a waste of time. Start at the most recent move. Let's call that position (r, c); the player's token is still player. Check in each of the eight functional directions to see how long is the string of player. For instance, you check the NW-SE diagonal like this:
count = 1 // We just placed one counter
row = r-1; col = c-1
while ( (row >= 0) and (col >= 0) and
(board_matrix[row][col] == player) )
count += 1
row = r+1; col = c+1
while ( (row < board_size) and (col < board_size) and
(board_matrix[row][col] == player) )
count += 1
// Note: gomoku rules require exactly 5 in a row;
// if you're playing with a"at least 5", then adjust this to >=
if (count == win_length) {
// Process the win
}

How to print out an X using nested loops

I have searched through to find a simple solution to this problem.
I have a method called
printCross(int size,char display)
It accepts a size and prints an X with the char variable it receives of height and width of size.
The calling method printShape(int maxSize, char display) accepts the maximum size of the shape and goes in a loop, sending multiples of 2 to the printCross method until it gets to the maximum.
Here is my code but it is not giving me the desired outcome.
public static void drawShape(char display, int maxSize)
{
int currentSize = 2; //start at 2 and increase in multiples of 2 till maxSize
while(currentSize<=maxSize)
{
printCross(currentSize,display);
currentSize = currentSize + 2;//increment by multiples of 2
}
}
public static void printCross(int size, char display)
{
for (int row = 0; row<size; row++)
{
for (int col=0; col<size; col++)
{
if (row == col)
System.out.print(display);
if (row == 1 && col == 5)
System.out.print(display);
if (row == 2 && col == 4)
System.out.print(display);
if ( row == 4 && col == 2)
System.out.print(display);
if (row == 5 && col == 1)
System.out.print(display);
else
System.out.print(" ");
}
System.out.println();
}
}
Is it because I hardcoded the figures into the loop? I did a lot of math but unfortunately it's only this way that I have been slightly close to achieving my desired output.
If the printCross() method received a size of 5 for instance, the output should be like this:
x x
x x
x
x x
x x
Please I have spent weeks on this and seem to be going nowhere. Thanks
The first thing you have to do is to find relationships between indices. Let's say you have the square matrix of length size (size = 5 in the example):
0 1 2 3 4
0 x x
1 x x
2 x
3 x x
4 x x
What you can notice is that in the diagonal from (0,0) to (4,4), indices are the same (in the code this means row == col).
Also, you can notice that in the diagonal from (0,4) to (4,0) indices always sum up to 4, which is size - 1 (in the code this is row + col == size - 1).
So in the code, you will loop through rows and then through columns (nested loop). On each iteration you have to check if the conditions mentioned above are met. The logical OR (||) operator is used to avoid using two if statements.
Code:
public static void printCross(int size, char display)
{
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
if (row == col || row + col == size - 1) {
System.out.print(display);
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
Output: (size = 5, display = 'x')
x x
x x
x
x x
x x
Instead of giving a direct answer, I will give you some hints.
First, you are right to use nested for loops.
However as you noticed, you determine when to print 'x' for the case of 5.
Check that 'x' is printed if and only if row = col or row + col = size - 1
for your printCross method, try this:
public static void printCross(int size, char display) {
if( size <= 0 ) {
return;
}
for( int row = 0; row < size; row++ ) {
for( int col = 0; col < size; col++ ) {
if( col == row || col == size - row - 1) {
System.out.print(display);
}
else {
System.out.print(" ");
}
}
System.out.println();
}
}
ah, I got beaten to it xD
Here's a short, ugly solution which doesn't use any whitespace strings or nested looping.
public static void printCross(int size, char display) {
for (int i = 1, j = size; i <= size && j > 0; i++, j--) {
System.out.printf(
i < j ? "%" + i + "s" + "%" + (j - i) + "s%n"
: i > j ? "%" + j + "s" + "%" + (i - j) + "s%n"
: "%" + i + "s%n", //intersection
display, display
);
}
}
Lte's try this simple code to print cross pattern.
class CrossPattern {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("enter the number of rows=column");
int n = s.nextInt();
int i, j;
s.close();
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (j == i) {
System.out.print("*");
} else if (j == n - (i - 1)) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}

java:generalized 8 queen to work for any initial state using depth first search [duplicate]

i am try to implement 8 queen using depth search for any initial state it work fine for empty board(no queen on the board) ,but i need it to work for initial state if there is a solution,if there is no solution for this initial state it will print there is no solution
Here is my code:
public class depth {
public static void main(String[] args) {
//we create a board
int[][] board = new int[8][8];
board [0][0]=1;
board [1][1]=1;
board [2][2]=1;
board [3][3]=1;
board [4][4]=1;
board [5][5]=1;
board [6][6]=1;
board [7][7]=1;
eightQueen(8, board, 0, 0, false);
System.out.println("the solution as pair");
for(int i=0;i<board.length;i++){
for(int j=0;j<board.length;j++)
if(board[i][j]!=0)
System.out.println(" ("+i+" ,"+j +")");
}
System.out.println("the number of node stored in memory "+count1);
}
public static int count1=0;
public static void eightQueen(int N, int[][] board, int i, int j, boolean found) {
long startTime = System.nanoTime();//time start
if (!found) {
if (IsValid(board, i, j)) {//check if the position is valid
board[i][j] = 1;
System.out.println("[Queen added at (" + i + "," + j + ")");
count1++;
PrintBoard(board);
if (i == N - 1) {//check if its the last queen
found = true;
PrintBoard(board);
double endTime = System.nanoTime();//end the method time
double duration = (endTime - startTime)*Math.pow(10.0, -9.0);
System.out.print("total Time"+"= "+duration+"\n");
}
//call the next step
eightQueen(N, board, i + 1, 0, found);
} else {
//if the position is not valid & if reach the last row we backtracking
while (j >= N - 1) {
int[] a = Backmethod(board, i, j);
i = a[0];
j = a[1];
System.out.println("back at (" + i + "," + j + ")");
PrintBoard(board);
}
//we do the next call
eightQueen(N, board, i, j + 1, false);
}
}
}
public static int[] Backmethod(int[][] board, int i, int j) {
int[] a = new int[2];
for (int x = i; x >= 0; x--) {
for (int y = j; y >= 0; y--) {
//search for the last queen
if (board[x][y] != 0) {
//deletes the last queen and returns the position
board[x][y] = 0;
a[0] = x;
a[1] = y;
return a;
}
}
}
return a;
}
public static boolean IsValid(int[][] board, int i, int j) {
int x;
//check the queens in column
for (x = 0; x < board.length; x++) {
if (board[i][x] != 0) {
return false;
}
}
//check the queens in row
for (x = 0; x < board.length; x++) {
if (board[x][j] != 0) {
return false;
}
}
//check the queens in the diagonals
if (!SafeDiag(board, i, j)) {
return false;
}
return true;
}
public static boolean SafeDiag(int[][] board, int i, int j) {
int xx = i;
int yy = j;
while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) {
if (board[xx][yy] != 0) {
return false;
}
yy++;
xx++;
}
xx = i;
yy = j;
while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) {
if (board[xx][yy] != 0) {
return false;
}
yy--;
xx--;
}
xx = i;
yy = j;
while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) {
if (board[xx][yy] != 0) {
return false;
}
yy--;
xx++;
}
xx = i;
yy = j;
while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) {
if (board[xx][yy] != 0) {
return false;
}
yy++;
xx--;
}
return true;
}
public static void PrintBoard(int[][] board) {
System.out.print(" ");
for (int j = 0; j < board.length; j++) {
System.out.print(j);
}
System.out.print("\n");
for (int i = 0; i < board.length; i++) {
System.out.print(i);
for (int j = 0; j < board.length; j++) {
if (board[i][j] == 0) {
System.out.print(" ");
} else {
System.out.print("Q");
}
}
System.out.print("\n");
}
}
}
for example for this initial state it give me the following error:
Exception in thread "main" java.lang.StackOverflowError
i am stuck, i think the error is infinite call for the method how to solve this problem.
any idea will be helpful,thanks in advance.
note:the broad is two dimensional array,when i put (1) it means there queen at this point.
note2:
we i put the initial state as the following it work:
board [0][0]=1;
board [1][1]=1;
board [2][2]=1;
board [3][3]=1;
board [4][4]=1;
board [5][5]=1;
board [6][6]=1;
board [7][1]=1;
[EDIT: Added conditional output tip.]
To add to #StephenC's answer:
This is a heck of a complicated piece of code, especially if you're not experienced in programming Java.
I executed your code, and it outputs this over and over and over and over (and over)
back at (0,0)
01234567
0
1 Q
2 Q
3 Q
4 Q
5 Q
6 Q
7 Q
back at (0,0)
And then crashes with this
Exception in thread "main" java.lang.StackOverflowError
at java.nio.Buffer.<init>(Unknown Source)
...
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at Depth.eightQueen(Depth.java:56)
at Depth.eightQueen(Depth.java:60)
at Depth.eightQueen(Depth.java:60)
at Depth.eightQueen(Depth.java:60)
at Depth.eightQueen(Depth.java:60)
...
My first instinct is always to add some System.out.println(...)s to figure out where stuff is going wrong, but that won't work here.
The only two options I see are to
Get familiar with a debugger and use it to step through and analyze why it's never stopping the loop
Break it down man! How can you hope to deal with a massive problem like this without breaking it into digestible chunks???
Not to mention that the concept of 8-queens is complicated to begin with.
One further thought:
System.out.println()s are not useful as currently implemented, because there's infinite output. A debugger is the better solution here, but another option is to somehow limit your output. For example, create a counter at the top
private static final int iITERATIONS = 0;
and instead of
System.out.println("[ANUMBERFORTRACING]: ... USEFUL INFORMATION ...")
use
conditionalSDO((iITERATIONS < 5), "[ANUMBERFORTRACING]: ... USEFUL INFORMATION");
Here is the function:
private static final void conditionalSDO(boolean b_condition, String s_message) {
if(b_condition) {
System.out.println(s_message);
}
}
Another alternative is to not limit the output, but to write it to a file.
I hope this information helps you.
(Note: I edited the OP's code to be compilable.)
You asked for ideas on how to solve it (as distinct from solutions!) so, here's a couple of hints:
Hint #1:
If you get a StackOverflowError in a recursive program it can mean one of two things:
your problem is too "deep", OR
you've got a bug in your code that is causing it to recurse infinitely.
In this case, the depth of the problem is small (8), so this must be a recursion bug.
Hint #2:
If you examine the stack trace, you will see the method names and line numbers for each of the calls in the stack. This ... and some thought ... should help you figure out the pattern of recursion in your code (as implemented!).
Hint #3:
Use a debugger Luke ...
Hint #4:
If you want other people to read your code, pay more attention to style. Your indentation is messed up in the most important method, and you have committed the (IMO) unforgivable sin of ignoring the Java style rules for identifiers. A method name MUST start with a lowercase letter, and a class name MUST start with an uppercase letter.
(I stopped reading your code very quickly ... on principle.)
Try to alter your method IsValid in the lines where for (x = 0; x < board.length - 1; x++).
public static boolean IsValid(int[][] board, int i, int j) {
int x;
//check the queens in column
for (x = 0; x < board.length - 1; x++) {
if (board[i][x] != 0) {
return false;
}
}
//check the queens in row
for (x = 0; x < board.length - 1; x++) {
if (board[x][j] != 0) {
return false;
}
}
//check the queens in the diagonals
if (!SafeDiag(board, i, j)) {
return false;
}
return true;
}

Messed up recursion code for a board game

What I have to do here is to count the number of adjacent white blocks (in 2's) on a square board which is made up of random black(0's) and white(1's) blocks. The white blocks have to be at i+1,j || i-1,j || i,j+1 || i,j-1. Technically diagonals are not counted. I have provided an example below:
[1 0 1]
[1 1 0]
[0 1 0]
Here count == 3 (0,0)(1,0) and (1,0)(1,1) and (1,1)(2,1)
Here is my code:
public int count = 0;
boolean count(int x, int y, int[][] mat)
{
if(x<0 || y<0)
return false;
if(mat[x][y] == 0)
return false;
for(int i = x; i<mat.length; i++)
{
for(int j = y; j<mat[0].length; j++)
{
if(mat[i][j] == 1)
{
mat[i][j] = 0;
if(count(i-1,j,mat))
count++;
if(count(i,j-1,mat))
count++;
if(count(i+1,j,mat))
count++;
if(count(i,j+1,mat))
count++;
}
}
}
return true;
}
Short explanation of what I am trying to do here: I am going about finding 1's on the board and when I find one I change it to a 0 and check its up,down,left,right for a 1. This goes on till I find no adjacent 1's. What is the thing I am missing here? I kind of have a feeling I am looping unnecessarily.
here's a solution without recursion
for(int i = 0; i < mat.length; i++) {
for(int j = 0; j < mat[i].length; j++) {
if(mat[i][j] == 1) {
if(i < mat.length - 1 && mat[i+1][j] == 1) {
count++;
}
if(j < mat[i].length - 1 && mat[i][j+1] == 1) {
count++;
}
}
}
I don't think recursion is the right answer as you should only being going one step deep (to find the adjacent value). Instead just loop through the elements looking to the right and down. Don't look up or left as twain mentioned so that you don't double count matches. Then is it simply:
for (i=0; i<max; i++)
for (j=0; j<max; j++)
if (array[i][j] == 1){
if (i<max-1 && array[i+1][j] == 1) count++;
if (j<max-1 && array[i][j+1] == 1) count++;
}

Categories