n Queens Java not working for 4 by 4 - java

My n Queens variation with an input seems to work for all inputs except 4x4 boards. It takes a board size and a starting position for 1 queen. Is there a reason why it isn't working for that size? I tried inputting 4 1 2 and it doesn't create a board properly
import java.io.*;
public class nQueens {
public static int N;
public static int skipCol;
public static int permaRow;
public static void printSolution(int board[][]) {
PrintWriter file = null;
try {
file = new PrintWriter("solution.txt");
// Prints Board to solution.txt
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (board[i][j] == 1) {
// If board = 1 then there is a Queen, 0 then empty
file.println((i + 1) + " " + (j + 1));
}
}
}
file.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean isSafe(int board[][], int row, int col) {
// Returns True if safe, returns False if not safe
// Checks all columns in the row
int i,j;
for (i = 0; i < col; i++) {
if (board[row][i] == 1) {
return false;
}
}
// Check Diagonals (upper then lower)
for (i = row, j = col; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 1) {
return false;
}
}
for (i = row, j = col; j >= 0 && i < N; i++, j--) {
if (board[i][j] == 1) {
return false;
}
}
return true;
}
public static boolean solveNQueensCol(int board[][], int col) {
if (col >= N) { // Base Case, checks if all queens are placed
return true;
}
if (col != skipCol) {
for (int i = 0; i < N; i++) {
if (isSafe(board, i, col)) {
board[i][col] = 1; // Changes that board space to Queen
if (solveNQueensCol(board, col + 1) == true) {
// Recursively places all the Queens onto the board
return true;
}
// If placing queen at i, col doesn't work, remove it
board[i][col] = 0;
}
}
} else {
board[permaRow][skipCol] = 1; // One Preset Queen
return solveNQueensCol(board,col+1);
}
return false;
}
public static boolean solveNQueens(int x, int y) {
// Creates new board with size N
int board[][] = new int[N][N];
for (int i = 0; i < N; i++) { // Fills board with 0s
for (int j = 0; j < N; j++) {
board[i][j] = 0;
}
}
permaRow = x;
skipCol = y;
if (solveNQueensCol(board, 0) == false) {
PrintWriter file = null;
try {
file = new PrintWriter("solution.txt");
// Prints Board to solution.txt
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (board[i][j] == 1) {
// If board = 1 then there is a Queen, 0 then empty
file.println((i + 1) + " " + (j + 1));
}
}
}
file.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
printSolution(board);
return true;
}
public static void main(String[] args) {
N = Integer.parseInt(args[0]);
solveNQueens(Integer.parseInt(args[1]) - 1, Integer.parseInt(args[2]) - 1);
}
}

If rows and columns are counted from 0 to 3, there is no solution when a queen starts in position 1,2.

Related

Solve Sudoko in Java

I've written the code as per the logic, but my Eclipse console is empty when I click 'Run'.
This is my code:
public class test {
public static void main(String[] args) {
int[][] board = new int[9][9];
helper(board, 0, 0);
}
public static void saveBoard(int[][] board) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board.length; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
}
public static void helper(int[][] board, int row, int col) {
if (row == board.length - 1) {
saveBoard(board);
return;
}
if (col == board.length - 1) {
col = 0;
row += 1;
}
for (int i = 1; i <= 9; i++) {
if (isSafe(board, row, col, i)) {
board[row][col] = i;
helper(board, row, col + 1);
}
}
}
public static boolean isSafe(int[][] board, int row, int col, int number) {
// row & column
for (int i = 0; i < board.length; i++) {
if (board[row][i] == number) return false;
if (board[i][col] == number) return false;
}
// grid
int sc = (col / 3) * 3;
int sr = (row / 3) * 3;
for (int i = 0; i < sr + 3; i++) {
for (int j = 0; j < sc + 3; j++) {
if (board[i][j] == number) return false;
}
}
return true;
}
}
or here's a screenshot

Java: Sudoku- increase number of empty spaces causes my code to throw an exception

