-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWordFinder.java
More file actions
127 lines (116 loc) · 4.76 KB
/
WordFinder.java
File metadata and controls
127 lines (116 loc) · 4.76 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
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* A program to find all possible Scrabble words from a given rack of tiles.
*
* Functionality:
* Reads a dictionary file of valid Scrabble words.
* Accepts user input for a rack of Scrabble tiles and outputs all valid
* words that can be formed from the rack along with their Scrabble scores.
* Words are sorted by score, and ties are broken alphabetically.
*
* Usage:
* - Provide the dictionary file name as a command-line argument or let it default to "sowpods.txt".
* - Run the program by typing `java Wordfinder [filename]` and enter Scrabble racks. Type `.` to quit.
*
*/
public class WordFinder {
/**
* The main method to execute the WordFinder program.
*
* @param args command-line arguments. The first argument, if provided, should
* be the dictionary file name.
* @throws FileNotFoundException if the dictionary file is not found.
* @throws IllegalDictionaryException if the dictionary contains duplicate words.
*/
public static void main(String[] args) throws FileNotFoundException, IllegalDictionaryException {
String dictionaryFileName;
if (args.length > 0) {
dictionaryFileName = args[0];
} else {
dictionaryFileName = "sowpods.txt";
}
try {
AnagramDictionary curAnagramDictionary = new AnagramDictionary(dictionaryFileName);
ScoreTable scoreTable = new ScoreTable();
System.out.println("Type . to quit.");
System.out.print("Rack? ");
Scanner in = new Scanner(System.in);
// Read user input until termination.
while (true) {
String input = in.next();
if (input.equals(".")) {
return;
}
Rack curRack = new Rack(input);
getAnagramsFromRack(curRack, curAnagramDictionary, scoreTable, input);
System.out.print("Rack? ");
}
} catch (FileNotFoundException | IllegalDictionaryException e) {
System.out.println(e.getMessage());
System.out.println("Exiting program.");
System.exit(1);
}
}
/**
* Finds and displays all valid words (and their scores) that can be formed
* from a given rack of Scrabble tiles.
*
* @param chars a Rack object representing the given tiles.
* @param dictionary the AnagramDictionary to fetch valid words.
* @param table the ScoreTable to compute word scores.
* @param input the original input string for user feedback.
*/
private static void getAnagramsFromRack(Rack chars, AnagramDictionary dictionary, ScoreTable table, String input) {
ArrayList<String> allSubSets = chars.getAllSubsets();
ArrayList<String> allAnagrams = new ArrayList<>();
// Collect all valid anagrams for each subset.
for (int i = 0; i < allSubSets.size(); i++) {
String curSubset = allSubSets.get(i);
if (curSubset.length() > 0) {
ArrayList<String> anagrams = dictionary.getAnagramsOf(curSubset);
if (!anagrams.isEmpty()) {
allAnagrams.addAll(anagrams);
}
}
}
System.out.println("We can make " + allAnagrams.size() + " words from " + "\"" + input + "\"");
if (allAnagrams.size() > 0) {
System.out.println("All of the words with their scores (sorted by score): ");
}
sortAnagrams(allAnagrams, table); // Sort and display the anagrams.
}
/**
* Sorts a list of words by their Scrabble score in descending order. Ties are
* broken alphabetically.
*
* @param input the list of words to sort.
* @param table the ScoreTable to calculate word scores.
*/
private static void sortAnagrams(ArrayList<String> input, ScoreTable table) {
HashMap<String, Integer> words = new HashMap<>();
// Calculate and store the score for each word.
for (int i = 0; i < input.size(); i++) {
String word = input.get(i);
Integer score = table.wordScore(word);
words.put(word, score);
}
ArrayList<Map.Entry<String, Integer>> wordsArray = new ArrayList<>(words.entrySet());
// Sort by score (descending). Break ties alphabetically.
wordsArray.sort((word1, word2) -> {
int compareScore = Integer.compare(word2.getValue(), word1.getValue());
if (compareScore != 0) {
return compareScore;
} else {
return word1.getKey().compareTo(word2.getKey());
}
});
// Print the sorted words and their scores.
for (int j = 0; j < wordsArray.size(); j++) {
System.out.println(wordsArray.get(j).getValue() + ": " + wordsArray.get(j).getKey());
}
}
}