Java Method that checks for objects diagonally in 2D array - java

I am doing an N Queens Program in Java. I was able to print all the solutions where each Queen is on a different row and column. Now I need to keep track of the diagonals for collisions. So there are 2n-1 diagonal lines on a 2D array. The algorithm wants us to there are 2n-1 negative diagonal lines and 2n - 1 positive diagonal lines on the chessboard. There is an array of size 2n-1, called d1, that keeps track of the number of queens, i.e., the number of collisions, on each of the 2n-1 negative diagonal lines. If there are k queens on the mth negative diagonal line, there are k-1 collisions on this diagonal line. The
number k is written into the mth element of the d1 array. Similarly, we choose another array with size 2n-1, called d2, for 2n-1 positive diagonal lines.
Here is my method for D2, but I am completely lost. I know that all the up diagonals are row + col, but that is it.
public void D2(){
int[] upDiag = new int[2*board.length - 1];
int numberOfCollisions = 0;
for(int row = 0; row < board.length; row++){
for(int col = 0; col < board.length; col++){
if(isQueen(row, col)){
upDiag[numberOfCollisions++];
}
}
}
}

I've written a three-part series on the Eight-Queens/N-Queens Problem.
Here's a general outline of the problem, and a recursive solution.
Here's a genetic algorithm solution.
Here's a simulated annealing solution.
For the collision checking itself, something like this works very well:
double assessFitness(Integer[] candidate) {
int collisions = 0;
final int MAXIMUM_COLLISIONS = calculateMaxCollisions();
for (int i = 0; i < GRID_SIZE - 1; i++) {
for (int j = i + 1; j < GRID_SIZE; j++) {
if ((candidate[i].equals(candidate[j])) || j - i == Math.abs(candidate[i] - candidate[j]))
collisions++;
}
}
return (MAXIMUM_COLLISIONS - collisions) / (double) MAXIMUM_COLLISIONS;
}
Note that this is adapted from my genetic algorithm solution. I do explain why I return a value that scales from 0 to 1 in the blog article, but in your case a slight modification would yield the result you're looking for:
int countCollisions(Integer[] candidate) {
int collisions = 0;
final int MAXIMUM_COLLISIONS = calculateMaxCollisions();
for (int i = 0; i < GRID_SIZE - 1; i++) {
for (int j = i + 1; j < GRID_SIZE; j++) {
if ((candidate[i].equals(candidate[j])) || j - i == Math.abs(candidate[i] - candidate[j]))
collisions++;
}
}
return collisions;
}
In order for this to work, you do need to calculate the maximum allowable number of collisions for your N-Queens problem.
private int calculateMaxCollisions() {
int sum = 0;
for (int i = GRID_SIZE - 1; i > 0; i--) {
sum += i;
}
return sum;
}

Related

How to traverse diagonally through two dimensional array in Java?

