Sudoku in C vs Sudoku in Java - java

I recently wrote a simple straightforward C code that solves Sudoku and that uses recursion and backtracking. You will find below the code that I just described. Everything works fine.
#include <stdio.h>
# define INsigned 0
int grid[9][9];
void printGrid(){
int row,col;
for(row=0;row<9;row++){
for(col=0;col<9;col++){
printf("%2d",grid[row][col]);
}
printf("\n");
}
}
int Unsigned(int *row, int* col){
int i,j;
for(i=0;i<9;i++){
for(j=0;j<9;j++){
if(grid[i][j]==0){
*row=i;
*col=j;
return 1;
}
}
}
return 0;
}
int check(){
int row=0;
int col=0;
int i;
if(Unsigned(&row, &col)==0)
return 1;
for(i=1;i<=9;i++){
if(conflict(i,row-row%3, col-col%3, row, col)==0){
grid[row][col]=i;
if(check()==1)
return 1;
}
grid[row][col]=0;
}
return 0;
}
int conflict (int num, int srow, int scol, int row, int col){
int i,j;
for(i=0;i<9;i++){
if(grid[row][i]==num) return 1;
if(grid[i][col]==num) return 2;
}
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(grid[i+srow][j+scol]==num) return 3;
}
}
return 0;
}
int main(){
int i;
for(i=0;i<9;i++){
scanf("%d %d %d %d %d %d %d %d %d",&grid[i][0],&grid[i][1],&grid[i][2],
&grid[i][3],&grid[i][4],&grid[i][5],
&grid[i][6],&grid[i][7],&grid[i][8]);
}
check();
printf("\n\n");
printGrid();
}
The input is :
0 0 0 0 0 9 0 0 3
0 0 5 0 0 0 0 9 0
3 0 0 8 1 0 2 0 0
0 0 0 0 4 3 1 0 0
5 6 0 0 9 0 0 7 8
0 0 3 5 6 0 0 0 0
9 0 6 0 8 7 0 0 4
0 2 0 0 0 0 8 0 0
1 0 0 9 0 0 0 0 0
So the problem that I have occurs when I tried to write the exact algorithm in java. Since java does not allow the pass by reference for primitive types and since I used the pass by reference in the Unsigned function that looks for the next empty cell. I decided to use a wrapper class in java in order to overcome this obstacle however the java equivalent of this code that not work as it should be Here is the code.
public class intObj {
public int value;
}
public class Grid {
int grid[][] = new int[9][9];
int r = 0;
int c = 0;
public Grid(int grid[][]) {
this.grid = grid;
}
void printGrid() {
int row;
int col;
System.out.println("");
for (row = 0; row < 9; row++) {
for (col = 0; col < 9; col++) {
System.out.printf("%2d", grid[row][col]);
}
System.out.println("");
}
}
int conflict(int num, int srow, int scol, int row, int col) {
int i, j;
for (i = 0; i < 9; i++) {
if (grid[row][i] == num) {
return 1;
}
if (grid[i][col] == num) {
return 2;
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (grid[i + srow][j + scol] == num) {
return 3;
}
}
}
return 0;
}
int Unsigned(intObj row, intObj col) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (grid[i][j] == 0) {
row.value = i;
col.value = j;
return 1;
}
}
}
return 0;
}
int check() {
intObj row = new intObj();
intObj col = new intObj();
if (Unsigned(row, col) == 0) {
return 1;
}
for (int i = 1; i <= 9; i++) {
if (conflict(i, (row.value) - (row.value) % 3,
(col.value) - (col.value) % 3, row.value, col.value) == 0) {
grid[row.value][col.value] = i;
if (check() == 1) {
return 1;
}
}
grid[row.value][col.value] = 0;
}
return 0;
}
}
The main class:
public class Main {
public static void main(String args[]) {
int grid[][] = {{0, 0, 0, 0, 0, 9, 0, 0, 3},
{0, 0, 5, 0, 0, 0, 0, 9, 3},
{3, 0, 0, 8, 1, 0, 2, 0, 0},
{0, 0, 0, 0, 4, 3, 1, 0, 0},
{5, 6, 0, 0, 9, 0, 0, 7, 8},
{0, 0, 3, 5, 6, 0, 0, 0, 0},
{9, 0, 6, 0, 8, 7, 0, 0, 4},
{0, 2, 0, 0, 0, 0, 8, 0, 0},
{1, 0, 0, 9, 0, 0, 0, 0, 0}};
Grid g = new Grid(grid);
g.check();
g.printGrid();
}
}
Sorry for the long post any help will be very much appreciated.

