I'm browsing through some sudoku solvers and I'm looking for one that utilizes backtracking, now I've found this code but I'm not really sure whether it uses backtracking or some other algorithm?
Help is appreciated.
abstract class SudoKiller {
private SudokuBoard sb; // Puzzle to solve;
public SudoKiller(SudokuBoard sb) {
this.sb = sb;
}
private boolean check(int num, int row, int col) {
int r = (row / sb.box_size) * sb.box_size;
int c = (col / sb.box_size) * sb.box_size;
for (int i = 0; i < sb.size; i++) {
if (sb.getCell(row, i) == num ||
sb.getCell(i, col) == num ||
sb.getCell(r + (i % sb.box_size), c + (i / sb.box_size)) == num) {
return false;
}
}
return true;
}
public boolean guess(int row, int col) {
int nextCol = (col + 1) % sb.size;
int nextRow = (nextCol == 0) ? row + 1 : row;
try {
if (sb.getCell(row, col) != sb.EMPTY)
return guess(nextRow, nextCol);
}
catch (ArrayIndexOutOfBoundsException e) {
return true;
}
for (int i = 1; i <= sb.size; i++) {
if (check(i, row, col)) {
sb.setCell(i, row, col);
if (guess(nextRow, nextCol)) {
return true;
}
}
}
sb.setCell(sb.EMPTY, row, col);
return false;
}
}
And if this is not backtracking, is there an easy way to "convert" to it?
The whole project can be found on the authors site.
Looks like it does backtracking via recursion.
Here we step forward:
sb.setCell(i, row, col);
and here we step backward:
sb.setCell(sb.EMPTY, row, col);
Related
I wrote a program for the percolation problem for the Coursera Algorithms course. Everything seems to compile successfully, but when I run it in terminal, it just freezes and no output is shown. Is my performance just way too slow, or is there a bug somewhere in my code? Code is posted below, the arguments I use are n = 200 and 100 trials. Thank you so much in advance!
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private WeightedQuickUnionUF grid;
private WeightedQuickUnionUF grid2;
private boolean[] openSites;
private int numOpenSites, gridLength, topIndex, bottomIndex;
public Percolation(int n) {
// create n-by-n grid, with all sites blocked
if (n <= 0) {
throw new IllegalArgumentException();
}
int numNodes = (n * n) + 2;
grid = new WeightedQuickUnionUF(numNodes);
grid2 = new WeightedQuickUnionUF(numNodes);
openSites = new boolean[n * n];
numOpenSites = 0;
gridLength = n;
topIndex = n * n;
bottomIndex = n * n + 1;
}
public void open(int row, int col) { // open site (row, col) if it is not open already
//check if row and col are valid
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
//if not open, then open
if (!isOpen(row, col)) {
openSite(row, col);
connectTopVirtualSite(row, col);
connectAdjacentSites(row, col);
connectBottomVirtualSite(row, col);
numOpenSites++;
}
}
private void openSite(int row, int col) {
int index = convertToIndex(row, col);
//set that site to true
openSites[index] = true;
}
private void connectTopVirtualSite(int row, int col) {
if (row == 1) {
grid.union(topIndex, convertToIndex(row, col));
grid2.union(topIndex, convertToIndex(row, col));
}
}
private void connectAdjacentSites(int row, int col) {
connectTop(row, col);
connectLeft(row, col);
connectRight(row, col);
connectBottom(row, col);
}
private void connectTop(int row, int col) {
if (row > 1 && isOpen(row - 1, col)) {
grid.union(convertToIndex(row - 1, col), convertToIndex(row, col));
grid2.union(convertToIndex(row - 1, col), convertToIndex(row, col));
}
}
private void connectLeft(int row, int col) {
if (col > 1 && isOpen(row, col - 1)) {
grid.union(convertToIndex(row, col - 1), convertToIndex(row, col));
grid2.union(convertToIndex(row, col - 1), convertToIndex(row, col));
}
}
private void connectRight(int row, int col) {
if (col < gridLength && isOpen(row, col + 1)) {
grid.union(convertToIndex(row, col), convertToIndex(row, col + 1));
grid2.union(convertToIndex(row, col), convertToIndex(row, col + 1));
}
}
private void connectBottom(int row, int col) {
if (row < gridLength && isOpen(row + 1, col)) {
grid.union(convertToIndex(row, col), convertToIndex(row + 1, col));
grid2.union(convertToIndex(row, col), convertToIndex(row + 1, col));
}
}
private void connectBottomVirtualSite(int row, int col) {
if (row == gridLength) {
grid2.union(convertToIndex(row, col), bottomIndex);
}
}
private int convertToIndex(int row, int col) {
return gridLength * (row - 1) + (col - 1);
}
public boolean isOpen(int row, int col) { // is site (row, col) open?
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
return openSites[convertToIndex(row, col)];
}
public boolean isFull(int row, int col) { // is site (row, col) full?
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
return grid.connected(convertToIndex(row, col), topIndex);
}
public int numberOfOpenSites() { // number of open sites
return numOpenSites;
}
public boolean percolates() { // does the system percolate?
return grid2.connected(topIndex, bottomIndex);
}
//public static void main(String[] args) // test client (optional)
}
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
import static java.lang.Math.sqrt;
public class PercolationStats {
private double[] results;
public PercolationStats(int n, int trials) {
if (n <= 0 || trials <= 0) {
throw new IllegalArgumentException();
}
results = new double[trials];
//fill up results with the p values of every trial
runExperiments(n, trials);
}
private void runExperiments(int n, int trials) {
int row, col;
for (int i = 0; i < trials; i++) {
Percolation test = new Percolation(n);
while (!test.percolates()) {
//generate new random row and col
row = StdRandom.uniform(n - 1) + 1;
col = StdRandom.uniform(n - 1) + 1;
test.open(row, col);
}
results[i] = (double)(test.numberOfOpenSites()) / (n * n);
}
}
public double mean() {
//return sample mean of all the p values
return StdStats.mean(results);
}
public double stddev() {
//return sample standard deviation of percolation threshold
return StdStats.stddev(results);
}
public double confidenceLo() {
return mean() - ((1.96 * stddev()) / sqrt(results.length));
}
public double confidenceHi() {
return mean() + ((1.96 * stddev()) / sqrt(results.length));
}
public static void main(String[] args) {
PercolationStats test = new PercolationStats(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
System.out.println("mean = " + test.mean());
System.out.println("stddev = " + test.stddev());
System.out.println("95% confidence interval = [" + test.confidenceLo() + ", " + test.confidenceHi() + "]");
}
}
I'm building a 2D grid game composed of cells in which players have to put tokens and try to contain (encircle) the opponent's tokens. Now each cell can have 3 states: empty, contains a red token or contains a blue token.
All cells that can form a "path" are in a list, and along that path I can draw lines (polygons) passing by the center of cells.
Also there is a list of contained tokens, the one being encircled,
Now I want to find a way to "invalidate" an encircled token so it can be ignored by path calculations
See examples below:
Blue tokens are encircled first, they cannot be apart of any further path calculation.
This cannot be allowed. First to contain, first to win.
All codes below are from the path class:
class Path extends Stack<int[]>{
private Token[][] grid;
//a path shorter than min can not surround any cell
private static final int MIN_PATH_LEGTH = 3;
//a collection of cells that has been tested
private ArrayList<int[]>checked;
//represents the cell where the search starts from
int[] origin;
//represents the token of the origin
Token originToken;
private int rows;
private int cols;
//represents the path bounds: min/max row/col in path
private int minPathRow, maxPathRow, minPathCol, maxPathCol;
Path(Token[][] grid){
this.grid = grid;
rows = grid.length;
cols = grid[0].length;
}
//search for a path
boolean findPath(int[] origin) {
this.origin = origin;
int row = origin[0] , col = origin[1];
//represents the token of the origin
originToken = grid[row][col];
//initialize list of checked items
checked = new CellsList();
boolean found = findPath(row, col);
if(found) {
printPath();
} else {
System.out.println("No path found");
}
return found;
}
//recursive method to find path. a cell is represented by its row, col
//returns true when path was found
private boolean findPath(int row, int col) {
//check if cell has the same token as origin
if(grid[row][col] != originToken) {
return false;
}
int[] cell = new int[] {row, col};
//check if this cell was tested before to avoid checking again
if(checked.contains(cell)) {
return false;
}
//get cells neighbors
CellsList neighbors = getNeighbors(row, col);
//check if solution found. If path size > min and cell
//neighbors contain the origin it means that path was found
if((size() >= MIN_PATH_LEGTH) && neighbors.contains(origin) ) {
add(cell);
return true;
}
//add cell to checked
checked.add(cell);
//add cell to path
add(cell);
//if path was not found check cell neighbors
for(int[] neighbor : neighbors ) {
boolean found = findPath(neighbor[0],neighbor[1]);
if(found) {
return true;
}
}
//path not found
pop(); //remove last element from stack
return false;
}
//use for testing
private void printPath() {
System.out.print("Path : " );
for(int[] cell : this) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
List<int[]> containedCells = getContainedWithin();
System.out.print(containedCells.size() +" cell contained : " );
for(int[] cell : containedCells) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
}
CellsList getPath() {
CellsList cl = new CellsList();
cl.addAll(this);
return cl;
}
}
The code below finds the neighbors of a cell (path.java):
//return a list of all neighbors of cell row, col
private CellsList getNeighbors(int row, int col) {
CellsList neighbors = new CellsList();
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {
for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {
if(!((colNum == col) && (rowNum == row))) {
if(isWithinGrid (rowNum, colNum ) ) {
neighbors.add( new int[] {rowNum, colNum});
}
}
}
}
return neighbors;
}
private boolean isWithinGrid(int colNum, int rowNum) {
if((colNum < 0) || (rowNum <0) ) {
return false;
}
if((colNum >= cols) || (rowNum >= rows)) {
return false;
}
return true;
}
}
The below code finds all bounded cell by a path (all contained or encircled tokens) and their token is of the opposite color of the path:
List<int[]> getContainedWithin() {
//find path max and min X values, max and min Y values
minPathRow = grid[0].length; //set min to the largest possible value
maxPathCol = grid.length;
maxPathRow = 0; //set max to the largest possible value
maxPathCol = 0;
//find the actual min max x y values of the path
for (int[] cell : this) {
minPathRow = Math.min(minPathRow, cell[0]);
minPathCol = Math.min(minPathCol, cell[1]);
maxPathRow = Math.max(maxPathRow, cell[0]);
maxPathCol = Math.max(maxPathCol, cell[1]);
}
List<int[]> block = new ArrayList<>(25);
int[] cell = get(0);//get an arbitrary cell in the path
Token pathToken = grid[cell[0]][cell[1]]; //keep a reference to its token
//iterate over all cells within path x, y limits
for (int col = minPathCol; col < (maxPathCol); col++) {
for (int row = minPathRow; row < (maxPathRow); row++) {
//check cell color
Token token = grid[row][col];
if ((token == pathToken) || (token == Token.VIDE)) {
continue;
}
if (isWithinLoop(row,col)) {
block.add(new int[] {row, col});
}
}
}
return block;
}
//check if row, col represent a cell within path by checking if it has a
//path-cell to its left, right, top and bottom
private boolean isWithinLoop(int row, int col) {
if( isPathCellOnLeft(row, col)
&&
isPathCellOnRight(row, col)
&&
isPathCellOnTop(row, col)
&&
isPathCellOnBottom(row, col)
) {
return true;
}
return false;
}
}
If you need more elements, just let me now, I'll update with the necessary.
This requirement means that previous paths, affect current path calculations. It can be achieved in many ways. The easiest, within current program structure could be adding a static collection of contained cells in all paths.
See allContainedWithin and the way it is used in the code.
Also note that I refactored getContainedWithin() to be a getter, and moved its functionality to a new method findContainedWithin().
All changes have no effect on other classes.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
//a stack representing cells in the path
//each cell represented by [row,col]
class Path extends Stack<int[]>{
private Token[][] grid;
//a path shorter than min can not surround any cell
private static final int MIN_PATH_LEGTH = 3;
//a collection of cells that has been tested
private ArrayList<int[]>checked;
//represents the cell where the search starts from
int[] origin;
//represents the token of the origin
Token originToken;
private int rows;
private int cols;
//represents the path bounds: min/max row/col in path
private int minPathRow, maxPathRow, minPathCol, maxPathCol;
//a collection of all cells that are bounded by the path
//and their token is of the opposite color of the path
private List<int[]> containedWithin;
//a STATIC collection that holds all containedWithin cells, of
//current and previous paths
private static CellsList allContainedWithin = new CellsList();
Path(Token[][] grid){
this.grid = grid;
rows = grid.length;
cols = grid[0].length;
}
//search for a path
boolean findPath(int[] origin) {
this.origin = origin;
int row = origin[0] , col = origin[1];
//represents the token of the origin
originToken = grid[row][col];
//initialize list of checked items
checked = new CellsList();
boolean found = findPath(row, col);
if(found) {
//find bounded cells
findContainedWithin();
//update the collection all
allContainedWithin.addAll(containedWithin);
printPath();
} else {
System.out.println("No path found");
}
return found;
}
//recursive method to find path. a cell is represented by its row, col
//returns true when path was found
private boolean findPath(int row, int col) {
//check if cell has the same token as origin
if(grid[row][col] != originToken) {
return false;
}
int[] cell = new int[] {row, col};
//check if this cell was tested before to avoid checking again
if(checked.contains(cell)) {
return false;
}
//check if this cell was contained in previously calculated paths
if(allContainedWithin.contains(cell)) {
return false;
}
//get cells neighbors
CellsList neighbors = getNeighbors(row, col);
//check if solution found. If path size > min and cell
//neighbors contain the origin it means that path was found
if((size() >= MIN_PATH_LEGTH) && neighbors.contains(origin) ) {
add(cell);
return true;
}
//add cell to checked
checked.add(cell);
//add cell to path
add(cell);
//if path was not found check cell neighbors
for(int[] neighbor : neighbors ) {
boolean found = findPath(neighbor[0],neighbor[1]);
if(found) {
return true;
}
}
//path not found
pop(); //remove last element from stack
return false;
}
//return a list of all neighbors of cell row, col
private CellsList getNeighbors(int row, int col) {
CellsList neighbors = new CellsList();
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {
for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {
if(!((colNum == col) && (rowNum == row))) {
if(isWithinGrid (rowNum, colNum ) ) {
neighbors.add( new int[] {rowNum, colNum});
}
}
}
}
return neighbors;
}
private boolean isWithinGrid(int colNum, int rowNum) {
if((colNum < 0) || (rowNum <0) ) {
return false;
}
if((colNum >= cols) || (rowNum >= rows)) {
return false;
}
return true;
}
//use for testing
private void printPath() {
System.out.print("Path : " );
for(int[] cell : this) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
List<int[]> containedCells = getContainedWithin();
System.out.print(containedCells.size()+" cell contained : " );
for(int[] cell : containedCells) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
}
CellsList getPath() {
CellsList cl = new CellsList();
cl.addAll(this);
return cl;
}
//finds all cells that are bounded by the path
//and their token is of the opposite color of the path
private void findContainedWithin() {
containedWithin = new ArrayList<>();
//find path max and min X values, max and min Y values
minPathRow = grid[0].length; //set min to the largest possible value
maxPathCol = grid.length;
maxPathRow = 0; //set max to the largest possible value
maxPathCol = 0;
//find the actual min max x y values of the path
for (int[] cell : this) {
minPathRow = Math.min(minPathRow, cell[0]);
minPathCol = Math.min(minPathCol, cell[1]);
maxPathRow = Math.max(maxPathRow, cell[0]);
maxPathCol = Math.max(maxPathCol, cell[1]);
}
//todo remove after testing
System.out.println("x range: "+minPathRow + "-"
+ maxPathRow + " y range: " + minPathCol + "-" + maxPathCol);
int[] cell = get(0);//get an arbitrary cell in the path
Token pathToken = grid[cell[0]][cell[1]]; //keep a reference to its token
//iterate over all cells within path x, y limits
for (int col = minPathCol; col < (maxPathCol); col++) {
for (int row = minPathRow; row < (maxPathRow); row++) {
//check cell color
Token token = grid[row][col];
if ((token == pathToken) || (token == Token.VIDE)) {
continue;
}
if (isWithinLoop(row,col)) {
containedWithin.add(new int[] {row, col});
}
}
}
}
//returns a collection of all cells that are bounded by the path
//and their token is of the opposite color of the path
List<int[]> getContainedWithin() {
return containedWithin;
}
//check if row, col represent a cell with in path by checking if it has a
//path-cell to its left, right, top and bottom
private boolean isWithinLoop(int row, int col) {
if( isPathCellOnLeft(row, col)
&&
isPathCellOnRight(row, col)
&&
isPathCellOnTop(row, col)
&&
isPathCellOnBottom(row, col)
) {
return true;
}
return false;
}
private boolean isPathCellOnLeft(int cellRow, int cellCol) {
for ( int col = minPathCol; col < cellCol ; col++) {
if(getPath().contains(new int[] {cellRow, col})) {
return true;
}
}
return false;
}
private boolean isPathCellOnRight(int cellRow, int cellCol) {
for ( int col = cellCol; col <= maxPathCol ; col++) {
if(getPath().contains(new int[] {cellRow, col})) {
return true;
}
}
return false;
}
private boolean isPathCellOnTop(int cellRow, int cellCol) {
for ( int row =minPathRow; row < cellRow ; row++) {
if(getPath().contains(new int[] {row, cellCol})) {
return true;
}
}
return false;
}
private boolean isPathCellOnBottom(int cellRow, int cellCol) {
for ( int row = cellRow; row <= maxPathRow; row++) {
if(getPath().contains(new int[] {row, cellCol})) {
return true;
}
}
return false;
}
}
Note that I only run some basic testing like :
In addition to the previous answer, I would like to add an alternative which requires a deeper change in the program.
A better way to handle the requirement would be to change the representation of a cell. Instead of using int[]{row, col} , consider representing it by a Cell class which has attributes like row, col,token, contained etc.
A simple implementation of Cell could be :
public class Cell {
private int row, col;
private Token token;
private boolean isContained;
Cell(int row, int col) {
this(row, col, Token.VIDE);
}
Cell(int row, int col, Token token) {
this.row = Math.abs(row); //to allow only positve addresses
this.col = Math.abs(col);
this.token = (token == null) ? Token.VIDE : token;
}
int getRow() {
return row;
}
int getCol() {
return col;
}
Token getToken() {
return token;
}
boolean isContained() {
return isContained;
}
void setRow(int row) {
this.row = row;
}
void setCol(int col) {
this.col = col;
}
void setToken(Token token) {
this.token = token;
}
void setContained(boolean isContained) {
this.isContained = isContained;
}
int[] getAddress() {
return new int[] {row, col};
}
#Override
public String toString() {
return Arrays.toString(getAddress()) +"-"+ token;
}
#Override
public boolean equals(Object cell) {
if ((cell == null) || !(cell instanceof Cell)) {
return false;
}
return Arrays.equals(getAddress(), ((Cell)cell).getAddress());
}
#Override
public int hashCode() {
return 31*row + 17*col;
}
}
Note: This representation should be changed all across the program.
(Not tested)
Here is the method, it ideally should solve the eight-queens problem by placing Qs on the board so that none of them threaten each other, but I can't seem to stop it from infinitely recursing.
public static void solve(int row, int col, int size, char[][] array) {
for (int i = 0; i < size - 2; i++) {
if (isSafe(row, col, size, array)) {
array[i][col] = 'Q';
} else {
if (col < size - 2) {
solve(row, col++, size, array); //changed ++ to +1
}
}
}
}
For clarity, here is the included 'isSafe' method:
public static boolean isSafe(int row, int col, int size, char[][] array) {
//check column
for (int i = 0; i < size - 1; i++) {
if (array[i][col] == 'Q') {
return false;
}
}
//horizontal
for (int i = size - 1; i >= 0; i--) {
if (array[row][i] == 'Q') {
return false;
}
}
//up diagonal
while (row > 0 && col > 0) {
int x = row;
int y = col;
if (array[row - 1][col - 1] == 'Q') {
return false;
} else {
x--;
y--;
}
}
//down diagonal
while (row < size - 1 && col > 0) {
int x = row;
int y = col;
if (array[row + 1][col - 1] == 'Q') {
return false;
} else {
x++;
y--;
}
}
return true;
}
Thank you for any light you can shed on this.
EDIT : So I just figured out that by changing '++' to '+1' I was able to stop the stack overflow, but my method does not recurse like I want it to so a question still remains
The problem is with solve(row, col++, size, array);
col will not be incremented until AFTER the call to solve.
You need to use solve(row, ++col, size, array);
i'm a bit stuck with the Sudoku algorithm, i coded it using backtrack, and following the theorical steps this should work, and i tried to debuge it, but is too hard (and yes, it solve some numbers and does things)
i paste the code, i hope that you can help me, i really can't see where the problem is...
public void backtracking(int row,int col){
if(row > 8){
System.out.println("Solution Found!!");
printSudoku();
}
if (m[row][col] != 0){
next(row, col);
}
else {
for(int i =1; i < n;i++)
if(row(row, i) && col(col, i)) {
m[row][col] =i;
next(row, col);
}
m[row][col] = 0;
}
}
public void next( int row, int col ) {
if( col < 8)
backtracking( row, col + 1 ) ;
else
backtracking( row+ 1, 0 ) ;
}
public boolean region(int x, int y, int numReg) {
x = (x / 3) * 3 ;
y = (y / 3) * 3 ;
for( int r = 0; r < 3; r++ )
for( int c = 0; c < 3; c++ )
if( m[x+r][y+c] == numReg )
return false ;
return true ;
}
public boolean row(int x, int k){
for(int i =0; i < 9; i++)
if(m[x][i] == k)
return false;
return true;
}
public boolean col(int x, int k){
for(int i =0; i < 9; i++)
if(m[i][x] == k)
return false;
return true;
}
I ommited the "printSudoku" method, is just a double for and you know.
The code seems almost right.
As far as i can see you just forgot to call the region method. And I can't see where the variable n is coming from.
Try it with this slightly modified backtracking method:
public static void backtracking(int row, int col) {
if (row > 8) {
System.out.println("Solution Found!!");
printSudoku();
System.exit(0); //exiting after solution is found
}
if (m[row][col] != 0) {
next(row, col);
} else {
for (int i = 1; i <= 9; i++) //replaced i < n with i<=9
if (row(row, i) && col(col, i) && region(row, col, i)) { //calling region method too
m[row][col] = i;
next(row, col);
}
m[row][col] = 0;
}
}
I'm trying to implement the N*N queen algorithm with a little twist to it. In this version the queen can also move like a Knight can in chess.
Checking for the diagonals and rows seems to be fine, however when I try to check for a queen in the "L" position away from my current position, I get a "arrayindexoutofboundexception".
I'm not entirely sure if my check_Knight move is right. I can't seem to locate the error causing the issue in my code.
public class QueenGame {
/**
* #param args
*/
static int solution =0;
static boolean check_Queen(int row, int col, int queens[])
{
for(int i =1; i<col; i++)
{
if (queens[col-i] == row ||
queens[col-i] == row-i ||
queens[col-i] == row+i)
{
//flag = false;
return false;
}
}
return true;
}
static boolean check_KnightMove(int row, int col, int queens[])
{
if(queens[col-2] == (row -1) || queens[col-2] == (row+1))
{
return false;
}
return true;
}
static void placement(int col, int queens[], int n){
//int solution =0;
for (int row = 1; row <= n; row++) {
queens[col] = row;
if((check_Queen(row,col,queens)) == true)
{
if((check_KnightMove(row,col,queens)) == true)
{
if(col == n)
{
solution++;
}
else
{
placement(col+1,queens,n);
}
}
}
}
queens[col] = 0;
}
public static void main(String[] args) {
int solution =0;
Scanner scanner=new Scanner(System.in);
//System.out.print("Please enter N");
int n =10;
//int n = scanner.nextInt();// TODO Auto-generated method stub
//System.out.print(n);
int queens[] = new int[n+1];
placement(1,queens,n);
System.out.println("nQueens: solution=" + solution);
}
}
If col is 0 or 1, then you will get an ArrayIndexOutOfBoundsException. Add a check before accessing the array.
if ((col >= 2) && (queens[col-2] == (row-1) || queens[col-2] == (row+1)))