Skip to content

Commit 5ea37e1

Browse files
authored
Merge branch 'master' into baconian-cipher
2 parents 4c3ba7c + c56d282 commit 5ea37e1

File tree

277 files changed

+13584
-1401
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

277 files changed

+13584
-1401
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
uses: actions/setup-java@v4
1111
with:
1212
java-version: 21
13-
distribution: 'adopt'
13+
distribution: 'temurin'
1414
- name: Build with Maven
1515
run: mvn --batch-mode --update-snapshots verify
1616
- name: Upload coverage to codecov (tokenless)

.github/workflows/codeql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
uses: actions/setup-java@v4
3131
with:
3232
java-version: 21
33-
distribution: 'adopt'
33+
distribution: 'temurin'
3434

3535
- name: Initialize CodeQL
3636
uses: github/codeql-action/init@v3

.github/workflows/infer.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
uses: actions/setup-java@v4
1919
with:
2020
java-version: 21
21-
distribution: 'adopt'
21+
distribution: 'temurin'
2222

2323
- name: Set up OCaml
2424
uses: ocaml/setup-ocaml@v3

DIRECTORY.md

Lines changed: 178 additions & 2 deletions
Large diffs are not rendered by default.

checkstyle.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@
183183
<!-- See https://checkstyle.org/checks/misc/index.html -->
184184
<module name="ArrayTypeStyle"/>
185185
<!-- TODO <module name="FinalParameters"/> -->
186-
<!-- TODO <module name="TodoComment"/> -->
186+
<module name="TodoComment"/>
187187
<module name="UpperEll"/>
188188

189189
<!-- https://checkstyle.org/filters/suppressionxpathfilter.html -->

pom.xml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<dependency>
2121
<groupId>org.junit</groupId>
2222
<artifactId>junit-bom</artifactId>
23-
<version>5.11.2</version>
23+
<version>5.11.3</version>
2424
<type>pom</type>
2525
<scope>import</scope>
2626
</dependency>
@@ -31,7 +31,7 @@
3131
<dependency>
3232
<groupId>org.junit.jupiter</groupId>
3333
<artifactId>junit-jupiter</artifactId>
34-
<version>5.11.2</version>
34+
<version>5.11.3</version>
3535
<scope>test</scope>
3636
</dependency>
3737
<dependency>
@@ -40,11 +40,18 @@
4040
<version>${assertj.version}</version>
4141
<scope>test</scope>
4242
</dependency>
43+
<dependency>
44+
<groupId>org.mockito</groupId>
45+
<artifactId>mockito-core</artifactId>
46+
<version>5.14.2</version>
47+
<scope>test</scope>
48+
</dependency>
49+
4350

4451
<dependency>
4552
<groupId>org.junit.jupiter</groupId>
4653
<artifactId>junit-jupiter-api</artifactId>
47-
<version>5.11.2</version>
54+
<version>5.11.3</version>
4855
<scope>test</scope>
4956
</dependency>
5057
<dependency>
@@ -63,7 +70,7 @@
6370
<plugins>
6471
<plugin>
6572
<artifactId>maven-surefire-plugin</artifactId>
66-
<version>3.5.0</version>
73+
<version>3.5.1</version>
6774
<configuration>
6875
<forkNode implementation="org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory"/>
6976
</configuration>
@@ -125,7 +132,7 @@
125132
<plugin>
126133
<groupId>com.github.spotbugs</groupId>
127134
<artifactId>spotbugs-maven-plugin</artifactId>
128-
<version>4.8.6.4</version>
135+
<version>4.8.6.5</version>
129136
<configuration>
130137
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
131138
<includeTests>true</includeTests>

spotbugs-exclude.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@
8787
<Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" />
8888
</Match>
8989
<!-- fb-contrib -->
90-
<Match>
91-
<Bug pattern="OCP_OVERLY_CONCRETE_PARAMETER" />
92-
</Match>
9390
<Match>
9491
<Bug pattern="LSC_LITERAL_STRING_COMPARISON" />
9592
</Match>

src/main/java/com/thealgorithms/backtracking/ArrayCombination.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,44 @@
44
import java.util.List;
55