I'm trying to make a Sudoku game for my project but if i increase the number of empty spaces in the Sudoku Grid the code just throws an exception arrayoutofbounds but can't figure out where it's coming from. k is the number of empty spaces in the grid.
I haven't tried anything because can't figure out what can be done at this kind of problem
Here is the code:
package sudoku.puzzle;
import java.util.*;
public class SudokuPuzzle {
int[] mat[];
int N; // number of columns/rows.
int SRN; // square root of N
int K; // No. Of missing digits
// Constructor
SudokuPuzzle(int N, int K) {
this.N = N;
this.K = K;
// Compute square root of N
Double SRNd = Math.sqrt(N);
SRN = SRNd.intValue();
mat = new int[N][N];
}
// Driver code
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Select Level Of Difficulty \n 1.Easy\n 2.Medium\n 3.Hard");
String Choice = in .next(); in .close();
if ("1".equals(Choice) || "Easy".equals(Choice) || "easy".equals(Choice) || "e".equals(Choice) || "E".equals(Choice)) {
int N = 9, K = 40;
SudokuPuzzle sudoku = new SudokuPuzzle(N, K);
sudoku.fillValues();
sudoku.printSudoku();
}
if ("2".equals(Choice) || "Medium".equals(Choice) || "medium".equals(Choice) || "m".equals(Choice) || "M".equals(Choice)) {
int N = 9, K = 60;
SudokuPuzzle sudoku = new SudokuPuzzle(N, K);
sudoku.fillValues();
sudoku.printSudoku();
}
if ("3".equals(Choice) || "Hard".equals(Choice) || "hard".equals(Choice) || "h".equals(Choice) || "H".equals(Choice)) {
int N = 9, K = 72;
SudokuPuzzle sudoku = new SudokuPuzzle(N, K);
sudoku.fillValues();
sudoku.printSudoku();
}
}
// Sudoku Generator
public void fillValues() {
// Fill the diagonal of SRN x SRN matrices
fillDiagonal();
// Fill remaining blocks
fillRemaining(0, SRN);
// Remove Randomly K digits to make game
removeKDigits();
}
// Fill the diagonal SRN number of SRN x SRN matrices
void fillDiagonal() {
for (int i = 0; i < N; i = i + SRN)
// for diagonal box, start coordinates->i==j
fillBox(i, i);
}
// Returns false if given 3 x 3 block contains num.
boolean unUsedInBox(int rowStart, int colStart, int num) {
for (int i = 0; i < SRN; i++)
for (int j = 0; j < SRN; j++)
if (mat[rowStart + i][colStart + j] == num)
return false;
return true;
}
// Fill a 3 x 3 matrix.
void fillBox(int row, int col) {
int num;
for (int i = 0; i < SRN; i++) {
for (int j = 0; j < SRN; j++) {
do {
num = randomGenerator(N);
}
while (!unUsedInBox(row, col, num));
mat[row + i][col + j] = num;
}
}
}
// Random generator
int randomGenerator(int num) {
return (int) Math.floor((Math.random() * num + 1));
}
// Check if safe to put in cell
boolean CheckIfSafe(int i, int j, int num) {
return (unUsedInRow(i, num) &&
unUsedInCol(j, num) &&
unUsedInBox(i - i % SRN, j - j % SRN, num));
}
// check in the row for existence
boolean unUsedInRow(int i, int num) {
for (int j = 0; j < N; j++)
if (mat[i][j] == num)
return false;
return true;
}
// check in the row for existence
boolean unUsedInCol(int j, int num) {
for (int i = 0; i < N; i++)
if (mat[i][j] == num)
return false;
return true;
}
// A recursive function to fill remaining
// matrix
boolean fillRemaining(int i, int j) {
// System.out.println(i+" "+j);
if (j >= N && i < N - 1) {
i = i + 1;
j = 0;
}
if (i >= N && j >= N)
return true;
if (i < SRN) {
if (j < SRN)
j = SRN;
} else if (i < N - SRN) {
if (j == (int)(i / SRN) * SRN)
j = j + SRN;
} else {
if (j == N - SRN) {
i = i + 1;
j = 0;
if (i >= N)
return true;
}
}
for (int num = 1; num <= N; num++) {
if (CheckIfSafe(i, j, num)) {
mat[i][j] = num;
if (fillRemaining(i, j + 1))
return true;
mat[i][j] = 0;
}
}
return false;
}
// Remove the K no. of digits to
// complete game
public void removeKDigits() {
int count = K;
while (count != 0) {
int cellId = randomGenerator(N * N);
// System.out.println(cellId);
// extract coordinates i and j
int i = (cellId / N);
int j = cellId % 9;
if (j != 0)
j = j - 1;
// System.out.println(i+" "+j);
if (mat[i][j] != 0) {
count--;
mat[i][j] = 0;
}
}
}
// Print sudoku
public void printSudoku() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
System.out.print(mat[i][j] + " ");
System.out.println();
}
System.out.println();
}
}
What you got is probably a ArrayIndexOutOfBoundsException. That means at some point you try to access a field of an array outside its boundaries.
But I canĀ“t see where K could be responsible for that. Can you provide more information about the error? E.g. at which value you get it or in which line.
EDIT: The variable i int the removeKDigits() function exceeds the boundaries of the array if the random generator spits out the value 81.

