solving N Queens using recursion - java

below is my code and I don't know where I got wrong
It compiled well works well but, doesn't print the right result;;;
if N is 4 , the result should be
2 4 1 3
However, It printed
1 3 0 0
I guess there are something wrong in for-loop because when I do it with another value like 5 it also printed only two numbers
this is the result from N=5;
1 4 0 0 0
import java.util.Scanner;
public class NQueens{
public static int N ;
public static int [] cols;
public static void printcols(){
for(int i =1; i<=N; i++){
System.out.print(cols[i] + " ");
}
System.out.print("\n");
}
public static boolean promising(int level){
for(int i =1; i<level ; i++){
if(cols[i] == cols[level]){
return false;
}else if(level-i == Math.abs(cols[level]- cols[i]))
return false;
}
return true;
}
public static boolean queens(int level){
if(!promising(level)){
printcols();
return false;
}
else if(level == N){
printcols();
return true;
}
for(int i =1; i<N; i++){
cols[level+1] = i;
if(queens(level+1)){
return true;
}
}
return false;
}
public static void main(String []args){
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
cols = new int [N+1];
queens(0);
}
}

It does not just print 1 3 0 0, but prints every backtracking step, and at the end it doesn't find any solutions. The problem is that you are mixing 0-based and 1-based indices, and eventually made an error.
In the following line:
for(int i =1; i<N; i++){
you are iterating over only N-1 possibilities, leaving i == N out. So the fix is just to allow equality too:
for(int i =1; i<=N; i++){
With this modification the program works as intended.

Related

Rat in a maze problem using backtracking in java

I have written the java code but it is not giving any output.Could anyone help me with the solution.thank you.I have provided the input and the output.
Here is the code-
Input-
5 4
OXOO
OOOX
OOXO
XOOO
XXOO
Output-
1 0 0 0
1 1 0 0
0 1 0 0
0 1 1 1
0 0 0 1
import java.util.*;
public class ratMaze {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int M = sc.nextInt();
char[][] ch = new char[N][M];
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
ch[i][j]=sc.next().charAt(0);
}
}
int[][] visited = new int[N][M];
boolean res=ratmaze(ch,0,0,visited);
if(res)
print(visited,N,M);
else
System.out.print("-1");
}
private static boolean ratmaze(char[][]ch,int row,int col,int[][] visited)
{
if(row==ch.length-1 && col==ch[0].length-1)
return true;
if(row==ch.length || col==ch[0].length || ch[row][col]=='X' || visited[row][col]==1)
return false;
visited[row][col]=1;
//Right
ratmaze(ch,row,col+1,visited);
//Down
ratmaze(ch,row+1,col,visited);
visited[row][col]=0;
return true;
}
private static void print(int[][] visited,int row,int col)
{
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
System.out.print(visited[row][col]+" ");
}
System.out.println();
}
}
}
There are two issues with your code. First comes from the way you read input characters. Scanner.next() returns a whole token. In this context, a token is a "word" - something limited by whitespaces or start/end of a line. In your example input "OXOO" is one token. You need to modify your your reading in such a way that token is read in the outer loop and then access characters at specific positions. You could do something like this:
for (int i = 0; i < N; i++) {
String token = sc.next();
for (int j = 0; j < M; j++) {
ch[i][j] = token.charAt(j);
}
}
It "worked" the way you did it but required each character to be separated by whitespace.
After fixing that you will get an ArrayIndexOutOfBoundsException in print() method. You should use i and j while printing the array, not row and col.
This will result in some output. I'm not sure if it is the output you expected.

Solving a backtracking question of N Queens

