-
Notifications
You must be signed in to change notification settings - Fork 1k
/
Crossword_puzzle.java
249 lines (200 loc) · 7.54 KB
/
Crossword_puzzle.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/* You are given a 10*10 2-D array(arr) containing only '+' and '-' characters, which represents a crossword puzzle.
You are also given n number of words which need to be filled into the crossword.
Cells containing '-' are to be filled with the given words. */
import java.util.*;
public class Crossword_puzzle {
public static void main(String[] args) throws Exception {
// User input
Scanner scn = new Scanner(System.in);
char[][] arr = new char[10][10];
System.out.println("\nEnter the crossword puzzle: ");
// filling the crossword board array
for (int i = 0; i < arr.length; i++) {
String str = scn.next();
arr[i] = str.toCharArray();
}
// total number of words
System.out.println("\nEnter the total words: ");
int n = scn.nextInt();
// storing words in array from input stream
System.out.println("\nEnter the words: ");
String[] words = new String[n];
for (int i = 0; i < words.length; i++) {
words[i] = scn.next();
}
System.out.println();
// invoking function to solve the crossword puzzle.
solvePuzzle(arr, words, 0);
// closing input stream
scn.close();
}
// Global count to keep track of number of configurations
static int count = 0;
// function to display the solution on the console
public static void display(char[][] arr) {
// configuration number
System.out.print(count + ".");
for (int i = 0; i < arr.length; i++) {
if(i>0) {
System.out.print(" " + "\t");
}
else {
System.out.print("\t");
}
for (int j = 0; j < arr[0].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
System.out.println();
}
public static void solvePuzzle(char[][] arr, String[] words, int idx) {
// Base case: All words are placed on the board
if (idx == words.length) {
count++;
display(arr);
return;
}
// Current word
String word = words[idx];
// Checking all possibilities for the current word
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
// word can be placed if the starting point is '-' or first letter of current
// word
if (arr[i][j] == '-' || arr[i][j] == word.charAt(0)) {
// checking if we can place the word horizontally
if (canPlaceWordHorizontally(arr, word, i, j)) {
// placing word horizontally
boolean[] wePlaced = placeWordHorizontally(arr, word, i, j);
// recursively calling for the next word
solvePuzzle(arr, words, idx + 1);
// undo the changes made while backtracking
removeWordHorizontally(arr, wePlaced, i, j);
}
// checking if we can place the word vertically
if (canPlaceWordVertically(arr, word, i, j)) {
// placing word vertically
boolean[] wePlaced = placeWordVertically(arr, word, i, j);
// recursively calling for the next word
solvePuzzle(arr, words, idx + 1);
// undo the changes made while backtracking
removeWordVertically(arr, wePlaced, i, j);
}
}
}
}
}
// This function checks all possible conditions for which the word can't be
// placed horizontally
public static boolean canPlaceWordHorizontally(char[][] arr, String word, int i, int j) {
if (j - 1 >= 0 && arr[i][j - 1] != '+')
return false;
else if (j + word.length() < arr[0].length && arr[i][j + word.length()] != '+')
return false;
for (int jj = 0; jj < word.length(); jj++) {
if (j + jj >= arr[0].length)
return false;
if (arr[i][j + jj] == '-' || arr[i][j + jj] == word.charAt(jj))
continue;
else
return false;
}
return true;
}
// This function checks all possible conditions for which the word can't be
// placed vertically
public static boolean canPlaceWordVertically(char[][] arr, String word, int i, int j) {
if (i - 1 >= 0 && arr[i - 1][j] != '+')
return false;
else if (i + word.length() < arr.length && arr[i + word.length()][j] != '+')
return false;
for (int ii = 0; ii < word.length(); ii++) {
if (i + ii >= arr.length)
return false;
if (arr[i + ii][j] == '-' || arr[i + ii][j] == word.charAt(ii))
continue;
else
return false;
}
return true;
}
// Places the word horizontally and returns a boolean array with only those
// indices marked true where changes were made by current word
public static boolean[] placeWordHorizontally(char[][] arr, String word, int i, int j) {
boolean[] wePlaced = new boolean[word.length()];
for (int jj = 0; jj < word.length(); jj++) {
if (arr[i][j + jj] == '-') {
arr[i][j + jj] = word.charAt(jj);
wePlaced[jj] = true;
}
}
return wePlaced;
}
// Places the word vertically and returns a boolean array with only those
// indices marked true where changes were made by current word
public static boolean[] placeWordVertically(char[][] arr, String word, int i, int j) {
boolean[] wePlaced = new boolean[word.length()];
for (int ii = 0; ii < word.length(); ii++) {
if (arr[i + ii][j] == '-') {
arr[i + ii][j] = word.charAt(ii);
wePlaced[ii] = true;
}
}
return wePlaced;
}
// Removing the current word from row
public static void removeWordHorizontally(char[][] arr, boolean[] wePlaced, int i, int j) {
for (int jj = 0; jj < wePlaced.length; jj++) {
if (wePlaced[jj] == true) {
arr[i][j + jj] = '-';
}
}
}
// Removing the current word from column
public static void removeWordVertically(char[][] arr, boolean[] wePlaced, int i, int j) {
for (int ii = 0; ii < wePlaced.length; ii++) {
if (wePlaced[ii] == true) {
arr[i + ii][j] = '-';
}
}
}
}
/*
The approach behind this is to recursively check for each word in the vertical position and in the horizontal position.
Then fill the word in the matrix that can be the best fit in the corresponding position of the grid,
then update the crossword grid by filling the gap with that word.
Sample Input/Output
Example 1:
Enter the crossword puzzle:
+-++++++++
+-++++++++
+-++++++++
+-----++++
+-+++-++++
+-+++-++++
+++++-++++
++------++
+++++-++++
+++++-++++
Enter the total words:
4
Enter the words:
LONDON
DELHI
ICELAND
ANKARA
1. + L + + + + + + + +
+ O + + + + + + + +
+ N + + + + + + + +
+ D E L H I + + + +
+ O + + + C + + + +
+ N + + + E + + + +
+ + + + + L + + + +
+ + A N K A R A + +
+ + + + + N + + + +
+ + + + + D + + + +
Time Complexity: O(2^N)
Space Complexity: O(N*M)
N is the number of words, M is the length of current word
*/