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.
Related
I have a 2D Array:
{0, 0, 1, 1, 1},
{0, 0, 1, 1, 1},
{0, 0, 1, 1, 1},
{0, 1, 0, 0, 1}
and I am trying to see which row has the closest 1 to the left, in this case it is index 3. So we have to return 3 to console, but I don't know how to go about comparing the values, etc.
This is what I have tried so far:
int array[][] = {
{0, 0, 1, 1, 1},
{0, 0, 1, 1, 1},
{0, 0, 1, 1, 1},
{0, 1, 0, 0, 1}
};
int count = 0;
Map<Integer, Integer> countMap = new HashMap<>();
for(int i = 0; i < array.length; i++){
for(int j = 0; j < array[i].length; j++){
if(array[i][j] != 1){
count++;
}else{
System.out.println("index of i: " + i + ", index of j:" + j + ", count: " + count);
countMap.put(j, count);
count = 0;
break;
}
}
}
System.out.println();
You can try to iterate in a column wise manner and return result as soon as you encounter the first '1'. This way you don't need to spend extra computation iterating through the whole 2D matrix.
public class ClosestOne {
public static int closestOne(int[][] a) {
for(int i = 0; i < a[0].length; i++) {
for(int j = 0; j < a.length; j++) {
if(a[j][i] == 1) {
return j;
}
}
}
return -1;
}
public static void main(String[] args) {
int array[][] = {
{0, 0, 1, 1, 1},
{0, 0, 1, 1, 1},
{0, 0, 1, 1, 1},
{0, 1, 0, 0, 1}
};
int closestRow = closestOne(array);
if(closestRow == -1) {
System.out.println("'1' is not present in matrix!");
} else {
System.out.println("Closest '1' is in row: " + closestRow );
}
}
}
Using a HashMap is completely over-engineered here. Theoretically you do not need any kind of data structure since you calculate the values row-by-row anyways, but since you were using one, I thought I would use one, too.
Use a simple array instead of the Map, with the length of the original array (i.e. the rows). Fill that array with a number that is higher than any result can be, to be safe I used Integer.MAX_VALUE.
int[] firstIndex = new int[array.length];
//for all i in length of array:
firstIndex[i] = Integer.MAX_VALUE;
No iterate though your your 2d array like you are and overwrite the firstIndex if you find something that is better than the current value.
//for every row
//for ever column (col)
if (array[row][col] == 1 && col < firstIndex[row]) {
firstIndex[row] = col;
}
Then in the end look for the minimum value in that array.
int min = firstIndex[0];
for (int row = 1; row < firstIndex.length; row++) {
min = Integer.min(min, firstIndex[row]);
}
System.out.println(min);
It looks like you have already worked out the count to the first 1 on each row, you just need to decide which is the lowest after completing your loop. You don't need a map to do that, just check if the current row is better than the "best so far" and if it is then update the best.
There is actually no need for a count variable since j is the same thing, and i is the row.
int best = -1; // Initialize to -1 which is an invalid index
int bestCount = Integer.MAX_VALUE; // Initialize to a very bad best count.
for(int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] == 1 && j < bestCount) {
best = i; // the row
bestCount = j; // the '1'
break;
}
}
}
System.out.println("Closest 1 to left in row " + best);
When i tried to check the rows of the Sudoku for duplicate elements, nothing is returned as result. Don't know whether the code is right or not. If the duplicate element found in a row, then need to print repetition found. Help me to reach the solution with using the method checkRow().
public class Sudoku {
public static void main(String... args) throws Exception
{
Scanner scanner = new Scanner(System.in);
int[][] sudokuPuzzle = {
{8, 1, 0, 0, 0, 0, 0, 3, 9},
{0, 0, 0, 9, 0, 1, 0, 0, 0},
{3, 0, 5, 0, 0, 0, 4, 0, 1},
{0, 0, 9, 8, 0, 2, 7, 0, 0},
{0, 0, 0, 5, 0, 6, 0, 0, 0},
{0, 0, 4, 3, 0, 7, 1, 0, 0},
{1, 0, 8, 0, 0, 0, 9, 0, 2},
{0, 0, 0, 6, 0, 4, 0, 0, 0},
{2, 4, 0, 0, 0, 0, 0, 6, 5}
};
printSudoku(sudokuPuzzle);
int count = countCellsToFill(sudokuPuzzle);
System.out.println("Number of cells have to filled: " + count);
}
public static void printSudoku(int[][] sudokuPuzzle)
{
for (int i = 0; i < sudokuPuzzle.length; i++)
{
if (i == 3 || i == 6)
System.out.println("------------------------");
for (int j = 0; j < sudokuPuzzle[i].length; j++)
{
System.out.format("%-2s", sudokuPuzzle[i][j]);
if (j == 2 || j == 5 )
System.out.print(" | ");
}
System.out.println();
}
}
public static int countCellsToFill(int[][] sudokuPuzzle){
int count=0;
for(int[] sudokuPuzzle1 : sudokuPuzzle){
for(int a: sudokuPuzzle1){
if(a == 0){
count++;
}
}
}
return count;
}
public boolean checkRow(int[] sudokuPuzzle){
for (int row = 0; row < sudokuPuzzle.length; row++)
{
int num = sudokuPuzzle[row];
if (num == sudokuPuzzle[row])
{
return true;
}
}
return false;
}
}
Take a moment and read your code:
public boolean checkRow(int[] sudokuPuzzle){
for (int row = 0; row < sudokuPuzzle.length; row++)
{
int num = sudokuPuzzle[row];
if (num == sudokuPuzzle[row])
{
return true;
}
}
return false;
}
What you are doing here is picking up the first number, "8" in this case, because it is on your position "0". Then, you check if that "8" is on your position "0", which of course, will be always true.
If you wanna check numbers per row, I suggest you to analize it with, maybe, a double for. So you can do your 9 lines, 9 numbers per line, and gotta have in mind don't compare the number you just read with himself.
By the way, if you are doing a Sudoku, you should check if that number appears in the first square as well. Sodukus are composed by 9 squares, you can not repeat numbers in rows, nor in columns, nor in squares.
That is an easy problem, struggle a bit!
Modified your checkRow method to check for duplicates -
public boolean checkRow(int[] sudokuPuzzle) {
for (int row = 0; row < sudokuPuzzle.length; row++) {
for (int i = 0; i < sudokuPuzzle.length; i++) {
if (i == row) {
continue;
}
if (sudokuPuzzle[i] == sudokuPuzzle[row]) {
return true;
}
}
}
return false;
}
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...
}
}
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
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();