mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-21 19:14:55 +08:00
Change project structure to a Maven Java project + Refactor (#2816)
This commit is contained in:

committed by
GitHub

parent
8e533d2617
commit
9fb3364ccc
140
src/main/java/com/thealgorithms/backtracking/KnightsTour.java
Normal file
140
src/main/java/com/thealgorithms/backtracking/KnightsTour.java
Normal file
@ -0,0 +1,140 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
* Problem Statement: -
|
||||
|
||||
Given a N*N board with the Knight placed on the first block of an empty board. Moving according to the rules of
|
||||
chess knight must visit each square exactly once. Print the order of each cell in which they are visited.
|
||||
|
||||
Example: -
|
||||
|
||||
Input : N = 8
|
||||
|
||||
Output:
|
||||
0 59 38 33 30 17 8 63
|
||||
37 34 31 60 9 62 29 16
|
||||
58 1 36 39 32 27 18 7
|
||||
35 48 41 26 61 10 15 28
|
||||
42 57 2 49 40 23 6 19
|
||||
47 50 45 54 25 20 11 14
|
||||
56 43 52 3 22 13 24 5
|
||||
51 46 55 44 53 4 21 12
|
||||
|
||||
*/
|
||||
public class KnightsTour {
|
||||
|
||||
private final static int base = 12;
|
||||
private final static int[][] moves = {{1, -2}, {2, -1}, {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}}; // Possible moves by knight on chess
|
||||
private static int[][] grid; // chess grid
|
||||
private static int total; // total squares in chess
|
||||
|
||||
public static void main(String[] args) {
|
||||
grid = new int[base][base];
|
||||
total = (base - 4) * (base - 4);
|
||||
|
||||
for (int r = 0; r < base; r++) {
|
||||
for (int c = 0; c < base; c++) {
|
||||
if (r < 2 || r > base - 3 || c < 2 || c > base - 3) {
|
||||
grid[r][c] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int row = 2 + (int) (Math.random() * (base - 4));
|
||||
int col = 2 + (int) (Math.random() * (base - 4));
|
||||
|
||||
grid[row][col] = 1;
|
||||
|
||||
if (solve(row, col, 2)) {
|
||||
printResult();
|
||||
} else {
|
||||
System.out.println("no result");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return True when solvable
|
||||
private static boolean solve(int row, int column, int count) {
|
||||
if (count > total) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<int[]> neighbor = neighbors(row, column);
|
||||
|
||||
if (neighbor.isEmpty() && count != total) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Collections.sort(neighbor, new Comparator<int[]>() {
|
||||
public int compare(int[] a, int[] b) {
|
||||
return a[2] - b[2];
|
||||
}
|
||||
});
|
||||
|
||||
for (int[] nb : neighbor) {
|
||||
row = nb[0];
|
||||
column = nb[1];
|
||||
grid[row][column] = count;
|
||||
if (!orphanDetected(count, row, column) && solve(row, column, count + 1)) {
|
||||
return true;
|
||||
}
|
||||
grid[row][column] = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns List of neighbours
|
||||
private static List<int[]> neighbors(int row, int column) {
|
||||
List<int[]> neighbour = new ArrayList<>();
|
||||
|
||||
for (int[] m : moves) {
|
||||
int x = m[0];
|
||||
int y = m[1];
|
||||
if (grid[row + y][column + x] == 0) {
|
||||
int num = countNeighbors(row + y, column + x);
|
||||
neighbour.add(new int[]{row + y, column + x, num});
|
||||
}
|
||||
}
|
||||
return neighbour;
|
||||
}
|
||||
|
||||
// Returns the total count of neighbors
|
||||
private static int countNeighbors(int row, int column) {
|
||||
int num = 0;
|
||||
for (int[] m : moves) {
|
||||
if (grid[row + m[1]][column + m[0]] == 0) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
// Returns true if it is orphan
|
||||
private static boolean orphanDetected(int count, int row, int column) {
|
||||
if (count < total - 1) {
|
||||
List<int[]> neighbor = neighbors(row, column);
|
||||
for (int[] nb : neighbor) {
|
||||
if (countNeighbors(nb[0], nb[1]) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prints the result grid
|
||||
private static void printResult() {
|
||||
for (int[] row : grid) {
|
||||
for (int i : row) {
|
||||
if (i == -1) {
|
||||
continue;
|
||||
}
|
||||
System.out.printf("%2d ", i);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
111
src/main/java/com/thealgorithms/backtracking/NQueens.java
Normal file
111
src/main/java/com/thealgorithms/backtracking/NQueens.java
Normal file
@ -0,0 +1,111 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Problem statement: Given a N x N chess board. Return all arrangements in
|
||||
* which N queens can be placed on the board such no two queens attack each
|
||||
* other. Ex. N = 6 Solution= There are 4 possible ways Arrangement: 1 ".Q....",
|
||||
* "...Q..", ".....Q", "Q.....", "..Q...", "....Q."
|
||||
* <p>
|
||||
* Arrangement: 2 "..Q...", ".....Q", ".Q....", "....Q.", "Q.....", "...Q.."
|
||||
* <p>
|
||||
* Arrangement: 3 "...Q..", "Q.....", "....Q.", ".Q....", ".....Q", "..Q..."
|
||||
* <p>
|
||||
* Arrangement: 4 "....Q.", "..Q...", "Q.....", ".....Q", "...Q..", ".Q...."
|
||||
*
|
||||
* Solution: Brute Force approach:
|
||||
*
|
||||
* Generate all possible arrangement to place N queens on N*N board. Check each
|
||||
* board if queens are placed safely. If it is safe, include arrangement in
|
||||
* solution set. Otherwise ignore it
|
||||
*
|
||||
* Optimized solution: This can be solved using backtracking in below steps
|
||||
*
|
||||
* Start with first column and place queen on first row Try placing queen in a
|
||||
* row on second column If placing second queen in second column attacks any of
|
||||
* the previous queens, change the row in second column otherwise move to next
|
||||
* column and try to place next queen In case if there is no rows where a queen
|
||||
* can be placed such that it doesn't attack previous queens, then go back to
|
||||
* previous column and change row of previous queen. Keep doing this until last
|
||||
* queen is not placed safely. If there is no such way then return an empty list
|
||||
* as solution
|
||||
*/
|
||||
public class NQueens {
|
||||
|
||||
public static void main(String[] args) {
|
||||
placeQueens(1);
|
||||
placeQueens(2);
|
||||
placeQueens(3);
|
||||
placeQueens(4);
|
||||
placeQueens(5);
|
||||
placeQueens(6);
|
||||
}
|
||||
|
||||
public static void placeQueens(final int queens) {
|
||||
List<List<String>> arrangements = new ArrayList<List<String>>();
|
||||
getSolution(queens, arrangements, new int[queens], 0);
|
||||
if (arrangements.isEmpty()) {
|
||||
System.out.println("There is no way to place " + queens + " queens on board of size " + queens + "x" + queens);
|
||||
} else {
|
||||
System.out.println("Arrangement for placing " + queens + " queens");
|
||||
}
|
||||
arrangements.forEach(arrangement -> {
|
||||
arrangement.forEach(row -> System.out.println(row));
|
||||
System.out.println();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is backtracking function which tries to place queen recursively
|
||||
*
|
||||
* @param boardSize: size of chess board
|
||||
* @param solutions: this holds all possible arrangements
|
||||
* @param columns: columns[i] = rowId where queen is placed in ith column.
|
||||
* @param columnIndex: This is the column in which queen is being placed
|
||||
*/
|
||||
private static void getSolution(int boardSize, List<List<String>> solutions, int[] columns, int columnIndex) {
|
||||
if (columnIndex == boardSize) {
|
||||
// this means that all queens have been placed
|
||||
List<String> sol = new ArrayList<String>();
|
||||
for (int i = 0; i < boardSize; i++) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int j = 0; j < boardSize; j++) {
|
||||
sb.append(j == columns[i] ? "Q" : ".");
|
||||
}
|
||||
sol.add(sb.toString());
|
||||
}
|
||||
solutions.add(sol);
|
||||
return;
|
||||
}
|
||||
|
||||
// This loop tries to place queen in a row one by one
|
||||
for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) {
|
||||
columns[columnIndex] = rowIndex;
|
||||
if (isPlacedCorrectly(columns, rowIndex, columnIndex)) {
|
||||
// If queen is placed successfully at rowIndex in column=columnIndex then try placing queen in next column
|
||||
getSolution(boardSize, solutions, columns, columnIndex + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if queen can be placed at row = rowIndex in column =
|
||||
* columnIndex safely
|
||||
*
|
||||
* @param columns: columns[i] = rowId where queen is placed in ith column.
|
||||
* @param rowIndex: row in which queen has to be placed
|
||||
* @param columnIndex: column in which queen is being placed
|
||||
* @return true: if queen can be placed safely false: otherwise
|
||||
*/
|
||||
private static boolean isPlacedCorrectly(int[] columns, int rowIndex, int columnIndex) {
|
||||
for (int i = 0; i < columnIndex; i++) {
|
||||
int diff = Math.abs(columns[i] - rowIndex);
|
||||
if (diff == 0 || columnIndex - i == diff) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
55
src/main/java/com/thealgorithms/backtracking/PowerSum.java
Normal file
55
src/main/java/com/thealgorithms/backtracking/PowerSum.java
Normal file
@ -0,0 +1,55 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/*
|
||||
* Problem Statement :
|
||||
* Find the number of ways that a given integer, N , can be expressed as the sum of the Xth powers of unique, natural numbers.
|
||||
* For example, if N=100 and X=3, we have to find all combinations of unique cubes adding up to 100. The only solution is 1^3+2^3+3^3+4^3.
|
||||
* Therefore output will be 1.
|
||||
*/
|
||||
public class PowerSum {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
System.out.println("Enter the number and the power");
|
||||
int N = sc.nextInt();
|
||||
int X = sc.nextInt();
|
||||
PowerSum ps = new PowerSum();
|
||||
int count = ps.powSum(N, X);
|
||||
//printing the answer.
|
||||
System.out.println("Number of combinations of different natural number's raised to " + X + " having sum " + N + " are : ");
|
||||
System.out.println(count);
|
||||
sc.close();
|
||||
}
|
||||
private int count = 0, sum = 0;
|
||||
|
||||
public int powSum(int N, int X) {
|
||||
Sum(N, X, 1);
|
||||
return count;
|
||||
}
|
||||
|
||||
//here i is the natural number which will be raised by X and added in sum.
|
||||
public void Sum(int N, int X, int i) {
|
||||
//if sum is equal to N that is one of our answer and count is increased.
|
||||
if (sum == N) {
|
||||
count++;
|
||||
return;
|
||||
} //we will be adding next natural number raised to X only if on adding it in sum the result is less than N.
|
||||
else if (sum + power(i, X) <= N) {
|
||||
sum += power(i, X);
|
||||
Sum(N, X, i + 1);
|
||||
//backtracking and removing the number added last since no possible combination is there with it.
|
||||
sum -= power(i, X);
|
||||
}
|
||||
if (power(i, X) < N) {
|
||||
//calling the sum function with next natural number after backtracking if when it is raised to X is still less than X.
|
||||
Sum(N, X, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//creating a separate power function so that it can be used again and again when required.
|
||||
private int power(int a, int b) {
|
||||
return (int) Math.pow(a, b);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user