The simplest solution that I can think of Is "Move your unsigned code inside check() itself"
int check(){
int row=0;
int col=0;
int i;
if(Unsigned(&row, &col)==0) //Move Unsigned() method code here and that's it
return 1;
II'nd Solution: These two objects that you are creating in check()
method must be part of your Grid class,do not create them locally in check() method.It should resolve your problem
intObj row = new intObj();
intObj col = new intObj();

Related

Why is the output of my multiplication of 2D array not correct?

I have to find the distances in a graph through the multiplication of a 2D array, and I am trying to multiply the array of the graph, it works but the output is not correct.
And I don't know where the problem is!
public class Graph {
private int[][] AdjacencyMatrix = {
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 0},
{0, 1, 0, 0, 0}};
int size = AdjacencyMatrix.length;
private int[][] distanceMatix = new int[size][size];
public void multiply() {
int sum = 0;
//für alle Zeilen in this matrix
for (int row = 0; row < size; row++) {
//für alle Spalten in other matrix
for (int col = 0; col < size; col++) {
//this matrix -> für alle Zellen in der Zeile
//other matrix -> für alle Zellen in der Spalte
for (int index = 0; index < size; index++) {
if (row == col) {
distanceMatix[row][col] = 0;
} else {
distanceMatix[row][col] +=
AdjacencyMatrix[row][index] *
AdjacencyMatrix[index][col];
}
}
}
}
System.out.println("\n-------- Print DistanceMatrix --------\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
System.out.print(distanceMatix[i][j] + " ");
}
System.out.println();
}
}
}
My Output:
0 0 2 0 1
0 0 0 2 0
2 0 0 0 1
0 2 0 0 0
1 0 1 0 0
The correct ouput is this:
0 1 2 1 2
1 0 1 2 1
2 1 0 1 2
1 2 1 0 3
2 1 2 3 0
Your inner loop should look like this. Primitive arrays are intitialized to 0's upon creation and you don't want to skip an iteration when row == col.
for (int index = 0; index < size; index++) {
distanceMatix[row][col] += AdjacencyMatrix[row][index] *
AdjacencyMatrix[index][col];
}
I used
1 2
3 4
And multiplied by hand and got
7 10
15 22
Which matches your program with above changes.
With regard to your expected answer, either it is wrong your input matrix may be wrong. You can verify your answers here
You can use a generic matrix multiplication approach so you don't get confused:
int size = 5;
int[][] matrix = {
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 0},
{0, 1, 0, 0, 0}};
int[][] result = new int[size][size];
for (int row = 0; row < size; row++)
for (int col = 0; col < size; col++)
for (int index = 0; index < size; index++)
result[row][col] += matrix[row][index] * matrix[index][col];
// output
for (int[] res : result) System.out.println(Arrays.toString(res));
//[2, 0, 2, 0, 1]
//[0, 3, 0, 2, 0]
//[2, 0, 2, 0, 1]
//[0, 2, 0, 2, 0]
//[1, 0, 1, 0, 1]
See also: An efficient way to multiply two object matrixes

how to check all reachable cells from one cell