Java Loop star pattern - algorithm optimalization

Can anyone tell me what is the more elegant solution for outputting this pattern?
I most interested in my makeTemplate method, but any other help will be appreciated.
Here is my code, which i want to be more readable:
public class Main {
public static void makeTemplate(char tab[][], int rows, int col) {
boolean increase = true;
int j = 0;
char star = '*';
for (int i = 0; i < rows; i++) {
if (increase) {
tab[i][j] = star;
if (j >= col - 1) {
increase = false;
j--;
continue;
}
j++;
} else {
tab[i][j] = star;
if (j < 0 + 1) {
increase = true;
j++;
continue;
}
j--;
}
}
}
public static void main(String[] args) {
char[][] tab = new char[30][6];
makeTemplate(tab, 30, 6);
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 6; j++) {
System.out.print(tab[i][j]);
}
System.out.println();
}
}
}
Only made some changes to makeTemplate
public static void makeTemplate(char tab[][], int rows, int col) {
boolean increase = true;
int j = 0;
char star = '*';
for (int i = 0; i < rows; i++) {
tab[i][j] = star;
if (increase) {
if (j >= col - 1) {
increase = false;
j--;
} else {
j++;
}
} else {
if (j < 1) {
increase = true;
j++;
}else {
j--;
}
}
}
}
Replaced the continue statements with else as the continue statement pretty much does the same thing as the else. Using continue in the if statement says to skip the j++ or j-- below. So instead the j++ or j-- will only be executed if the if is true.
I also changed if(j < 0 + 1) to if(j < 1) as 0+1 = 1
Moved tab[i][j] = star; before the first if as it is the first line in the if and else - Thanks Betlista
Elegant java8 solution:
IntStream.range(0, ROWS).forEach(i -> {
int cur = i % (COLS * 2);
if(cur < 6) {
IntStream.range(0, cur).forEach(f -> System.out.print(" "));
} else {
IntStream.range(0, COLS - cur % COLS).forEach(f -> System.out.print(" "));
}
System.out.println("*");
});
Granted, I haven't used the makeTemplate() method but as far as elegance and understand-ability goes, this does the job well.
You can use recursion
public static char[][] makeTemplate(char tab[][], int rows, int col, int curRow, int curPos, boolean increase) {
if (curRow == rows)
return tab;
tab[curRow][curPos] = '*';
if (increase && curPos + 1 == col) {
increase = false;
} else if (curPos == 0) {
increase = true;
}
return makeTemplate(tab, rows, col, curRow + 1, (increase) ? ++curPos : --curPos, increase);
}
public static void main(String[] args) {
char[][] tab = makeTemplate(new char[30][6], 30, 6, 0, 0, true);
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 6; j++) {
System.out.print(tab[i][j]);
}
System.out.println();
}
}

How do I avoid getting NullPointerException in my Matrix sum?

