Skip to content

Commit 2442dff

Browse files
authored
Merge branch 'master' into jobscheduling_deadline_new_algo
2 parents e0126d8 + 5c79e5d commit 2442dff

40 files changed

+2266
-444
lines changed

DIRECTORY.md

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

pom.xml

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

3+
/**
4+
* This class contains methods to solve a maze using recursive backtracking.
5+
* The maze is represented as a 2D array where walls, paths, and visited/dead
6+
* ends are marked with different integers.
7+
*
8+
* The goal is to find a path from a starting position to the target position
9+
* (map[6][5]) while navigating through the maze.
10+
*/
311
public final class MazeRecursion {
12+
413
private MazeRecursion() {
514
}
615

7-
public static void mazeRecursion() {
8-
// First create a 2 dimensions array to mimic a maze map
9-
int[][] map = new int[8][7];
10-
int[][] map2 = new int[8][7];
11-
12-
// We use 1 to indicate wall
13-
// Set the ceiling and floor to 1
14-
for (int i = 0; i < 7; i++) {
15-
map[0][i] = 1;
16-
map[7][i] = 1;
17-
}
18-
19-
// Then we set the left and right wall to 1
20-
for (int i = 0; i < 8; i++) {
21-
map[i][0] = 1;
22-
map[i][6] = 1;
23-
}
24-
25-
// Now we have created a maze with its wall initialized
26-
27-
// Here we set the obstacle
28-
map[3][1] = 1;
29-
map[3][2] = 1;
30-
31-
// Print the current map
32-
System.out.println("The condition of the map: ");
33-
for (int i = 0; i < 8; i++) {
34-
for (int j = 0; j < 7; j++) {
35-
System.out.print(map[i][j] + " ");
36-
}
37-
System.out.println();
38-
}
39-
40-
// clone another map for setWay2 method
41-
for (int i = 0; i < map.length; i++) {
42-
System.arraycopy(map[i], 0, map2[i], 0, map[i].length);
43-
}
44-
45-
// By using recursive backtracking to let your ball(target) find its way in the
46-
// maze
47-
// The first parameter is the map
48-
// Second parameter is x coordinate of your target
49-
// Third parameter is the y coordinate of your target
50-
setWay(map, 1, 1);
51-
setWay2(map2, 1, 1);
52-
53-
// Print out the new map1, with the ball footprint
54-
System.out.println("After the ball goes through the map1,show the current map1 condition");
55-
for (int i = 0; i < 8; i++) {
56-
for (int j = 0; j < 7; j++) {
57-
System.out.print(map[i][j] + " ");
58-
}
59-
System.out.println();
16+
/**
17+
* This method solves the maze using the "down -> right -> up -> left"
18+
* movement strategy.
19+
*
20+
* @param map The 2D array representing the maze (walls, paths, etc.)
21+
* @return The solved maze with paths marked, or null if no solution exists.
22+
*/
23+
public static int[][] solveMazeUsingFirstStrategy(int[][] map) {
24+
if (setWay(map, 1, 1)) {
25+
return map;
6026
}
27+
return null;
28+
}
6129

62-
// Print out the new map2, with the ball footprint
63-
System.out.println("After the ball goes through the map2,show the current map2 condition");
64-
for (int i = 0; i < 8; i++) {
65-
for (int j = 0; j < 7; j++) {
66-
System.out.print(map2[i][j] + " ");
67-
}
68-
System.out.println();
30+
/**
31+
* This method solves the maze using the "up -> right -> down -> left"
32+
* movement strategy.
33+
*
34+
* @param map The 2D array representing the maze (walls, paths, etc.)
35+
* @return The solved maze with paths marked, or null if no solution exists.
36+
*/
37+
public static int[][] solveMazeUsingSecondStrategy(int[][] map) {
38+
if (setWay2(map, 1, 1)) {
39+
return map;
6940
}
41+
return null;
7042
}
7143

7244
/**
73-
* Using recursive path finding to help the ball find its way in the maze
74-
* Description:
75-
* 1. map (means the maze)
76-
* 2. i, j (means the initial coordinate of the ball in the maze)
77-
* 3. if the ball can reach the end of maze, that is position of map[6][5],
78-
* means the we have found a path for the ball
79-
* 4. Additional Information: 0 in the map[i][j] means the ball has not gone
80-
* through this position, 1 means the wall, 2 means the path is feasible, 3
81-
* means the ball has gone through the path but this path is dead end
82-
* 5. We will need strategy for the ball to pass through the maze for example:
83-
* Down -> Right -> Up -> Left, if the path doesn't work, then backtrack
45+
* Attempts to find a path through the maze using a "down -> right -> up -> left"
46+
* movement strategy. The path is marked with '2' for valid paths and '3' for dead ends.
8447
*
85-
* @author OngLipWei
86-
* @version Jun 23, 2021 11:36:14 AM
87-
* @param map The maze
88-
* @param i x coordinate of your ball(target)
89-
* @param j y coordinate of your ball(target)
90-
* @return If we did find a path for the ball,return true,else false
48+
* @param map The 2D array representing the maze (walls, paths, etc.)
49+
* @param i The current x-coordinate of the ball (row index)
50+
* @param j The current y-coordinate of the ball (column index)
51+
* @return True if a path is found to (6,5), otherwise false
9152
*/
92-
public static boolean setWay(int[][] map, int i, int j) {
93-
if (map[6][5] == 2) { // means the ball find its path, ending condition
53+
private static boolean setWay(int[][] map, int i, int j) {
54+
if (map[6][5] == 2) {
9455
return true;
9556
}
96-
if (map[i][j] == 0) { // if the ball haven't gone through this point
97-
// then the ball follows the move strategy : down -> right -> up -> left
98-
map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2
99-
// first。
100-
if (setWay(map, i + 1, j)) { // go down
57+
58+
// If the current position is unvisited (0), explore it
59+
if (map[i][j] == 0) {
60+
// Mark the current position as '2'
61+
map[i][j] = 2;
62+
63+
// Move down
64+
if (setWay(map, i + 1, j)) {
10165
return true;
102-
} else if (setWay(map, i, j + 1)) { // go right
66+
}
67+
// Move right
68+
else if (setWay(map, i, j + 1)) {
10369
return true;
104-
} else if (setWay(map, i - 1, j)) { // go up
70+
}
71+
// Move up
72+
else if (setWay(map, i - 1, j)) {
10573
return true;
106-
} else if (setWay(map, i, j - 1)) { // go left
74+
}
75+
// Move left
76+
else if (setWay(map, i, j - 1)) {
10777
return true;
108-
} else {
109-
// means that the current point is the dead end, the ball cannot proceed, set
110-
// the current point to 3 and return false, the backtracking will start, it will
111-
// go to the previous step and check for feasible path again
112-
map[i][j] = 3;
113-
return false;
11478
}
115-
} else { // if the map[i][j] != 0 , it will probably be 1,2,3, return false because the
116-
// ball cannot hit the wall, cannot go to the path that has gone though before,
117-
// and cannot head to deadened.
79+
80+
map[i][j] = 3; // Mark as dead end (3) if no direction worked
11881
return false;
11982
}
83+
return false;
12084
}
12185

122-
// Here is another move strategy for the ball: up->right->down->left
123-
public static boolean setWay2(int[][] map, int i, int j) {
124-
if (map[6][5] == 2) { // means the ball find its path, ending condition
86+
/**
87+
* Attempts to find a path through the maze using an alternative movement
88+
* strategy "up -> right -> down -> left".
89+
*
90+
* @param map The 2D array representing the maze (walls, paths, etc.)
91+
* @param i The current x-coordinate of the ball (row index)
92+
* @param j The current y-coordinate of the ball (column index)
93+
* @return True if a path is found to (6,5), otherwise false
94+
*/
95+
private static boolean setWay2(int[][] map, int i, int j) {
96+
if (map[6][5] == 2) {
12597
return true;
12698
}
127-
if (map[i][j] == 0) { // if the ball haven't gone through this point
128-
// then the ball follows the move strategy : up->right->down->left
129-
map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2
130-
// first。
131-
if (setWay2(map, i - 1, j)) { // go up
99+
100+
if (map[i][j] == 0) {
101+
map[i][j] = 2;
102+
103+
// Move up
104+
if (setWay2(map, i - 1, j)) {
132105
return true;
133-
} else if (setWay2(map, i, j + 1)) { // go right
106+
}
107+
// Move right
108+
else if (setWay2(map, i, j + 1)) {
134109
return true;
135-
} else if (setWay2(map, i + 1, j)) { // go down
110+
}
111+
// Move down
112+
else if (setWay2(map, i + 1, j)) {
136113
return true;
137-
} else if (setWay2(map, i, j - 1)) { // go left
114+
}
115+
// Move left
116+
else if (setWay2(map, i, j - 1)) {
138117
return true;
139-
} else {
140-
// means that the current point is the dead end, the ball cannot proceed, set
141-
// the current point to 3 and return false, the backtracking will start, it will
142-
// go to the previous step and check for feasible path again
143-
map[i][j] = 3;
144-
return false;
145118
}
146-
} else { // if the map[i][j] != 0 , it will probably be 1,2,3, return false because the
147-
// ball cannot hit the wall, cannot go to the path that has gone through before,
148-
// and cannot head to deadend.
119+
120+
map[i][j] = 3; // Mark as dead end (3) if no direction worked
149121
return false;
150122
}
123+
return false;
151124
}
152125
}

0 commit comments

Comments
 (0)