I need to check all possible paths that is reachable from one certain cell in a 2d array. For example;
int [][] grid = {{2, 0, 0, 1, 1, 2},
{1, 0, 2, 0, 0, 1},
{1, 0, 2, 0, 4, 2},
{8, 3, 4, 0, 1, 2},
{1, 2, 5, 0, 3, 3},
{5, 1, 1, 2, 1, 0}};`
and I want to check all cells that is reachable from cell(2)(1) (it is just an example location). First some number will be placed here if this location is zero. For example, 1 is placed at that location.
Then I need to start merging all 1’s which are reachable from cell (2,1).Then cell(2)(1) location must be replaced with the 2 if the cells that create this path includes at least two 1 since 1+1 = 2.
After that, the cells which are used during merging process must be assigned to zero.
But if there is still possible merging for cell(2)(1) they should be merged too.
I try to use recursive function but it did not work as I want.
I could not figure out how to prevent merging if there are less than 3 neighbor cells which includes same value and how to merge until no possible merging left. Method should continue merging until there are no possible merge left, but my code merge for once. I have just started to learn java sorry for mistakes already now.
So...
I am not sure if I got everything right because some things are misleading.
cell(2)(2) has the initial content: 2
I think your chosen cell is (1)(2). //note: indices in java start with 0
So your idea is a little bit more complex and should not be solved with only one method.
I've written some code:
private static int[][] directions = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};
public static void step(int[][] array, int x, int y) {
if(array[x][y] == 0){
array[x][y] = 1;
}else{
return;
}
int number = 1;
while(true){
printGrid(array);
int amount = process(array, x, y);
if(amount == 1)break;
number ++;
array[x][y] = number;
}
}
public static int process(int[][] array,int x, int y){
int number = array[x][y];
if(number == 0) return 0;
int total = 1;
array[x][y] = 0;
for(int[] dire:directions){
if(x + dire[0] >= 0 && x + dire[0] < array.length && y + dire[1] >= 0 && y + dire[1] < array[0].length){
if(array[x + dire[0]][y+dire[1]] == number){
total += process(array, x + dire[0], y+dire[1]);
}
}
}
return total;
}
public static void printGrid(int[][] grid) {
for(int i = 0; i < grid.length; i++){
String s = "";
for(int n = 0; n< grid[0].length; n++){
s += grid[i][n]+", ";
}
System.out.println(s);
}
System.out.println("");
}
public static void main(String[] args){
int [][] grid =
{{2, 0, 0, 1, 1, 2},
{1, 0, 2, 0, 0, 1},
{1, 0, 2, 0, 4, 2},
{8, 3, 4, 0, 1, 2},
{1, 2, 5, 0, 3, 3},
{5, 1, 1, 2, 1, 0}};
Main.step(grid, 2,1);
printGrid(grid);
}
I modified it like this;
public static void main(String []args){
System.out.println("Welcome to the game Merge Numbers. Your grid as follows:");
int[][] newGrid = {{2, 0, 1, 1, 0, 8},
{2, 1, 0, 2, 4, 0},
{1, 2, 1, 2, 1, 3},
{2, 3, 2,0, 1, 0},
{0, 0, 5, 8, 7, 2},
{2, 0, 1, 1, 0, 0}};
for(int i = 0 ; i < newGrid.length ; i++){
for (int j = 0; j < newGrid[i].length; j++) {
System.out.print(newGrid[i][j] + " ");
}
System.out.println();
}
try (Scanner keyboard = new Scanner(System.in)){
System.out.print("Please enter your target's row index:");
int newRow = keyboard.nextInt();
System.out.print("Please enter your target's column index:");
int newColumn = keyboard.nextInt();
System.out.print("Please enter the number that you want to add to location " + newRow + " " + newColumn);
int newNextNumber = keyboard.nextInt();
step(newGrid, newRow, newColumn, newNextNumber);
for(int i = 0 ; i < newGrid.length ; i++){
for (int j = 0; j < newGrid[i].length; j++) {
System.out.print(newGrid[i][j] + " ");
}
System.out.println();
}}
}
public static void step(int[][] grid, int row, int column, int nextNumber ) {
if(grid[row][column] == 0){
grid[row][column] = nextNumber;
}else{
return;
}
int number = nextNumber;
while(true){
int amount = process(grid, row, column);
if(amount == 1)break;
number ++;
grid[row][column] = number;
}
}
public static int process(int[][] grid,int row, int column){
int number = grid[row][column];
if(number == 0) return 0;
int total = 1;
grid[row][column] = 0;
for(int[] dire:directions){
if(row + dire[0] >= 0 && row + dire[0] < grid.length && column + dire[1] >= 0 && column + dire[1] < grid[0].length){
if(grid[row + dire[0]][column+dire[1]] == number){
total += process(grid, row + dire[0], column+dire[1]);
}
}
}
return total;
}
}
But when I run it all the points include the target location becomes zero. Output is like;
Welcome to the game Merge Numbers. Your grid as follows:
2 0 1 1 0 8
2 1 0 2 4 0
1 2 1 2 1 3
2 3 2 0 1 0
0 0 5 8 7 2
2 0 1 1 0 0
Please enter your target's row index:3
Please enter your target's column index:3
Please enter the number that you want to add to location 3 3: 1
2 0 1 1 0 8
2 1 0 0 4 0
1 2 1 0 0 3
2 3 0 0 0 0
0 0 5 8 7 2
2 0 1 1 0 0
I mean if you look at the first grid in the output, cell(3)(3) is zero. When 1 is placed here, the 1's that are reachable from this cell(3)(3) merged. Then cell(3)(3) includes 2. After that same procedure follows. But when all possible merges done, all cells that has been used during the process include center became 0. Center should be increase by one after each merging. I think, I use the fourth parameter which is nextNumber incorrectly. Should function process also include that parameter or not? Sorry to disturb you so much :)
here is how you can find neighbors of a cell...
int x[] = {-1, -1, -1, 0, 0, +1, +1, +1};
int y[] = {-1, 0, +1, -1, +1, -1, 0, +1};
// looping through the neghibours...
for(int i=0; i<8; i++) {
if( p+x[i] < n && q+y[i] < m && a[p + x[i]][q + y[i]] == a[p][q]) {
// neighbour
}
}
Here is the recursive implementation of your problem, n & m is the size of grid a and p & q is the index of the cell you want to perform merge...
public static void merge(int a[][], int n, int m, int p, int q) {
int x[] = {-1, -1, -1, 0, 0, +1, +1, +1};
int y[] = {-1, 0, +1, -1, +1, -1, 0, +1};
int c = 0;
// looping through the neghibours...
for(int i=0; i<8; i++) {
if( p+x[i] < n && q+y[i] < m && a[p + x[i]][q + y[i]] == a[p][q]) {
c++;
}
}
if(c > 3) { // merging only if neghibours > 3
for(int i=0; i<8; i++) {
if( p+x[i] < n && q+y[i] < m && a[p + x[i]][q + y[i]] == a[p][q]) {
a[p + x[i]][q + y[i]] = 0;
}
}
a[p][q] += 1;
merge(a, n, m, p, q); // recurcively merging if possible...
}
}

How can I find three of the same numbers in a row?

I have an array something like the following.
int[][] myArray =
{{1, 2, 3, 0, 0, 1}
{1, 0, 4, 4, 0, 1}
{1, 2, 4, 3, 4, 0}
{2, 2, 0, 0, 2, 2}
{3, 0, 0, 3, 0, 0}
{4, 2, 3, 0, 0, 0}}
It would say that one had won because of the 1s in the three 1s in the first column. Two would not win because they are not in a "row".
I want to do some sort of win checking so that it finds three of the same number in a row, diagonal or column. Sort of like tic-tac-toe but with a larger grid. Before I used a messy set of if statements and goto statements. (It was written in Basic.) I have tried using a system where it found the directions from the last placed piece, in which there is a number of the same, but it didn't work properly. How can I do this in an easy and maintainable way?
Tried code:
private static boolean checkBoardCombinations(int[][] board, int inputX, int inputY) {
int currentPlayer = board[inputX-1][inputY-1];
boolean[][] directions = new boolean[3][3];
for(int y = 0; y >= -2; y--){
for(int x = 0; x >= -2; x--){
if(inputX+x >= 0 && inputX+x <= 7 && inputY+y >= 0 && inputY+y <= 7
&& (board[inputX+x][inputY+y] == currentPlayer)){
//System.out.printf("X: %s Y: %s", inputX+x, inputY+y);
directions[x+2][y+2] = true;
}
else{
directions[x+2][y+2] = false;
}
//System.out.printf("X: %s Y: %s B: %s,", inputX+x, inputY+y, directions[x+2][y+2]);
}
//System.out.println();
}
/*
for(int x = 0; x <= 2; x++){
for(int y = 0; y <= 2; y++){
System.out.print(directions[x][y] + " ");
}
System.out.println();
}
*/
return false;
}
Supposing the number of players are known, you can iterate over all the players one by one, and check if any player is forming a connection of required length or not.
Such code would look like following:
private int[][] grid; // Your array of size ROWS x COLUMNS
private final int ROWS = 6, COLUMNS = 6;
private final int CONSECUTIVE_CONNECTION_REQUIRED = 3;
// Returns true if given playerType is forming a connection, else false.
public boolean checkGrid(int playerType)
{
// Check downward
for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
int counter = 0;
for (int k = i; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++)
{
if (grid[k][j] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
// Check across
for (int i = 0; i <= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = 0; j < ROWS; j++)
{
int counter = 0;
for (int k = i; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++)
{
if (grid[j][k] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
// Check left to right diagonally
for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = 0; j <= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; j++)
{
int counter = 0;
for (int k = i, m = j; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++, m++)
{
if (grid[k][m] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
// Check right to left diagonally
for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = COLUMNS - 1; j >= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; j--)
{
int counter = 0;
for (int k = i, m = j; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++, m--)
{
if (grid[k][m] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
return false;
}
Where playerType is 0, 1, 2, 3 and so on...
You can use checkGrid() method like following:
for(int i = MIN_PLAYER_NUMBER; i <= MAX_PLAYER_NUMBER; i++)
{
if(checkGrid(i))
{
// Player i is forming the connection!!!
}
}
But if you don't want to iterate over your grid this many times, then drop your two dimensional array, and use a graph with adjacency list representation. Write a proper API for that which lets you make changes in your particular representation easily, and you can then find if any player is making a connection of particular length in the graph or not, in less iterations.
Although you already accepted an answer I thought to also submit you my answer for diversity :)
public static void main (String[] args)
{
int[][] myArray =
{{1, 2, 3, 0, 0, 1},
{1, 0, 4, 4, 0, 1},
{1, 2, 4, 3, 4, 0},
{2, 2, 0, 0, 2, 2},
{3, 0, 0, 3, 0, 0},
{4, 2, 3, 0, 0, 0}};
System.out.println(testForWinner(myArray));
}
/**
* Returns -1 if no winner
*/
static int testForWinner(int[][] ar) {
for(int i=0; i<ar.length; i++) {
for(int j=0; j<ar[i].length; j++) {
if(checkNext(ar, i, j, 0, 1, 1)) { //Check the element in the next column
return ar[i][j];
}
for(int k=-1; k<=1; k++) { //Check the three adjacent elements in the next row
if(checkNext(ar, i, j, 1, k, 1)) {
return ar[i][j];
}
}
}
}
return -1;
}
/**
* Step number `step` starting at `ar[i][j]` in direction `(di, dj)`.
* If we made 3 steps we have a winner
*/
static boolean checkNext(int[][] ar, int i, int j, int di, int dj, int step) {
if(step==3) {
return true;
}
if(i+di<0 || i+di>ar.length-1 || j+dj<0 || j+dj>ar[i].length-1) {
return false;
}
if(ar[i+di][j+dj]==ar[i][j]) {
return checkNext(ar, i+di, j+dj, di, dj, step+1);
}
return false;
}
See it in action: http://ideone.com/Ou2sRh

How to display numbers on the left side and on the bottom of my 2D array?

I need to print a 2 dimensions array with some numbers on the left side and on the bottom.
Here is my code for the initialization, wich is in the class Grille :
class Grille {
String[][] grille = new String[7][8];
public Grille() {
for (int line = 0; line < grille.length; line++) {
for (int column = 0; column < grille[column].length; column++) {
grille[line][column] = " ";
}
}
}
I print my array with this, in the same class Grille:
public void print() {
for (int line = 0; line < grille.length; line++) {
for (int column = 0; column < grille[line].length; column++) {
System.out.print(grille[line][column] + " ");
}
System.out.println("");
}
}
I would like to obtain this:
6
5
4
3
2
1
1 2 3 4 5 6 7
there are spaces between numbers in horizontal lines to make the difference and to know that they arre not in the same column
thank you!!
This task is fairly straight-forward. If you have a Two-Dimensional array, print array[I][0] until you reach array.length.
Then starting at J = 0, print array[I][J] until you reach array[i].length. Where I is the index of the last row.
The following code will print:
6
5
4
3
2
1
1 2 3 4 5 6
The code is:
public static void main(String[] args) {
int array[][] =
{
{6, 0, 0, 0, 0, 0},
{5, 0, 0, 0, 0, 0},
{4, 0, 0, 0, 0, 0},
{3, 0, 0, 0, 0, 0},
{2, 0, 0, 0, 0, 0},
{1, 2, 3, 4, 5, 6}
};
int array2[][] =
{
{6},
{5},
{4},
{3},
{2},
{1, 2, 3, 4, 5, 6}
};
print(array);
System.out.println("\n");
print(array2);
}
public static void print(int[][] array) {
for (int i = 0; i < array.length; ++i) {
if (i == array.length - 1) {
System.out.print(array[i][0] + "\n ");
for (int j = 0; j < array[i].length; ++j) {
System.out.print(array[i][j] + " ");
}
}
else {
System.out.println(array[i][0]);
}
}
}
boolean b=true;
for(int i=0;i<array.length;i++)
{
for(int j=0;j<=i;j++)
{
if(i==array.length-1)
{
if(b)
{
System.out.print(array[i][0]+"\n");
b=false;
}
System.out.print(" "+array[i][j]);
}
else
{
System.out.print(array[i][j]);
break;
}
}
System.out.print("\n");
}

Depth first search bug?

So I have a matrix of N×M. At a given position I have a value which represents a color. If there is nothing at that point the value is -1. What I need to do is after I add a new point, to check all his neighbours with the same color value and if there are more than 2, set them all to -1.
If what I said doesn't make sense what I'm trying to do is an algorithm which I use to destroy all the same color bubbles from my screen, where the bubbles are memorized in a matrix where -1 means no bubble and {0,1,2,...} represent that there is a bubble with a specific color.
Also, if you have any suggestions I'd be grateful. Thanks.
This is what I tried and failed:
public class Testing {
static private int[][] gameMatrix=
{{3, 3, 4, 1, 1, 2, 2, 2, 0, 0},
{1, 4, 1, 4, 2, 2, 1, 3, 0, 0},
{2, 2, 4, 4, 3, 1, 2, 4, 0, 0},
{0, 4, 2, 3, 4, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};
static int Rows=6;
static int Cols=10;
static int count;
static boolean[][] visited=new boolean[15][15];
static int NOCOLOR = -1;
static int color = 1;
public static void dfs(int r, int c, int color, boolean set)
{
for(int dr = -1; dr <= 1; dr++)
for(int dc = -1; dc <= 1; dc++)
if(!(dr == 0 && dc == 0) && ok(r+dr, c+dc))
{
int nr = r+dr;
int nc = c+dc;
// if it is the same color and we haven't visited this location before
if(gameMatrix[nr][nc] == color && !visited[nr][nc])
{
visited[nr][nc] = true;
count++;
dfs(nr, nc, color, set);
if(set)
{
gameMatrix[nr][nc] = NOCOLOR;
}
}
}
}
static boolean ok(int r, int c)
{
return r >= 0 && r < Rows && c >= 0 && c < Cols;
}
static void showMatrix(){
for(int i = 0; i < gameMatrix.length; i++) {
System.out.print("[");
for(int j = 0; j < gameMatrix[0].length; j++) {
System.out.print(" " + gameMatrix[i][j]);
}
System.out.println(" ]");
}
System.out.println();
}
static void putValue(int value,int row,int col){
gameMatrix[row][col]=value;
}
public static void main(String[] args){
System.out.println("Initial Matrix:");
putValue(1, 4, 1);
putValue(1, 5, 1);
putValue(1, 4, 2);
showMatrix();
for(int n = 0; n < Rows; n++)
for(int m = 0; m < Cols; m++)
visited[n][m] = false;
//reset count
count = 0;
dfs(5,1,color,false);
//if there are more than 2 set the color to NOCOLOR
for(int n = 0; n < Rows; n++)
for(int m = 0; m < Cols; m++)
visited[n][m] = false;
if(count > 2)
{
dfs(5,1,color,true);
}
System.out.println("Matrix after dfs:");
showMatrix();
}
}
One issue you are encountering is that you do not check the upper row and leftest col:
static boolean ok(int r, int c)
{
return r > 0 && r < Rows && c > 0 && c < Cols;
}
you should check for r >= 0, c>= 0
Second issue is you are using dfs() twice, but the visited field is static - it is all set to true before the second run of dfs() you need to initialize it back to false in all fields before the second run, or the algorithm will terminate instantly without doing anything [since all the nodes are already in visited - and the algorithm will decide not to re-explore these nodes.].
Your code counts diagonal cells as neighbours too. If you want only left/right/top/bottom cells than you can check
if(!(dr == 0 && dc == 0) && ok(r+dr, c+dc) && dr * dc == 0)
You also need to count first cell. You don't count cell you start from.
I think you are after a flood-fill algorithm (perhaps with the slightly odd constraint that there must be at least two neighbours of the same colour)? I'm not sure why depth-first-search is appropriate here.

Categories

Resources