66
/**
7-
* Finds all combinations of 0...n-1 of length k
7+
* This class provides methods to find all combinations of integers from 0 to n-1
8+
* of a specified length k using backtracking.
89
*/
910
public final class ArrayCombination {
1011
private ArrayCombination() {
1112
}
1213

1314
/**
14-
* Finds all combinations of length k of 0..n-1 using backtracking.
15+
* Generates all possible combinations of length k from the integers 0 to n-1.
1516
*
16-
* @param n Number of the elements.
17-
* @param k Length of the combination.
18-
* @return A list of all combinations of length k.
17+
* @param n The total number of elements (0 to n-1).
18+
* @param k The desired length of each combination.
19+
* @return A list containing all combinations of length k.
20+
* @throws IllegalArgumentException if n or k are negative, or if k is greater than n.
1921
*/
2022
public static List<List<Integer>> combination(int n, int k) {
2123
if (n < 0 || k < 0 || k > n) {
22-
throw new IllegalArgumentException("Wrong input.");
24+
throw new IllegalArgumentException("Invalid input: n must be non-negative, k must be non-negative and less than or equal to n.");
2325
}
2426

2527
List<List<Integer>> combinations = new ArrayList<>();
2628
combine(combinations, new ArrayList<>(), 0, n, k);
2729
return combinations;
2830
}
2931

32+
/**
33+
* A helper method that uses backtracking to find combinations.
34+
*
35+
* @param combinations The list to store all valid combinations found.
36+
* @param current The current combination being built.
37+
* @param start The starting index for the current recursion.
38+
* @param n The total number of elements (0 to n-1).
39+
* @param k The desired length of each combination.
40+
*/
3041
private static void combine(List<List<Integer>> combinations, List<Integer> current, int start, int n, int k) {
31-
if (current.size() == k) { // Base case: combination found
32-
combinations.add(new ArrayList<>(current)); // Copy to avoid modification
42+
// Base case: combination found
43+
if (current.size() == k) {
44+
combinations.add(new ArrayList<>(current));
3345
return;
3446
}
3547

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package com.thealgorithms.backtracking;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.List;
6+
7+
/**
8+
* A class to solve a crossword puzzle using backtracking.
9+
* Example:
10+
* Input:
11+
* puzzle = {
12+
* {' ', ' ', ' '},
13+
* {' ', ' ', ' '},
14+
* {' ', ' ', ' '}
15+
* }
16+
* words = List.of("cat", "dog")
17+
*
18+
* Output:
19+
* {
20+
* {'c', 'a', 't'},
21+
* {' ', ' ', ' '},
22+
* {'d', 'o', 'g'}
23+
* }
24+
*/
25+
public final class CrosswordSolver {
26+
private CrosswordSolver() {
27+
}
28+
29+
/**
30+
* Checks if a word can be placed at the specified position in the crossword.
31+
*
32+
* @param puzzle The crossword puzzle represented as a 2D char array.
33+
* @param word The word to be placed.
34+
* @param row The row index where the word might be placed.
35+
* @param col The column index where the word might be placed.
36+
* @param vertical If true, the word is placed vertically; otherwise, horizontally.
37+
* @return true if the word can be placed, false otherwise.
38+
*/
39+
public static boolean isValid(char[][] puzzle, String word, int row, int col, boolean vertical) {
40+
for (int i = 0; i < word.length(); i++) {
41+
if (vertical) {
42+
if (row + i >= puzzle.length || puzzle[row + i][col] != ' ') {
43+
return false;
44+
}
45+
} else {
46+
if (col + i >= puzzle[0].length || puzzle[row][col + i] != ' ') {
47+
return false;
48+
}
49+
}
50+
}
51+
return true;
52+
}
53+
54+
/**
55+
* Places a word at the specified position in the crossword.
56+
*
57+
* @param puzzle The crossword puzzle represented as a 2D char array.
58+
* @param word The word to be placed.
59+
* @param row The row index where the word will be placed.
60+
* @param col The column index where the word will be placed.
61+
* @param vertical If true, the word is placed vertically; otherwise, horizontally.
62+
*/
63+
public static void placeWord(char[][] puzzle, String word, int row, int col, boolean vertical) {
64+
for (int i = 0; i < word.length(); i++) {
65+
if (vertical) {
66+
puzzle[row + i][col] = word.charAt(i);
67+
} else {
68+
puzzle[row][col + i] = word.charAt(i);
69+
}
70+
}
71+
}
72+
73+
/**
74+
* Removes a word from the specified position in the crossword.
75+
*
76+
* @param puzzle The crossword puzzle represented as a 2D char array.
77+
* @param word The word to be removed.
78+
* @param row The row index where the word is placed.
79+
* @param col The column index where the word is placed.
80+
* @param vertical If true, the word was placed vertically; otherwise, horizontally.
81+
*/
82+
public static void removeWord(char[][] puzzle, String word, int row, int col, boolean vertical) {
83+
for (int i = 0; i < word.length(); i++) {
84+
if (vertical) {
85+
puzzle[row + i][col] = ' ';
86+
} else {
87+
puzzle[row][col + i] = ' ';
88+
}
89+
}
90+
}
91+
92+
/**
93+
* Solves the crossword puzzle using backtracking.
94+
*
95+
* @param puzzle The crossword puzzle represented as a 2D char array.
96+
* @param words The list of words to be placed.
97+
* @return true if the crossword is solved, false otherwise.
98+
*/
99+
public static boolean solveCrossword(char[][] puzzle, Collection<String> words) {
100+
// Create a mutable copy of the words list
101+
List<String> remainingWords = new ArrayList<>(words);
102+
103+
for (int row = 0; row < puzzle.length; row++) {
104+
for (int col = 0; col < puzzle[0].length; col++) {
105+
if (puzzle[row][col] == ' ') {
106+
for (String word : new ArrayList<>(remainingWords)) {
107+
for (boolean vertical : new boolean[] {true, false}) {
108+
if (isValid(puzzle, word, row, col, vertical)) {
109+
placeWord(puzzle, word, row, col, vertical);
110+
remainingWords.remove(word);
111+
if (solveCrossword(puzzle, remainingWords)) {
112+
return true;
113+
}
114+
remainingWords.add(word);
115+
removeWord(puzzle, word, row, col, vertical);
116+
}
117+
}
118+
}
119+
return false;
120+
}
121+
}
122+
}
123+
return true;
124+
}
125+
}
Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,51 @@
11
package com.thealgorithms.backtracking;
22

3-
/*
4-
* Problem Statement :
5-
* Find the number of ways that a given integer, N , can be expressed as the sum of the Xth powers
6-
* of unique, natural numbers. For example, if N=100 and X=3, we have to find all combinations of
7-
* unique cubes adding up to 100. The only solution is 1^3+2^3+3^3+4^3. Therefore output will be 1.
3+
/**
4+
* Problem Statement:
5+
* Find the number of ways that a given integer, N, can be expressed as the sum of the Xth powers
6+
* of unique, natural numbers.
7+
* For example, if N=100 and X=3, we have to find all combinations of unique cubes adding up to 100.
8+
* The only solution is 1^3 + 2^3 + 3^3 + 4^3. Therefore, the output will be 1.
9+
*
10+
* N is represented by the parameter 'targetSum' in the code.
11+
* X is represented by the parameter 'power' in the code.
812
*/
913
public class PowerSum {
1014

11-
private int count = 0;
12-
private int sum = 0;
13-
14-
public int powSum(int n, int x) {
15-
sum(n, x, 1);
16-
return count;
15+
/**
16+
* Calculates the number of ways to express the target sum as a sum of Xth powers of unique natural numbers.
17+
*
18+
* @param targetSum The target sum to achieve (N in the problem statement)
19+
* @param power The power to raise natural numbers to (X in the problem statement)
20+
* @return The number of ways to express the target sum
21+
*/
22+
public int powSum(int targetSum, int power) {
23+
// Special case: when both targetSum and power are zero
24+
if (targetSum == 0 && power == 0) {
25+
return 1; // by convention, one way to sum to zero: use nothing
26+
}
27+
return sumRecursive(targetSum, power, 1, 0);
1728
}
1829

19-
// here i is the natural number which will be raised by X and added in sum.
20-
public void sum(int n, int x, int i) {
21-
// if sum is equal to N that is one of our answer and count is increased.
22-
if (sum == n) {
23-
count++;
24-
return;
25-
} // we will be adding next natural number raised to X only if on adding it in sum the
26-
// result is less than N.
27-
else if (sum + power(i, x) <= n) {
28-
sum += power(i, x);
29-
sum(n, x, i + 1);
30-
// backtracking and removing the number added last since no possible combination is
31-
// there with it.
32-
sum -= power(i, x);
30+
/**
31+
* Recursively calculates the number of ways to express the remaining sum as a sum of Xth powers.
32+
*
33+
* @param remainingSum The remaining sum to achieve
34+
* @param power The power to raise natural numbers to (X in the problem statement)
35+
* @param currentNumber The current natural number being considered
36+
* @param currentSum The current sum of powered numbers
37+
* @return The number of valid combinations
38+
*/
39+
private int sumRecursive(int remainingSum, int power, int currentNumber, int currentSum) {
40+
int newSum = currentSum + (int) Math.pow(currentNumber, power);
41+
42+
if (newSum == remainingSum) {
43+
return 1;
3344
}
34-
if (power(i, x) < n) {
35-
// calling the sum function with next natural number after backtracking if when it is
36-
// raised to X is still less than X.
37-
sum(n, x, i + 1);
45+
if (newSum > remainingSum) {
46+
return 0;
3847
}
39-
}
4048

41-
// creating a separate power function so that it can be used again and again when required.
42-
private int power(int a, int b) {
43-
return (int) Math.pow(a, b);
49+
return sumRecursive(remainingSum, power, currentNumber + 1, newSum) + sumRecursive(remainingSum, power, currentNumber + 1, currentSum);
4450
}
4551
}

0 commit comments

Comments
 (0)