How to make sure that every 3x3 block contains values in Sudoku - java
I want to check a whole Sudoku table if all the blocks got the 9 values or not but I was able to check only the first block and I need to check the other 8 blocks how?
public static boolean checkSubs(int[][] p) {
int[] nums = new int[9];
int x=0, temp;
for (int i=0; i<3; i++)
for (int j=0; j<3; j++) {
temp = p[i][j];
for ( int m=0; m<nums.length; m++)
if ( nums[m]==temp ) return false;
nums[x++]=temp; }
return true; }
You can modify your checkSubsMethod.
Add i and j of the top left corner of sudoku subblock (e.g (0,0), (0,3),... (3,0), (3,3)... (6,3),(6,6)).
Use set to check does the value already used or not. The add() method of Set class return true if value doesn't in the set and false if value already added to the set.
And when you generalise your method you can use it for fields of any size. In your case size is 9x9, here is the example
public static boolean checkSubs(int[][] p, int topI, int topJ) {
Set<Integer> nums = new HashSet<>();
for (int i = topI; i < topI + 3; i++) {
for (int j = topJ; j < topJ + 3; j++) {
if (!nums.add(p[i][j])) {
return false;
}
}
}
return true;
}
public static void main(String[] args) {
int[][] sudoku = {
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9}};
for (int i = 0; i < sudoku.length;i += 3){
for (int j = 0; j<sudoku[0].length; j += 3){
if (!checkSubs(sudoku, i, j)){
System.out.println("DUPLICATED VALUES FOUND!");
return;
}
}
}
System.out.println("OK!!");
}
The output for this case will be OK!!
If you change the input like this
int[][] sudoku = {
{3,3,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9}};
The output will be DUPLICATED VALUES FOUND!
You can modify this example for your purposes in future.
Related
checking rows and cols in a 9x9 grid
I have an assignment in which I have to create the following classes: public class Square3x3 { private int[][] mat = new int [3][3]; public boolean allThere(){ int[] options = {1,2,3,4,5,6,7,8,9}; for (int i = 0 ; i < NUM_OF_ROWS; i++){ for(int j =0 ; j < NUM_OF_COLS; j++){ for (int k = 0; k < options.length; k++){ if(mat[i][j] == options[k]) { options[k] = -1; break; } } } } for (int num : options) { if(num != -1) return false; } return true; } a class that represents a 3x3 2d array, and a sudoku class that is constructed by a 3x3 2d array of Square3x3 objects: public class Sudoku { private Square3x3[][] grid9x9 = new Square3x3[3][3]; } I need to check if the 9x9 grid is valid, I have a method to check if a single 3x3 object is valid, but I also need to check if the entire row/col of the 9x9 grid is valid (has all the numbers from 1-9)
Here's one way to improve your data definitions using the same two classes. Define one 9 x 9 int array, and pass a sub-array to your allThere method by using the row and column indexes. public class Sudoku { private int[][] grid9x9 = new int[9][9]; } public class Square3x3 { public boolean allThere(int[][] grid, int row, int column) { int[] options = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for (int i = row; i < row + 3; i++) { for (int j = column; j < column + 3; j++) { options = testOptions(options, grid[i][j]); } } for (int num : options) { if (num != -1) return false; } return true; } private int[] testOptions(int[] options, int gridValue) { for (int i = 0; i < options.length; i++) { if (gridValue == options[i]) { options[i] = -1; break; } } return options; } } I cleaned up your allThere code to document that the break statement only breaks out of the options loop.
Checking to see if two 2D boolean arrays are equal at a given interval: Java
I have two 2d boolean arrays, the smaller array (shape) is going over the larger array (world). I am having trouble to find a method to find out when the smaller array can "fit" into the larger one. When I run the code it either just goes through the larger array, never stopping, or stops after one step (incorrectly). public void solve() { ArrayList<Boolean> worldList=new ArrayList<>(); ArrayList<Boolean> shapeList=new ArrayList<>(); for (int i = 0; i < world.length; i++) { for (int k = 0; k < world[i].length; k++) { worldList.add(world[i][k]); display(i, k, Orientation.ROTATE_NONE); for (int j = 0; j < shape.length; j++) { for (int l = 0; l < shape[j].length; l++) { shapeList.add(shape[j][l]); if(shapeList.equals(worldList)) { return; } } } } } }
A good place to start with a problem like this is brute force for the simplest case. So, for each index in the world list, just check to see if every following index of world and shapes match. Notice we only iterate to world.size()-shapes.size(), because naturally if shapes is longer than the portion of world we haven't checked, it won't fit. import java.util.ArrayList; public class Test { ArrayList<Boolean> world = new ArrayList<>(); ArrayList<Boolean> shapes = new ArrayList<>(); public static void main(String[] args) { new Work(); } public Test() { world.add(true); world.add(false); world.add(false); world.add(true); shapes.add(false); shapes.add(true); // Arraylists initialized to these values: // world: T F F T // shapes: F T System.out.println(getFitIndex()); } /** * Get the index of the fit, -1 if it won't fit. * #return */ public int getFitIndex() { for (int w = 0; w <= world.size()-shapes.size(); w++) { boolean fits = true; for (int s = 0; s < shapes.size(); s++) { System.out.println("Compare shapes[" + s + "] and world["+ (w+s) + "]: " + shapes.get(s).equals(world.get(w+s))); if (!shapes.get(s).equals(world.get(w+s))) fits = false; } System.out.println(); if (fits) return w; } return -1; } } When we run this code, we get a value of 2 printed to the console, since shapes does indeed fit inside world, starting at world[2].
You can find the row and column of fitting like this public void fit() { int h = world.length - shape.length; int w = world[0].length - shape[0].length; for (int i = 0; i <= h; i++) { for (int k = 0; k <= w; k++) { boolean found = true; for (int j = 0; j < shape.length && found; j++) { for (int l = 0; l < shape[j].length && found; l++) { if (shape[j][l] != world[i + j][k + l]) found = false; } } if (found) { //Your shape list fit the world list at starting index (i, k) //You can for example save the i, k variable in instance variable //Or return then as an object for further use return; } } }
Logic check for a 10*10 game
I am doing a game called 1010! Probably some of you have heard of it. Bascially I encouter some trouble when writing the Algorithm for clearance. The rule is such that if any row or any column is occupied, then clear row and column respectively. The scoring is such that each move gains a+10*b points. a is the number of square in the input piece p and b is the total number of row&column cleared. To start, I create a two dimensional Array board[10][10], poulate each elements in the board[][] with an empty square. In the class of Square, it has public void method of unset()-> "empty the square" & boolean status() -> "judge if square is empty"In the class of piece, it has int numofSquare -> "return the number of square in each piece for score calculation" In particular, I don't know how to write it if both row and column are occupied as they are inter-cross each other in an two dimensional array. It fail the test under some condition, in which some of the squares are not cleared but they should have been cleared and I am pretty sure is the logic problem. My thinking is that: Loop through squares in first row and first column, record the number of square that are occupied (using c and r); if both are 10, clear row&column, otherwise clear row or column or do nothing. reset the c &r to 0, loop through square in the second row, second column… update score. Basically the hard part is that if I seperate clear column and clear row algorithm ,I will either judge row or column first then clear them . However, as every column contains at least one square belong to the row, and every row contains at least one square belong to the column, there will be mistake when both row and column are full. Thanks for help. import java.util.ArrayList; public class GameState{ public static final int noOfSquares = 10; // the extent of the board in both directions public static final int noOfBoxes = 3; // the number of boxes in the game private Square[][] board; // the current state of the board private Box[] boxes; // the current state of the boxes private int score; // the current score // initialise the instance variables for board // all squares and all boxes are initially empty public GameState() { getboard(); score = 0; board = new Square[10][10]; for(int i =0;i<board.length;i++){ for(int j =0;j<board[i].length;j++){ board[i][j] = new Square(); } } boxes = new Box[3]; for(int k =0;k<boxes.length;k++){ boxes[k] = new Box(); } } // return the current state of the board public Square[][] getBoard() { return board; } // return the current score public int getScore() { return score; } // place p on the board with its (notional) top-left corner at Square x,y // clear columns and rows as appropriate int r =0; int c = 0; int rowandcolumn = 0; for (int row=0;row<10;row++){ for (int column=0;column<10;column++) { if (board[row][column].status() == true){ c = c + 1; if( c == 10 ) { rowandcolumn = rowandcolumn + 1; for(int z=0;z<10;z++){ board[row][z].unset(); //Clear column } } } if (board[column][row].status() == true){ r = r + 1; if( r == 10) { rowandcolumn = rowandcolumn + 1; for(int q=0;q<10;q++){ board[q][row].unset(); //Clear row } } } } r=0; //reset c=0; } score = score + p.numberofBox()+10*rowandcolumn; }
how about this void Background::liquidate(int &score){ int arr_flag[2][10]; //0 is row,1 is column。 for (int i = 0; i < 2; i++) { for (int j = 0; j < 10; j++) { arr_flag[i][j] = 1; } } //column for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (arr[i][j].type == 0) { arr_flag[0][i] = 0; break; } } } //row for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (arr[j][i].type == 0) { arr_flag[1][i] = 0; break; } } } //clear column for (int i = 0; i < 10; i++) { if (arr_flag[0][i] == 1) { for (int j = 0; j < 10; j++) { arr[i][j].Clear(); } } } //clear row for (int i = 0; i < 10; i++) { if (arr_flag[1][i] == 1) { for (int j = 0; j < 10; j++) { arr[j][i].Clear(); } } } }
I tried to write somme code for the idea I posted // place p on the board with its (notional) top-left corner at Square x,y // clear columns and rows as appropriate int r =0; int c = 0; int rowandcolumn = 0; int row=FindFirstRow(); int column=FindFirstColumn(); if(row!=-1 && column!=-1) { rowandcolumn++; //actions here: row found and column found //clear row and column clearRow(row); clearColumn(column); } else if(row!=-1) { //only row is found //clear row clearRow(row); } else if(column!=-1) { //only column is found //clear column clearColumn(column); } else { //nothing is found } public void clearRow(int row) { for(int i=0; i<10;i++) { board[row][i].unset(); } } public void clearColumn(int column) { for(int i=0; i<10;i++) { board[i][column].unset(); } } //this method returns the first matching row index. If nothing is found it returns -1; public int FindFirstRow() { for (int row=0;row<10;row++) { int r=0; for (int column=0;column<10;column++) { if (board[row][column].status() == true) { r = r + 1; if( r == 10) { //row found return row; } } } r=0; //reset } //nothing found return -1; } //this method returns the first matching column index. If nothing is found it returns -1; public int FindFirstColumn() { for (int column=0;column<10;column++) { int c=0; for (int row=0;row<10;row++) { if (board[row][column].status() == true) { c = c + 1; if( c == 10 ) { //matching column found return column; } } } c=0; //reset } //nothing found return -1; }
(8 Queens) Find out if a Queen fits in 2D matrix
I'm attempting to write a program which solves the 8 Queens Problem using a 2 dimensional array of booleans. I will use backtracking to find the solution. I know this is not the optimal way to solve this problem, and that I should probably go for a 1D array for simplicity, but I want to solve it this way. Right now I'm stuck on the function which is supposed to check whether a queen fits at a given coordinate. My row, column and down-right diagonal checks work, but I can't get the down-left diagonal check to work. I'm struggling to find the correct indexes of i and j (x and y) to start at, and which counter to increment/decrement for each iteration. Right now my function looks like this: public static boolean fits(int x, int y) { for(int i = 0; i < N; i++) { if(board[x][i]) { return false; // Does not fit on the row } } for(int i = 0; i < N; i++) { if(board[i][y]) { return false; // Does not fit on the column } } for(int i = Math.max(x-y, 0), j = Math.max(y-x, 0); i < N && j < N; i++, j++) { if(board[i][j]) { return false; // Down right diagonal issue } } for(int i = Math.min(x+y, N-1), j = Math.max(N-1-x, 0); i >= 0 && j < N; i--, j++) { if(board[i][j]) { return false; // Supposed to check the down-left diagonal, but does not work. } } return true; } As you can see there's a problem with the last loop here. I'd be very, very happy if someone could give me a working for-loop to check the down-left diagonal. Thanks in advance! Edit: Here's the working code: public class MyQueens { static boolean[][] board; static final int N = 8; public static void main(String[] args) { int p = 0; board = new boolean[N][N]; board[1][1] = true; System.out.println(fits(0, 2)); System.out.println(fits(2, 2)); } public static boolean fits(int x, int y) { for(int i = 0; i < N; i++) { if(board[x][i]) { return false; // Row } } for(int i = 0; i < N; i++) { if(board[i][y]) { return false; // Column } } for(int i = 0, j = 0; i < N && j < 0; i++, j++) { if(board[i][j]) { return false; // for right diagonal } } int mirrorx = (N-1)-x; for(int i = Math.max(mirrorx-y, 0), j = Math.max(y-mirrorx, 0); i < N && j < N; i++, j++) { if(board[(N-1)-i][j]) { return false; } } return true; } }
I'm attempting to write a program which solves the 8 Queens Problem using a 2 dimensional array of booleans. This is not the optimal representation, because you must use four loops to check if a queen can be placed or not. A much faster way of doing it is available. For the purposes of your program, there are four things that must be free of threats in order for a queen to be placed: A row, A column, An ascending diagonal, and A descending diagonal Each of these four things can be modeled with a separate array of booleans. There are eight rows, eight columns, fifteen ascending diagonals, and fifteen descending diagonals (including two degenerate cases of one-cell "diagonals" in the corners). Declare four arrays row[8], col[8], asc[15] and desc[15], and use these four methods to work with it: public static boolean fits(int r, int c) { return !row[r] && !col[c] && !asc[r+c] && !desc[c-r+7]; } public static void add(int r, int c) { set(r, c, true); } public static void remove(int r, int c) { set(r, c, false); } private static void set(int r, int c, boolean q) { row[r] = col[c] = asc[r+c] = desc[c-r+7] = q; }
Just flip the board horizontally and reuse the same algorithm as for the down right diagonal: int mirrorx = (N-1)-x; for(int i = Math.max(mirrorx-y, 0), j = Math.max(y-mirrorx, 0); i < N && j < N; i++, j++) { if(board[(N-1)-i][j]) { return false; } } You could re-arrange it to make it more optimal.
Why don't you just use: for(int i = 0, j = 0; i < N && j < 0; i++, j++) { if(board[i][j]) { return false; // for right diagonal } } Similarly: for(int i = 0, j = N-1; i < N && j >= 0; i++, j--) { if(board[i][j]) { return false; // for left diagonal } }
Null Pointer Exception - Printing 2d array
I'm having an issue with attempting to print a 2 dimensional array, I continually get a nullpointer exception at the first for loop in printArray(), and at printArray(). I do know what a nullpointerexception means, I'm just having a hard time understanding why I'm getting it. I've ran into this problem before while trying to print an array and it'd be great for me to finally figure this out. import java.lang.*; import java.util.*; public class Board { int N = 3; static int [][] unittest; //construct a board from an N-by-N array of blocks //(where blocks[i][j] = block in row i, column j) public Board(int[][] blocks){ blocks = new int[N][N]; //creates array of size N //generates random numbers 0 inclusive to # exclusive //Random r = new Random(); uses blocks[i][j] = r.nextInt(); for (int i = 0; i < blocks.length; i++){ for (int j = 0; j < blocks[i].length; j++){ blocks[i][j] = randInt(0,9); } } unittest = blocks.clone(); } //generates random numbers in a range private static int randInt( int min, int max){ Random rand = new Random(); int randomNum = rand.nextInt((max - min) + 1) + min; return randomNum; } //board size N public int size(){ return 0; //placeholder } //number of blocks out of place public int hamming(){ return 0; //placeholder } //sum of manhattan distances between blocks and goal public int manhattan(){ return 0; } //is this board the goal board? public boolean isGoal(){ return true; //placeholder } //is the board solvable? public boolean isSolvable(){ return true; //placeholder } //does this board equal y? //Object because can only take objects //does it use Comparable? public boolean equals(Object y){ return true; //placeholder } //all neighboring boards public Iterable<Board> neighbors(){ Stack<Board> placeholder = new Stack<Board>(); return placeholder; } //string representation of the board public String toString(){ return "placeholder"; } //unit test private static void printArray(){ for (int i = 0; i < unittest.length; i++){ //**NULL POINTER EXCEPTION for (int j = 0; j < unittest[i].length; j++){ System.out.print(unittest[i][j]); if (j < unittest[i].length - 1){ System.out.print(" "); } } System.out.println(); } } public static void main(String[] args){ //prints out board printArray(); //**NULL POINTER EXCEPTION } }
The problem lies in the test condition of printArray() function: for (int i = 0; i < unittest.length; i++) Here, unitest is a null object and when you try to apply length method on it, its throwing and exception. Basically, you are not initializing the unittest object (2D array in your case). You can do something like this to avoid the exception: private static void printArray(){ if(unittest == null) System.out.println("its NULL"); else{ for (int i = 0; i < unittest.length; i++){ //**NULL POINTER EXCEPTION for (int j = 0; j < unittest[i].length; j++){ System.out.print(unittest[i][j]); if (j < unittest[i].length - 1){ System.out.print(" "); } } System.out.println(); } } } Hope it helps :)
static int [][] unittest; is null when you call it you have never initialized the array, nor put anything into it
Beyond initializing the array you have an off by one error public Board(int[][] blocks){ blocks = new int[N][N]; //creates array of size N //generates random numbers 0 inclusive to # exclusive //Random r = new Random(); uses blocks[i][j] = r.nextInt(); for (int i = 0; i < blocks.length; i++){ <----------------- blocks length should be blocks.length-1 for (int j = 0; j < blocks[i].length; j++){ <---------------------also blocks [i].length - 1 blocks[i][j] = randInt(0,9); }