-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathBoggleSolver.java
More file actions
129 lines (112 loc) · 4.68 KB
/
BoggleSolver.java
File metadata and controls
129 lines (112 loc) · 4.68 KB
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
package assignment4;
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import java.util.Objects;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
public class BoggleSolver {
private static final char Q = 'Q';
private static final char U = 'U';
private static final int[] SCORES = {0, 0, 0, 1, 1, 2, 3, 5, 11};
private final Trie trie = new Trie();
private final Set<String> dictionary = new HashSet<>();
// Initializes the data structure using the given array of strings as the dictionary.
// (We're assuming each word in the dictionary contains only the uppercase letters A through Z.)
public BoggleSolver(String[] dictionary) {
Arrays.stream(dictionary)
.forEach(word -> {
if (word.length() >= 3) {
trie.put(word);
this.dictionary.add(word);
}
});
}
// Returns the set of all valid words in the given Boggle board, as an Iterable.
public Iterable<String> getAllValidWords(BoggleBoard board) {
Set<String> total = new HashSet<>();
boolean[] visited = new boolean[board.rows() * board.cols()];
for (int i = 0; i < board.rows(); i++) {
for (int j = 0; j < board.cols(); j++) {
LinkedList<Trie.Node> stack = new LinkedList<>();
stack.push(trie.getRoot());
buildWords("", i, j, total, visited, board, stack);
visited[i * board.cols() + j] = false;
}
}
return total;
}
// dfs search which uses stack of trie nodes for resuming the string
// search from the point where it stopped the previous prefix search
private void buildWords(String currentWord, int row, int col, Set<String> result, boolean[] visited,
BoggleBoard board, LinkedList<Trie.Node> stack) {
char ch = board.getLetter(row, col);
visited[row * board.cols() + col] = true;
Trie.Node current = stack.peek();
if (current == null) {
return;
}
Trie.Node x = current.getNext(ch);
if (x != null) {
stack.push(x);
String newWord = currentWord + ch;
if (ch == Q) {
// noinspection ConstantConditions
Trie.Node uNode = stack.peek().getNext(U);
if (uNode == null) {
stack.pop();
visited[row * board.cols() + col] = false;
return;
}
stack.push(uNode);
newWord += U;
}
if (newWord.length() >= 3 && dictionary.contains(newWord)) {
result.add(newWord);
}
for (int i = row - 1; i <= row + 1; i++) {
for (int j = col - 1; j <= col + 1; j++) {
if (i == row && j == col) {
continue;
}
if (i >= 0 && j >= 0 && i < board.rows() && j < board.cols()
&& !visited[i * board.cols() + j]) {
buildWords(newWord, i, j, result, visited, board, stack);
}
}
}
stack.pop();
if (ch == Q) {
stack.pop();
}
}
visited[row * board.cols() + col] = false;
}
// Returns the score of the given word if it is in the dictionary, zero otherwise.
// (We're assuming the word contains only the uppercase letters A through Z.)
public int scoreOf(String word) {
if (word == null || word.length() < 3 || !dictionary.contains(word)) {
return 0;
}
return word.length() >= SCORES.length ? SCORES[8] : SCORES[word.length()];
}
public static void main(String[] args) {
String fileName = args[0];
System.out.println(args[0]);
In in = new In(Objects.requireNonNull(BoggleSolver.class.getClassLoader()
.getResource("assignment4/" + fileName)).getFile());
String[] dictionary = in.readAllStrings();
BoggleSolver solver = new BoggleSolver(dictionary);
String boardFile = Objects.requireNonNull(BoggleSolver.class.getClassLoader()
.getResource("assignment4/" + args[1])).getFile();
BoggleBoard board = new BoggleBoard(boardFile);
System.out.println(board);
int score = 0;
for (String word : solver.getAllValidWords(board)) {
StdOut.println(word + " = " + solver.scoreOf(word));
score += solver.scoreOf(word);
}
StdOut.println("Score = " + score);
}
}