Change project structure to a Maven Java project + Refactor (#2816)

This commit is contained in:
Aitor Fidalgo Sánchez
2021-11-12 07:59:36 +01:00
committed by GitHub
parent 8e533d2617
commit 9fb3364ccc
642 changed files with 26570 additions and 25488 deletions

View 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();
}
}
}

View 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;
}
}

View 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);
}
}