I have a m x n matrix mat and I need to return an array of all the elements of the array in a diagonal order.
Input: mat = [[1,2,3],
[4,5,6],
[7,8,9]]
Output: [1,2,4,7,5,3,6,8,9]
public int[] findDiagonalOrder(int[][] mat){
int rows = mat.length;
int cols = mat[0].length;
int[] result = new int[rows * cols];
for(int i = 0; i <= rows - 1; i++){
for (int j = 0; j <= cols - 1; j++) {
while(i >= 0) {
i = i - 1;
j = j + 1;
from this point I dont know what should I do. Do you have any tips / advices how to continue to solve it myself?
I'm trying to figure out how to solve this problem by myself.
I'm trying to start from the first row and first column and then continue to traverse the array diagonally.

Avoid adding duplicates to an array

I would to store the distance between 4 clusters, so I took the sum of the distance between cluster x and cluster y and vise versa -since the distance between cluster x and cluster y != cluster y and cluster x- then divide them by 2 so it would be non directional.
The problem I'm facing here is the duplication. How can I end up with only 6 distances and avoid adding duplicates to the array in the first place.
Notes:
I made DistanceBetweenClusterToAnother a two dimensional array with the goal of solving this issue, since I couldn't solve it with one dimensional array.
this.clusterSize() equals 4.
for (int k = 0; k < this.clusterSize(); k++) {
for (int j = 0; j < this.clusterSize(); j++) {
if (k != j) {
DistanceBetweenClusterToAnother[k][j] = GADOfCluster1toCluster2[k][j] + GADOfCluster1toCluster2[j][k];
DistanceBetweenClusterToAnother[k][j]= DistanceBetweenClusterToAnother[k][j]/2;
}
}
}
Start the inner loop after the current position of the outer loop. Also, you can average in one line:
for (int k = 0; k < this.clusterSize(); k++) {
for (int j = k + 1; j < this.clusterSize(); j++) {
DistanceBetweenClusterToAnother[k][j] = (GADOfCluster1toCluster2[k][j] + GADOfCluster1toCluster2[j][k]) / 2;
}
}
Not sure if it would be the optimal way, but you can check the array for an match.
if (valueYouWantToCheck == Array.getIndex(i))
Array.add(valueYouWantToCheck);

Solve sudoku by backtracking (java)

public static int[][] solve(int[][] input){
for (int i = 0; i < 9*9; i++){
if(input[i / 9][i % 9] != 0){
continue;
}
for (int j = 1; j <= 9; j++){
if(validNumber(input, i / 9, i % 9, j)){
input[i / 9][i % 9] = j;
solve(input);
}
}
}
return input;
}
This method should solve a (solvable) sudoku puzzle via backtracking regardless of the initial situation. It works like this:
Given a sudoku puzzle it iterates from the upper left corner over each row to the lower right corner of the 2D array. When there is already a number, it gets skipped. When there is a zero (empty field) it calculates possible values via the validNumber method. The first valid number (from 1 to 9) is put in the field and the method goes to the next field.
In this algorithm the method does not now whether or not a valid number will eventually render the puzzle unsolvable.
I want to alter it like this:
At the end, when the method finishes iterating through the whole 2d array, every entry of the array gets tested if it is a zero or not.
If there is even one zero the whole algorithm must go to the place where the very first "valid" number was put in. Now, the next "valid" number is put in and so on until there are no zeroes at the end of the algorithm.
I have some troubles implementing this thought. It seems to me there must be an other for loop somewhere, or something like a goto statement, but I don't know where to put it.
Any advice?
I implemented a Sudoku solver once before. It was a bit more complicated than what you had, but solved the game in a blink. :)
What you are attempting to do is solve Sudoku by "Brute Force" and using (tail) recursion. That means you are attempting to solve the board by iterating over all 981 possible combinations. 9 to the power of 81 is... well it's a big number. And so your approach will take eternity, but you'll run out of stack space from the tail recursion much sooner.
When I implemented Sudoko, it was more straight up. It kept a 9x9 array of "items", where each item was the value in the square, and an array of 9 booleans representing candidates (true == viable, false == eliminated). And then it just did a non-recursive loop of solving the board.
The main loop would start with the simple process of finding squares with only 1 remaining candidate. Then the next step would do simple candidate elimination based on values already assigned. Then it would work its way into more complicated elimination techniques such as X-Wing.
Your algorithm does not actually backtrack. It moves forward if it can, but it never moves backwards when it realizes it's stuck in a corner. This is because it never returns any knowledge up the stack, and it never resets squares. Unless you get really lucky, your code will get the game board into a cornered state, and then print out that cornered state. To backtrack, you need to reset the last square you set (the one that got you cornered) to zero, so your algorithm will know to keep trying other things.
For understanding backtracking, I highly recommend a book called The Algorithm Design Manual by Steven Skiena. I read it when I was preparing for SWE interviews, and it really improved my knowledge of backtracking, complexity, and graph search. The second half of the book is a catalog of 75 classic algorithmic problems, and Sudoku is one of them! He has an interesting analysis of optimizations you can make to prune the search tree and solve very hard puzzle boards. Below is some code I wrote a long time ago after reading this chapter (probably not that high quality by my current standards, but it works). I just read through it really quickly and added the solveSmart boolean in the solve method which allows you to turn one of those optimizations on or off, which results in a pretty big time savings when solving a "hard" class Sudoku board (one with only 17 squares filled in to start with).
public class Sudoku {
static class RowCol {
int row;
int col;
RowCol(int r, int c) {
row = r;
col = c;
}
}
static int numSquaresFilled;
static int[][] board = new int[9][9];
static void printBoard() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(" " + (board[i][j] == 0 ? " " : board[i][j]) + " ");
if (j % 3 == 2 && j < 8)
System.out.print("|");
}
System.out.println();
if (i % 3 == 2 && i < 8)
System.out.println("---------|---------|---------");
}
System.out.println();
}
static boolean isEntireBoardValid() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (!isBoardValid(i, j)) {
return false;
}
}
}
return true;
}
static boolean isRowValid(int row) {
int[] count = new int[9];
for (int col = 0; col < 9; col++) {
int n = board[row][col] - 1;
if (n == -1)
continue;
count[n]++;
if (count[n] > 1)
return false;
}
return true;
}
static boolean isColValid(int col) {
int[] count = new int[9];
for (int row = 0; row < 9; row++) {
int n = board[row][col] - 1;
if (n == -1)
continue;
count[n]++;
if (count[n] > 1)
return false;
}
return true;
}
static boolean isSquareValid(int row, int col) {
int r = (row / 3) * 3;
int c = (col / 3) * 3;
int[] count = new int[9];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int n = board[r + i][c + j] - 1;
if (n == -1)
continue;
count[n]++;
if (count[n] > 1)
return false;
}
}
return true;
}
static boolean isBoardValid(int row, int col) {
return (isRowValid(row) && isColValid(col) && isSquareValid(row, col));
}
static RowCol getOpenSpaceFirstFound() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == 0) {
return new RowCol(i, j);
}
}
}
return new RowCol(0, 0);
}
static RowCol getOpenSpaceMostConstrained() {
int r = 0, c = 0, max = 0;
int[] rowCounts = new int[9];
int[] colCounts = new int[9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != 0)
rowCounts[i]++;
if (board[j][i] != 0)
colCounts[i]++;
}
}
int[][] squareCounts = new int[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int count = 0;
for (int m = 0; m < 3; m++) {
for (int n = 0; n < 3; n++) {
if (board[(i * 3) + m][(j * 3) + n] != 0)
count++;
}
}
squareCounts[i][j] = count;
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == 0) {
if (rowCounts[i] > max) {
max = rowCounts[i];
r = i;
c = j;
}
if (colCounts[j] > max) {
max = rowCounts[j];
r = i;
c = j;
}
}
}
}
return new RowCol(r, c);
}
static boolean solve() {
if (81 == numSquaresFilled) {
return true;
}
boolean solveSmart = true;
RowCol rc = solveSmart ? getOpenSpaceMostConstrained() : getOpenSpaceFirstFound();
int r = rc.row;
int c = rc.col;
for (int i = 1; i <= 9; i++) {
numSquaresFilled++;
board[r][c] = i;
if (isBoardValid(r, c)) {
if (solve()) {
return true;
}
}
board[r][c] = 0;
numSquaresFilled--;
}
return false;
}
public static void main(String[] args) {
// initialize board to a HARD puzzle
board[0][7] = 1;
board[0][8] = 2;
board[1][4] = 3;
board[1][5] = 5;
board[2][3] = 6;
board[2][7] = 7;
board[3][0] = 7;
board[3][6] = 3;
board[4][3] = 4;
board[4][6] = 8;
board[5][0] = 1;
board[6][3] = 1;
board[6][4] = 2;
board[7][1] = 8;
board[7][7] = 4;
board[8][1] = 5;
board[8][6] = 6;
numSquaresFilled = 17;
printBoard();
long start = System.currentTimeMillis();
solve();
long end = System.currentTimeMillis();
System.out.println("Solving took " + (end - start) + "ms.\n");
printBoard();
}
}
Eventually validNumber() method will not return any number because there is no possibilities left that means one of the previous choices was incorrect. Just imagine that the algorithm is started with the empty grid (obviously this puzzle is solvable1).
The solution is to keep tree of possible choices and if some choices are incorrect, then just remove them from the tree and use the next available choice (or step back on a higher level of the tree, if there is no choice left in this branch). This method should find a solution if any. (Actually this is how I implemented my sudoku solver some time ago.)
1 IMHO there are 3 different kinds of sudoku:
"true" correct sudoku that has a single unique complete solution;
ambiguous sudoku that has multiple distinct complete solutions, e.g. a puzzle with only 7 different numbers, so it has at least two distinct solutions that differ by swapping 8th and 9th numbers;
incorrect sudoku that has no complete solution, e.g. with a row with two or more occurrences of the same number.
With this definition, a solver algorithm should either:
prove that there is no solution;
return complete solution that satisfies the initial grid.
In the case of a "true" sudoku the result is a "true" solution by definition. In the case of an ambiguous sudoku the result can be different depending on the algorithm. An empty grid is the ultimate example of ambiguous sudoku.