I want to check if the sum of each row in any matrix is equal. How should I rewrite this to avoid NPE?
I can make it work for "normal" matrices like int[][] a = {{1,2,3}, {4,5,6}}, but I want it to work even when testing with null and empty matrices.
public static boolean allRowSumsEqual(int[][] m) {
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
As you said, this does work for most matrices. There are a few places I might check for null, see modified code below:
public static boolean allRowSumsEqual(int[][] m){
if(m == null) return true;
if(m.length == 0) return true;
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 1; i < m.length; i++){
// You can use your own function instead of the inner for loop
x = rowSum(m[i]);
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v){
int vSum = 0;
// Assume a null row has sum 0
if(v == null) return 0;
for (int i = 0 ; i < v.length ; i++){
vSum += v[i];
}
return vSum;
}
You need to define a result or an exception if you want to check for "null" parameter. You can return true if null is valid or false otherwise.
if(m == null) return true;
Empty or one lined matrices can return true all the time and does not require any calculation:
if(m.length < 2) return true;
The line test is more simple, I think:
// expect a positiv result
boolean result = true;
// calculate first line
int firstLine = rowSum(m[0]);
// loop remaining lines
for (int i = 1 ; i < m.length ; i++){
// compare first line with current line
if (firstLine != rowSum(m[i]))
{
// not equal -> change result
result = false;
// break loop
break;
}
}
return result;
public class Snippet {
public static boolean allRowSumsEqual(int[][] m) {
if (null == m || 0 == m.length)
return true;
boolean a = false;
int x = 0;
int total = 0;
if (null != m[0])
total = rowSum(m[0]);
for (int i = 1; i < m.length; i++) {
if (null != m[i]) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
} else
x = 0;
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
public static void main(String[] args) {
int[][] a = { { 1, 2, 3 }, { 3, 2, 1 }, null };
System.out.println(allRowSumsEqual(a));
int[][] b = { null, null, null };
System.out.println(allRowSumsEqual(b));
}
}
What do you think of this solution:
public static boolean allRowSumsEqual(int[][] m) {
if(m == null) { return false; }
int sum = 0;
for(int i = 0; i < m.length; i++) {
int temp = 0;
if(m[i] == null) { continue; }
for(int j = 0; j < m[i].length; j++) {
temp += m[i][j];
}
if(i == 0) { //is the first row
sum = temp;
}
else if(sum != temp) {
return false;
}
}
return true;
}

Sudoku Checker java

public class Sudoku {
public static void main(String[] args) {
// Row and column Latin but with invalid subsquares
String config1 = "1234567892345678913456789124567891235678912346" + "78912345789123456891234567912345678";
String[][] puzzle1 = makeSudoku(config1);
if (isValidSudoku(puzzle1)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle1));
System.out.println("--------------------------------------------------");
// Row Latin but column not Latin and with invalid subsquares
String config2 = "12345678912345678912345678912345678912345678" + "9123456789123456789123456789123456789";
String[][] puzzle2 = makeSudoku(config2);
if (isValidSudoku(puzzle2)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle2));
System.out.println("--------------------------------------------------");
// A valid sudoku
String config3 = "25813764914698532779324685147286319558149273663" + "9571482315728964824619573967354218";
String[][] puzzle3 = makeSudoku(config3);
if (isValidSudoku(puzzle3)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle3));
System.out.println("--------------------------------------------------");
}
public static String[][] makeSudoku(String s) {
int SIZE = 9;
int k = 0;
String[][] x = new String[SIZE][SIZE];
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
x[i][j] = s.substring(k, k + 1);
k++;
}
}
return x;
}
public static String getPrintableSudoku(String[][] x) {
int SIZE = 9;
String temp = "";
for (int i = 0; i < SIZE; i++) {
if ((i == 3) || (i == 6)) {
temp = temp + "=================\n";
}
for (int j = 0; j < SIZE; j++) {
if ((j == 3) || (j == 6)) {
temp = temp + " || ";
}
temp = temp + x[i][j];
}
temp = temp + "\n";
}
return temp;
}
//sudoku validation
public static boolean isValidSudoku(String[][] x) {
return rowsAreLatin(x) && colsAreLatin(x) && goodSubsquares(x);
}
public static boolean rowsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume rows are latin
for (int i = 0; i < 9; i++) {
result = result && rowIsLatin(x, i); // Make sure each row is latin
}
return result;
}
public static boolean rowIsLatin(String[][] x, int i) {
boolean[] found = new boolean[9];
for (int j = 0; j < 9; j++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int j = 0; j < 9; j++) {
if (!found[j]) {
return false;
}
}
return true;
}
public static boolean colsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume cols are latin
for (int j = 0; j < 9; j++) {
result = result && colIsLatin(x, j); // Make sure each row is latin
}
return result;
}
public static boolean colIsLatin(String[][] x, int j) {
// fill in your code here
boolean[] found = new boolean[9];
for (int i = 0; i < 9; i++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int i = 0; i < 9; i++) {
if (!found[i]) {
return false;
}
}
return true;
}
public static boolean goodSubsquares(String[][] x) {
return true;
}
public static boolean goodSubsquare(String[][] x, int i, int j) {
boolean[] found = new boolean[9];
// We have a 3 x 3 arrangement of subsquares
// Multiplying each subscript by 3 converts to the original array subscripts
for (int p = i * 3, rowEnd = p + 3; p < rowEnd; p++) {
for (int q = j * 3, colEnd = q + 3; q < colEnd; q++) {
found[Integer.parseInt(x[p][q])] = true;
}
}
for (int p = 0; p < 9; p++) {
if (!found[p]) {
return false;
}
}
return true;
}
}
This the error I am getting. Help!
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at Sudoku.rowIsLatin(Sudoku.java:104)
at Sudoku.rowsAreLatin(Sudoku.java:93)
at Sudoku.isValidSudoku(Sudoku.java:85)
at Sudoku.main(Sudoku.java:8)
Java Result: 1
The problem is with the line:
Integer.parseInt(x[i][j])
Sudoku numbers range from [1, 9], but indices for an array (of length 9) range from [0, 8]. So, when the (i, j) element is a 9, the index is 9 and therefore the IndexOutOfBoundsException is being thrown.
You'll have to change it to
found[Integer.parseInt(x[i][j]) - 1] = true;
Note that you also make the same mistake in the column's respective method.

Categories