I am currently trying to learn the topic of Backtracking in Java. It is really really confusing for me because I am stuck.
The problem is to find ways in which N Queens can be placed in NxN Chess board so that none of the Queens can attack each other. A queen can attack in the same row, same column and diagonally. My code goes like this:
import java.util.Scanner;
class Main {
public static void putZero(int[][] board,int n){
for(int i = 0;i<n;i++){
for(int j=0;j<n;j++){
board[i][j]=0;
}
}
}
public static void printBoard(int[][] board,int n){
for(int i = 0;i<n;i++){
for(int j=0;j<n;j++){
System.out.print(board[i][j]);
}
System.out.print("\n");
}
System.out.print("\n\n\n");
}
public static void SolveNQ(int n){
int[][] board = new int[n][n];
putZero(board,n);
if(SolveQUtil(board,0,n)==true){
printBoard(board,n);
}
}
public static boolean isSafe(int row, int col, int[][] board,int n){
int i,j;
for(i=0;i<col;i++){
if(board[row][i]==1)
return false;
}
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 SolveQUtil(int[][] board, int col, int n){
if(col>=n){
return true;
}
else
for(int i=0;i<n;i++){
if(isSafe(i,col,board,n)==true){
board[i][col]=1;
boolean a = SolveQUtil(board,col+1,n);
if(a==true)
return true;
else
board[i][col]=0;
}
}
return false;
}
public static void main(String[] args){
Scanner scan = new Scanner(`enter code here`System.in);
int n = scan.nextInt();;
SolveNQ(n);
}
}
It is producing the result I want, but I am not understanding how this works. In my method SolveQUtil(), the method is called again which is "recursive". When col = 0 is called, the Q1 is placed at [0,0] as there are no existing queens. But when col = 1 is called recursively, it searches for the suitable place and returns 'true'. Now, isn't the SolveNQ() supposed to print the solution every time true is returned? When does it return false? How is this working? I am a beginner and can anyone please explain this to me, step by step? Thank you in advance.
SolveNQ, which does the printing, is not called recursively; SolveQUtil, which SolveNQ calls, and which does not print anything, is recursive.

Checking divisibility of a range of numbers with no repetition of digits

I wrote the following program to count the numbers that are divisible by 12 but contain no repetition of digits. eg. the number 144 is not to be considered even though it is divisible by 12 as a repetition of digit 4 is present. The problem is that I get no output. I tried changing the range of for loop from 12...54321 to 12...1000 and even 12...24. I still get no output. I can't seem to find what the problem is. Can someone please tell me what is wrong with my code. Or just suggest me a better code/solution to the problem. Thanks...
class mod12
{
public static void main(String[] args)
{
int count=0;
for(int num=12;num<=54321;num+=12)
{
boolean repetition=false;
int digits[]=new int[10];
int length=0;
while (num!=0)
{
digits[length++]=num%10;
num=num/10;
}
for(int i=0; i<length; i++)
{
for(int j=0; j<length; j++)
{
if(i!=j)
{
if(digits[i]==digits[j])
{
repetition=true;
break;
}
}
}
}
if(repetition==false)
{count++;}
}
System.out.println("There are "+count+" numbers satisfying the condition");
}
}
In the while loop you decrease num, effectively moving the for loop backwards, so it never completes. Using a temporary variable instead would solve the problem:
public static void main(String[] args)
{
int count=0;
for(int num=12;num<=54321;num+=12)
{
boolean repetition=false;
int digits[]=new int[10];
int length=0;
int tempNum = num; // Here
while (tempNum !=0)
{
digits[length++]=tempNum %10;
tempNum =tempNum /10;
}
for(int i=0; i<length; i++)
{
for(int j=0; j<length; j++)
{
if(i!=j)
{
if(digits[i]==digits[j])
{
repetition=true;
break;
}
}
}
}
if(repetition==false)
{count++;}
}
System.out.println("There are "+count+" numbers satisfying the condition");
}
EDIT:
Regardless of the original question, note you can shorten your code considerably by using a Set to track the digits:
public static void main(String[] args) {
int count = 0;
NUMBERS:
for (int num = 12; num <= 54321; num += 12) {
Set<Integer> digits = new HashSet<>();
int tempNum = num;
while (tempNum != 0) {
int digit = tempNum % 10;
if (!digits.add(digit)) {
continue NUMBERS;
}
tempNum = tempNum / 10;
}
++count;
}
System.out.println("There are "+count+" numbers satisfying the condition");
}

Ascending order and Descending Java

Hi here's my problem i cant seem to print my outputs correctly i guess i'm having a logical error in my code, it doesn't print when i put an ascending number then a descending. i'm kind of new to programming too.
Code:
import java.util.Scanner;
public class tester {
public static void main(String[] args) {
int n, i, k, j;
int asc = 0,
Scanner x = new Scanner(System.in);
do {
System.out.print("How many numbers to process : ");
k = x.nextInt();
if(k<=1) {
System.out.println("Enter a number greater than 1");
}
} while(k<=1);
System.out.printf("Please enter %d numbers: ",k);
n = x.nextInt();
for(i=0; i<n-1; i++) {
j = x.nextInt();
if( j < n) {
asc++; // is this right?
} else {
asc--;
}
}
if (asc==k) {
System.out.print("Not Growing Up.");
}
if (asc!=k) {
System.out.print("Growing Up.");
}
}
}
Here are the outputs
Example outputs (what i'm trying to get)
How many numbers to process : 4
Please enter 4 numbers : 1 2 3 4
Growing up.
How many numbers to process : 4
Please enter 4 numbers : 4 3 2 1
Not Growing up.
This is my problem :
How many numbers to process : 4
Please enter 4 numbers : 1 2 1 3
Growing up. // it should be not growing up.
There is no need to iterate through all numbers. You can just check if the previous number is lower (if growing). If not, print and return. Check my example code.
Replace
n = x.nextInt();
for (i=0; i<n-1; i++) {
j = x.nextInt();
if( j < n) {
asc++; // is this right?
} else {
asc--;
}
}
if (asc==k) {
System.out.print("Not Growing Up.");
}
if (asc!=k) {
System.out.print("Growing Up.");
}
With
int prev = x.nextInt();
for (i=0; i<k-1; i++) {
j = x.nextInt();
if (j < prev) { System.out.print("Not Growing Up."); return; }
prev = j;
}
System.out.print("Growing Up.");
String numbers = "1 2 3 4"; // Let's take this input for example
int temp = 0; // This use to compare previous integer
boolean isAsc = false; // This store whether the digits is growing up or not
StringTokenizer st = new StringTokenizer(numbers); // Declare StringTokenizer
while (st.hasMoreTokens()) {
int next = Integer.parseInt(st.nextToken()); // Put the first integer in next (1)
if(next > temp){ // if (1) > 0
temp = next; // Assign 1 to temp, next time digit 2 will compare with digit 1
isAsc = true; // Assign the ascending to true
} else
isAsc = false;
}
if(isAsc)
System.out.print("Growing up.");
else
System.out.print("Not growing up.");
}
Your can store the user input as a string like the variable numbers I've declared and break them into each token for compare purpose.
import java.lang.reflect.Array;
import java.util.*;
public class A1 {
public static void main(String[] args) {
int a[]={2,5,0,1};
Arrays.sort(a);
int b= a.length;
for(int i=0;i<a.length;i++)
{
System.out.println(+a[i]+"\t"+a[b-1]);
b--;
}
}
}

Arraylist, incomparable types: DieClass and int

Trying to write a program that "rolls" dice and displays the results of the players and computer's rolls, as well as find how many of each number was rolled. Say, player rolls 3 4 3 5 6, then the player has a match composed of 2 3's. Haven't wrote the code to display the matching yet.
My problem is that I am trying to record the rolls to an ArrayList, then compare each number for the players and computers rolls from the ArrayList, and count up the number of each number's occurrence, but it I keep getting the error of
error: incomparable types: DieClass and int
Whenever I try to compare from the ArrayList
The program in question uses methods from the class DieClass
import java.util.ArrayList;
public class DieTester
{
private static ArrayList<DieClass> player = new ArrayList<DieClass>();
private static ArrayList<DieClass> computer = new ArrayList<DieClass>();
public static void main(String[] args)
{
for(int a = 1; a <= 5; a++)
{
DieClass roller = new DieClass();
player.add(roller);
}
for(int a = 1; a <= 5; a++)
{
DieClass roller = new DieClass();
computer.add(roller);
}
System.out.println("The user rolls: "+player);
System.out.println("The computer rolls: "+computer);
}
public String findMatching()
{
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
int count5 = 0;
for(int i=1; i<player.size(); i++)
{
if(player.get(i)==1)
{
count1++;
}
else if(player.get(i)==2)
{
count2++;
}
else if(player.get(i)==3)
{
count3++;
}
else if(player.get(i)==4)
{
count4++;
}
else if(player.get(i)==5)
{
count5++;
}
}
for(int i=1; i<player.size(); i++)
{
if(computer.get(i)==1)
{
count1++;
}
else if(computer.get(i)==2)
{
count2++;
}
else if(computer.get(i)==3)
{
count3++;
}
else if(computer.get(i)==4)
{
count4++;
}
else if(computer.get(i)==5)
{
count5++;
}
}
}
}
Your problem is that you are comparing DieClass with Integers
if(player.get(i)==1)
For the counters, why don't you use an array of int? like
int counters [] = new int[6];
counters[2]++;
Please post DieClass, however, I think that your code should be like this.
for (DieClass dieClass : player) {
counters[dieClass.getNumber()-1]++; //Supose that DieClass has a getNumber method and set minus one because counters goes from 0 to 5
}

Categories

Resources