Raising a matrix to the power method JAVA

I am having a really hard time creating a method to raise a matrix to the power. I tried using this
public static int powerMethod(int matrix, int power) {
int temp = matrix ;
for (int i = power; i == 1; i--)
temp = temp * matrix ;
return temp ;
but the return is WAYYY off. Only the first (1,1) matrix element is on point.
I tried using that method in a main like so
// Multiplying matrices
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
for (l = 0; l < row; l++)
{
sum += matrix[i][l] * matrix[l][j] ;
}
matrix[i][j] = sum ;
sum = 0 ;
}
}
// Solving Power of matrix
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++)
matrixFinal[power][i][j] = Tools.powerMethod(matrix[i][j], power) ;
}
Where "power", "row", and "column" is an int that the user enters.
Any ideas how I can do this??
Thanks!!!
You have a lot of issues here.
First, your matrix squaring algorithm has a (common) error. You have:
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
for (l = 0; l < row; l++) {
sum += matrix[i][l] * matrix[l][j] ;
}
matrix[i][j] = sum ;
sum = 0 ;
}
}
However, you need to store the result in a temporary second matrix, because when you do matrix[i][j] = sum, it replaces the value at that position with the output, then later results end up being incorrect. Also I suggest initializing sum to 0 first, since it appears you declare it outside of this loop, and initializing it first protects you against any arbitrary value sum may have before going into the loop. Furthermore, it is not immediately clear what you mean by row and column -- make sure you are iterating over the entire matrix. E.g.:
int temp[][] = new int[matrix.length];
for (i = 0; i < matrix.length; i++) {
temp[i] = new int[matrix[i].length];
for (j = 0; j < matrix[i].length; j++) {
sum = 0 ;
for (l = 0; l < matrix.length; l++) {
sum += matrix[i][l] * matrix[l][j] ;
}
temp[i][j] = sum ;
}
}
// the result is now in 'temp', you could do this if you wanted:
matrix = temp;
Note that matrix.length and matrix[i].length are fairly interchangeable above if the matrix is square (which it must be, in order to be multiplied by itself).
Secondly, your multiplication squares a matrix. This means if you repeatedly apply it, you keep squaring the matrix every time, which means you will only be able to compute powers that are themselves powers of two.
Your third issue is your final bit doesn't make much sense:
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++)
matrixFinal[power][i][j] = Tools.powerMethod(matrix[i][j], power) ;
}
It's not immediately clear what you are trying to do here. The final part seems to be trying to raise individual elements to a certain power. But this is not the same as raising a matrix to a power.
What you need to do is define a proper matrix multiplication method that can multiply two arbitrary matrices, e.g.:
int[][] multiplyMatrices (int[][] a, int[][] b) {
// compute and return a x b, similar to your existing multiplication
// algorithm, and of course taking into account the comments about
// the 'temp' output matrix above
}
Then computing a power becomes straightforward:
int[][] powerMatrix (int[][] a, int p) {
int[][] result = a;
for (int n = 1; n < p; ++ n)
result = multiplyMatrices(result, a);
return result;
}
Why not just use Math.pow?
import java.lang.Math;
Then you just have to do
matrixFinal[power][i][j] = (int) Math.pow(matrix[i][j],power); //might have to cast this to an int

