public class SomeQueens {
static Stack<Integer> s= new Stack<Integer>();
static int Solved = 0;
static int current = 0;
public static int solve(int n) { // n is 8
while(current < n) { // should I use current < n instead
for (int i = current; i < n; i++) {
if(validPosition(i)) {
s.push(i);
current = 0;
}
}
if(!validPosition(current)) {
if(s.empty()) {
break;
}
if(!s.empty()) {
s.pop();
current++;
}
}
if(s.size() == n) {
s.pop();
current++;
printSolution(s);// this is a method, but it shouldn't matter for this
Solved++;
}
}
return Solved;
}
public static boolean validPosition(int column) {
for( int row = 0; row < s.size(); row++)
if(s.get(row) == column || ((column - s.get(row)) == (s.size() - row)) ||
((s.get(row) - column) == (s.size() - row)) )
return false; // there's a conflict
return true; // no conflict;
}
//it's called by int num = solve(n);
//sop("There're" + num + "sols to the" + n "queens prob");
This is a subsection of my program for NQueens, but I seem to always get: There are 0 solutions to the 8-queens problem. I tried debugging with system.out.prints in the main method, which led me to guess that there would be something wrong in my boolean method, but I don't think it's doing anything wrong.
I'm unsure if my while statement is incorrect or if the break inside the while loop is initialized before anything is even done. Thanks for the help and guidance and I'm sorry if my program and explanation makes no sense
Here is why you instantly get a zero:
s.push(0);
while(s.size() > n) // n is 8
{
//...
}
return Solved;
When the program arrives at the while-condition s has a size of one and n is 8. This will instantly fail and cause the method to return a zero.
But that's not the only problem with the algorithm. You should seriously rethink it.
Related
This code prints the first occurence of element 'k' in the array properly but the question I'm doing wants me to print -1 if the element 'k' is entirely not present in the array. I know its easy but I'm just stuck and its frustatiting any help?
n = sc.nextInt();
k = sc.nextInt();
int arr[] = new int[n];
for(int i=0;i<n;i++) {
arr[i] = sc.nextInt();
}
for(int i=0;i<n;i++) {
if(arr[i]==k) {
System.out.println(i);
break;
}
}
Use Arrays#binarySearch:
int firstIndexOf(int[] sortedArray, int x) {
int p = Arrays.binarySearch(sortedArray, x);
if (p < 0) {
return -1;
}
while (p > 0 && sortedArray[p - 1] == x) {
--p;
}
return p;
}
Binary search splits the searched range in half repetively looking in which half to continue. It returns either the found position or the complement (~p) of the insert position.
int findOccurenceOfElemet(int[] a, int k) {
if(a.length == 0) {
return -1;
}
for(int i = 0; i < a.length; i++) {
if(a[i] == k) {
return i;
}
}
//return -1 if element not found
return -1;
}
What you are asking in the title, and what you are asking in the post body, are two different questions; however, if we will follow your question's body, that has nothing to do with binary search, and introducing boolean flag would get you what you are asking for:
boolean notFound = true;
for(int i=0; i<n; i++) {
if(arr[i] == k) {
System.out.println(i);
notFound = false;
break;
}
}
if(notFound) System.out.println("-1");
Here is the following piece of code I wrote to compute the equilibrium index of a given array.
public class Equilibrium{
private int lowerSum =0;
public int equilibrium(int[] A) {
for(int i=0; i<A.length;i++)
{
if(lowerSum(A, i) == upperSum(A,i))
{
return i;
}
}
return -1;
}
private int lowerSum(int[] ar, int index)
{
if(index == 0)
return 0;
lowerSum += ar[--index];
return lowerSum;
}
//This can be fixed accordingly in a similar way lowerSum
//was implemented to have a time complexity of O(n) but
//this is not relevant to the problem here
private int upperSum(int[] ar, int index)
{
int sum=0;
for(int i= index+1; i<ar.length; i++)
{
sum+=ar[i];
}
return sum;
}
}
The above code does not produce the right results. For example for the following tests:
assertEquals(1, solution.solution(new int[]{1,2,1}));
assertEquals(3, solution.solution(new int[]{3,5,8,9,5,3,8}));
The first passes but the second does not. This is because the calculation of the
lowerSum field is by +1 wrong.
However making the following changes to the code produces the right result:
private int lowerSum =0;
public int solution(int[] A) {
for(int i=0; i<A.length;i++)
{
lowerSum(A, i);
if( lowerSum== upperSum(A,i))
{
return i;
}
}
return -1;
}
private void lowerSum(int[] ar, int index)
{
if(index == 0)
lowerSum = 0;
else
lowerSum += ar[--index];
}
Can someone please explain to me why this is happening?
In your first implementation you simply return 0. In your second implementation you set lowerSum to 0 before returning lowerSum.
Fixed:
private int lowerSum(int[] ar, int index)
{
if(index == 0) {
lowerSum = 0;
} else {
lowerSum += ar[--index];
}
return lowerSum;
}
I am trying to write a sudoku solver with backtracking right now and I solved some problems already but I don't know what to do now.
This is the Problem:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at ISudoku.NumberOnBoard(ISudoku.java:19)
at ISudokuSolver.containedinRoC(ISudokuSolver.java:23)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:10)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19)
at BacktrackingISudokuSolver.solveSudoku(BacktrackingISudokuSolver.java:4)
at Examples.main(Examples.java:17)
When I run the code
I don't expect to get the right code handed to me, i just appreciate every help.
public class ISudoku {
private boolean[][] sudokuboolean;
private int[][] sudokuboard;
private int size;
public ISudoku(int size){
this.size = size;
sudokuboard = new int[size][size];
sudokuboolean = new boolean[size][size];
}
public void setNumber(int i, int j, int number, boolean given){
sudokuboard[i][j] = number;
sudokuboolean[i][j] = given;
}
public int NumberOnBoard(int i, int j){
return sudokuboard[i][j];
}
public int getSize(){
return size;
}
public String toString(){
String string = "";
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
if(sudokuboolean[i][j]){
string += "<" + sudokuboard[i][j] + "> ";
}
else{
string += sudokuboard[i][j] + " ";
}
if(j == 2 || j == 5){
string += " ";
}
}
string += "\n";
if(i == 2 || i == 5){
string += "\n";
}
}
return string;
}
}
public abstract class ISudokuSolver {
public abstract boolean solveSudoku(ISudoku sudoku);
public boolean containedin3x3(ISudoku sudoku,int row, int col, int value){
int firstRow = row / 3 * 3;
int firstCol = col / 3 * 3;
for(int i = firstRow; i < firstRow+3; i++){
for(int j = firstCol; j < firstCol+3; j++){
if(!(i == row && j == col)){
if(sudoku.NumberOnBoard(i,j) == value){
return true;
}
}
}
}
return false;
}
public boolean containedinRoC(ISudoku sudoku,int row, int col, int value){
for(int i = 0; i < 9;i++){
if(i != col){
if(sudoku.NumberOnBoard(row,i) == value){
return true;
}
}
if(i != row){
if(sudoku.NumberOnBoard(i,col) == value){
return true;
}
}
}
return false;
}
}
public class BacktrackingISudokuSolver extends ISudokuSolver{
public boolean solveSudoku(ISudoku sudoku){
backtracking(0,1,sudoku);
return true;
}
private boolean backtracking(int row,int number, ISudoku sudoku){
for(int i = 0; i < sudoku.getSize();i++){
if(!containedinRoC(sudoku,row,i,number) && !containedin3x3(sudoku,row,i,number)){
sudoku.setNumber(row,i,number,false);
if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number != 9){
number += 1;
}
if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number == 9){
return true;
}
else{
if(backtracking(row+1,number,sudoku)){
return true;
}
else{
sudoku.setNumber(row,i,0,false);
}
}
}
}
return false;
}
}
public class Examples extends BacktrackingISudokuSolver {
public static void main(String[] args) {
ISudokuSolver solver = new BacktrackingISudokuSolver();
ISudoku sudoku = new ISudoku(9);
System.out.println(sudoku);
System.out.println("Beispiel 1: ");
System.out.println("Lösbar? (Erwartet): Ja");
System.out.println("Benötigte Zeit? (Erwartet): 15 ms (Intel i5 3,8 Ghz)");
long start = System.currentTimeMillis();
boolean solvable = solver.solveSudoku(sudoku);
long end = System.currentTimeMillis();
System.out.println("Lösbar?: " + solvable);
System.out.println("Benötigte Zeit: " + (end - start) + " ms");
System.out.println(sudoku);
}
}
Without a line number in the exception, I'm going to blame the i in the second loop conditional in containedin3x3. The body never changes i, so j gets incremented until it goes out of bounds.
for(int i = firstRow; i < firstRow+3; i++){
for(int j = firstCol; i < firstCol+3; j++){
The stack trace in the image you linked appears to implicate this line:
return sudokuboard[i][j];
The error message indicates that the value of the out-of-bounds index is 9.
Supposing that you are solving a 9x9 sudoku, variable sudokuboard will have dimensions 9, 9. In Java, array indices start at 0, so the valid range for both indexes of that array is 0 to 8.
It would take rather more analysis on my part to work out why that method is called with incorrect arguments, as it is; that job would better be handled via a debugger.
Update:
seems to be the problem but i dont know how to change it
Generally speaking, "knowing how to change it" depends on determining just where and how things go pear-shaped. That is one of the things a debugger is useful for, as I already suggested. You really should learn how to use one.
The rest of the stack trace can be useful for that purpose as well. In this case, it implicates this method invocation on line 10 of BacktrackingISudokuSolver.backtracking():
containedinRoC(sudoku,row,i,number)
It doesn't take much study of the code to conclude that the only argument that could be out of bounds is row, whose value was itself an argument to a recursive call to backtracking() at line 19 (referring again to the stack trace). Consider, then, that line and the ones around it:
09 for(int i = 0; i < sudoku.getSize();i++){
10 if(!containedinRoC(sudoku,row,i,number) && !containedin3x3(sudoku,row,i,number)){
11 sudoku.setNumber(row,i,number,false);
12 if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number != 9){
13 number += 1;
14 }
15 if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number == 9){
16 return true;
17 }
18 else{
19 if(backtracking(row+1,number,sudoku)){
20 return true;
21 }
22 else{
23 sudoku.setNumber(row,i,0,false);
24 }
25 }
26 }
27 }
Looking at that code, and at line 19 in particular, do you see any way that this method could have been called with valid arguments, yet perform a recursive call with invalid arguments? That's what you need to fix.
The compiler says I'm not returning an integer. The getC method returns an integer. How can I fix this?
public static int calcCost(Guard[] g, int spot){
if(spot >= 31078657) return 0;
else {
for(int i = 51499; i >= 0; i--){
if(g[i].getS() == spot && g[i].getF() <= 31078657) {
return (g[i].getC() + calcCost(g, g[i].getF() + 1));
}
}
}
}
This problem arises when your method doesn't return a result by following all the paths. In this case, if the if inside the for loop never gets executed, you aren't returning anything.
Just add a default return statement at the bottom of your method:
public static int calcCost(Guard[] g, int spot){
if(spot >= 31078657) return 0;
else {
for(int i = 51499; i >= 0; i--){
if(g[i].getS() == spot && g[i].getF() <= 31078657) {
return (g[i].getC() + calcCost(g, g[i].getF() + 1));
}
}
}
//here
return 0; //or another desired default value
}
You're not returning an integer in every case. If the inner condition is never met, control will flow to the end of the method without anything being returned.
You need to add a 'return' for the case when your 'for' loop terminates - i.e. with i==0. Not knowing what this code is doing, it's entirely possible that you are certain the the inner return must occur for some value of i, but neither I nor your compiler can determine that this is the case, merely by looking at this code fragment. Modern compilers are pretty smart, but not that smart ;-)
Simply add default value in the end
public static int calcCost(Guard[] g, int spot){
if(spot >= 31078657) return 0;
else {
for(int i = 51499; i >= 0; i--){
if(g[i].getS() == spot && g[i].getF() <= 31078657) {
return (g[i].getC() + calcCost(g, g[i].getF() + 1));
}
}
}
return -1;// add default value here
}
OR you can throw an Exception such as IllegalArgumentException in case of invalid value.
public static int calcCost(Guard[] g, int spot){
if(spot >= 31078657) return 0;
else {
for(int i = 51499; i >= 0; i--){
if(g[i].getS() == spot && g[i].getF() <= 31078657) {
return (g[i].getC() + calcCost(g, g[i].getF() + 1));
}
}
}
throw new IllegalArgumentException();
}
I think this can be solved with setting traps/breakpoints - but I'm not quite sure on how to do that. This method is supposed to sort an array of objects (each object contains an int, which is a year), but I get nothing on the terminal, and a busy VM signal... What's going on?
public static movie2[] sortYear(movie2[] sort, int parameter)
{
int[] dest = new int[sort.length];
if(parameter == 1)
{
for(int i = 0; i < sort.length-1; i++)
{
int next = sort[i].getYear();
int insertIndex = 0;
int k = i; //Why do I need this?
while( k > 0 && insertIndex == 0)
{
if(next > dest[k-1])
{
insertIndex = k;
}
else
{
dest[insertIndex] = next;
}
}
sort[i].setYear(dest[i]);
}