debugjavaMinor
Broken keyboard challenge
Viewed 0 times
keyboardbrokenchallenge
Problem
Inspired by Reddit r/dailyprogrammer
Help! My keyboard is broken, only a few keys work any more. If I tell you what keys work, can you tell me what words I can write?
The program works fine, not really any additions I wish to make to it. Was just wanting some general feedback on the layout, structure and efficiency.
Note: The dictionary used can be found in the given link.
```
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* Created on 7/1/2016.
*
* Inspired by r/dailyprogrammer
* https://www.reddit.com/r/dailyprogrammer/comments/3pcb3i/20151019_challenge_237_easy_broken_keyboard/
*/
public class BrokenKeyboard {
private static List wordDict;
private static final String dictPath = "Dictionaries/EnglishWords.txt";
/**
* The main acquires input from the user then
* applies it to the other below methods.
* @param args Unused.
*/
public static void main(String args[]) {
BrokenKeyboard.setDict(dictPath); // Stores dictionary in list.
System.out.println("Processing...");
System.out.println(String.join(", ", findMatches("bikn", wordDict)));
}
/**
* Used to load a given text file into memory.
* @param filePath Used to specify the path of the file that needs to be loaded into memory.
*/
private static void setDict(String filePath){
try {
wordDict = Files.readAllLines(new File(filePath).toPath());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Used to compare a given key to the text file loaded into memory.
* @param key The inputted set of characters compared to the given dictionary.
* @param dict The list of words that will be used to compare to the key.
* @return The list of matches made when comparing the key with the given dictionary.
*/
private static List findMatches(String key, List di
Help! My keyboard is broken, only a few keys work any more. If I tell you what keys work, can you tell me what words I can write?
The program works fine, not really any additions I wish to make to it. Was just wanting some general feedback on the layout, structure and efficiency.
Note: The dictionary used can be found in the given link.
```
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* Created on 7/1/2016.
*
* Inspired by r/dailyprogrammer
* https://www.reddit.com/r/dailyprogrammer/comments/3pcb3i/20151019_challenge_237_easy_broken_keyboard/
*/
public class BrokenKeyboard {
private static List wordDict;
private static final String dictPath = "Dictionaries/EnglishWords.txt";
/**
* The main acquires input from the user then
* applies it to the other below methods.
* @param args Unused.
*/
public static void main(String args[]) {
BrokenKeyboard.setDict(dictPath); // Stores dictionary in list.
System.out.println("Processing...");
System.out.println(String.join(", ", findMatches("bikn", wordDict)));
}
/**
* Used to load a given text file into memory.
* @param filePath Used to specify the path of the file that needs to be loaded into memory.
*/
private static void setDict(String filePath){
try {
wordDict = Files.readAllLines(new File(filePath).toPath());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Used to compare a given key to the text file loaded into memory.
* @param key The inputted set of characters compared to the given dictionary.
* @param dict The list of words that will be used to compare to the key.
* @return The list of matches made when comparing the key with the given dictionary.
*/
private static List findMatches(String key, List di
Solution
setDict() is a bit of a misnomer; loadDict() would be more accurate. Since the loaded dictionary becomes part of the global state, it would be more appropriate to make it an instance variable than a static variable. If loading fails, you shouldn't just print a stack trace and attempt to continue execution — that defeats the purpose of exceptions. In general, if you don't have a good way to handle an exception, just propagate it (by declaring throws IOException).Your technique for checking whether a word consists solely of a limited set of characters is to do repeated string replacement. That would cause a lot of temporary objects to be allocated and discarded. A more appropriate tool to use would be a regular expression match (using
Pattern.compile("^[bikn]*$"), for example).Since this is a filtering exercise, it would be more eloquently written using
Stream.filter(Predicate) instead of List.Although
String args[] is syntactically valid, String[] args is considered more idiomatic in Java, since String[] is considered the type.Suggested solution
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class BrokenKeyboard {
public static Predicate typableUsing(String availableKeys) {
// CAVEAT: availableKeys is assumed not to contain regex metacharacters
// such as ^ [ ] - \
return Pattern.compile("^[" + availableKeys + "]*$").asPredicate();
}
public static Stream dictionary(File f) throws IOException {
return Files.lines(f.toPath());
}
public static void main(String[] args) throws IOException {
System.out.println(
BrokenKeyboard.dictionary(new File(args[1]))
.filter(BrokenKeyboard.typableUsing(args[0]))
.collect(Collectors.joining(", "))
);
}
}It is possible to resolve the caveat using
Pattern.quote(). I'll leave it as an exercise to the reader. =)Code Snippets
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class BrokenKeyboard {
public static Predicate<String> typableUsing(String availableKeys) {
// CAVEAT: availableKeys is assumed not to contain regex metacharacters
// such as ^ [ ] - \
return Pattern.compile("^[" + availableKeys + "]*$").asPredicate();
}
public static Stream<String> dictionary(File f) throws IOException {
return Files.lines(f.toPath());
}
public static void main(String[] args) throws IOException {
System.out.println(
BrokenKeyboard.dictionary(new File(args[1]))
.filter(BrokenKeyboard.typableUsing(args[0]))
.collect(Collectors.joining(", "))
);
}
}Context
StackExchange Code Review Q#133875, answer score: 3
Revisions (0)
No revisions yet.