Java Sudoku Squares 3x3 Checking Validity

I'm working on a Java program that checks if a sudoku puzzle is solved or not. I have finished the horizontal and vertical number check part. But when trying to check squares, I can't do anything. Here is how my check system works.
This is what I want to make. Hope someone helps because I'm on a hard situation with square check.
int[][] SudokuBoard = new int[9][9];
// I didn't wrote the sudoku board completely hope you understood how sudoku table looks like.
public static boolean checkSquares(int[][] SquareBoard) {
int retr = false;
int loop = 0;
int[] extraboard = new int[9];
int[] truelist ={1,2,3,4,5,6,7,8,9};
for(int i = 1; i <=9 ; I++) {
//here , extraboard will have the numbers in " i " numbered sudoku square.( i is like first //,second)
Arrays.sort(extraboard);
for(int j = 0; j < 9; j++) {
if(extraboard[j] == truelist[j])
loop += 1;
}
extraboard = new int[9];
}
if(loop == 81)
retr == true;
return retr;
}
You could do
int count = 0;
for(int k = 0; k < 9; k++) {
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
extraboard[count++] = SquareBoard[i+3*k/3][j+k%3*3];
}
}
Arrays.sort(extraboard);
for(int j = 0; j < 9; j++) {
if(extraboard[j] == truelist[j])
loop += 1;
}
extraboard = new int[9];
count = 0;
}
The actual formula to calculate the location in the box is quite simple. As the board is split into rows and column, getting the location of the row and column needs to get offset based on the location of the box in the full area.
i here counts the index within the box of the row. As each row of boxes has a length of 3 in a 9x9 sudoku we need to increase the row number by 3 each time we get 3 boxes in. To figure out and only add 3 we can use some integer division.
For example:
i+i.length*k/i.length
This is obviously an syntax error as i doesn't have length but can consider it as the limit of i in the loop (in this case 3).
This would then get the current row in the box (the first i) and add that to the offset of boxes in the sudoki. That is for every 3 boxes k/i.length becomes 1 more, and we then multiply that with 3 to get the offset of 3.
In the column part we have a bit of an bigger issue as we need to offset it for every 3 we move left in the array and reset it when we get back to boxes on the far left.
So the forumla would become
j + (k%i.length)*j.length
This would give us the column in the box we are in, then we offset by the box location with k%i.length. The reason we use the i.length and not the j.length is that we need to calculate the offset by rows and then offset it by the length of the box column wise.
With this you can then apply to this to any size board. 2x2, 2x3, 3x2, 3x3 or bigger even.
public static boolean checkSquares(int[][] SquareBoard) {
int i=0, extraboard=0;
for (;i<9;i++,extraboard=0) {
for (int j=0;j<9;j++)
extraboard+=1<<(SquareBoard[i/3*3+j/3][i%3*3+j%3]-1);
if (extraboard!=(1<<9)-1) // 511, binary(511) = 111111111
break;
}
return i==9;
}
This is a solution i came up with. it uses 4 nested loops but the time complexity is still O(n^2). Basically i check the first 3 boxes on top, then the 3 boxes in the middle, then the last 3 boxes.
for (int l = 0; l < 9; l+= 3){
for (int i = 0; i < 9; i += 3){
HashSet<Character> set = new HashSet<>();
for (int j = l; j < l+3; j++){
for (int k = i; k < i+3; k++){
if (!set.contains(board[j][k])){
if (board[j][k] != '.')
set.add(board[j][k]);
}
else
return false;
}
}
}
}
return true;
and note that the sudoku might not be complete, and the missing numbers are replaced by ' . '

Categories

Resources