Skip to content

Instantly share code, notes, and snippets.

@dhinojosa
Created September 17, 2020 12:53
Show Gist options
  • Save dhinojosa/82b8e5edeedbbed26d7c461b069c2d79 to your computer and use it in GitHub Desktop.
Save dhinojosa/82b8e5edeedbbed26d7c461b069c2d79 to your computer and use it in GitHub Desktop.
public class WordChallenge1 {
static class Tuple2<A, B> {
private final A a;
private final B b;
public Tuple2(A a, B b) {
this.a = a;
this.b = b;
}
public A getA() {
return a;
}
public B getB() {
return b;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Tuple2<?, ?> tuple2 = (Tuple2<?, ?>) o;
return Objects.equals(a, tuple2.a) &&
Objects.equals(b, tuple2.b);
}
@Override
public String toString() {
return new StringJoiner(", ",
Tuple2.class.getSimpleName() + "[",
"]")
.add("a=" + a)
.add("b=" + b)
.toString();
}
}
private static Set<String> dictionary;
protected static Set<String> getDictionary() {
if (dictionary != null) return dictionary;
//From https://gist.github.com/wchargin/8927565
//since /usr/share/dict/words didn't have a comprehensive list
InputStream resourceAsStream =
WordChallenge1.class.getResourceAsStream("/words");
InputStreamReader inputStreamReader =
new InputStreamReader(resourceAsStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
dictionary = bufferedReader
.lines()
.filter(w -> Character.isLowerCase(w.charAt(0)))
.filter(w -> !w.endsWith("\'s"))
.map(String::toUpperCase)
.collect(Collectors.toSet());
return dictionary;
}
//From: https://www.npr.org/2019/11/10/777941999/sunday-puzzle-7-letters
public static void main(String[] args) {
List<String> words = List.of("PARTOOK", "TERSELY",
"GUNROOM", "HELLISH", "LORELEI",
"CARCASS", "GORDIAN", "LIGNITE",
"PARTING");
Supplier<Stream<String>> alpha =
() -> IntStream.range('A', 'Z')
.mapToObj(x -> String.valueOf((char) x));
Stream<Tuple2<String, String>> candidates =
words
.stream()
.map(String::toUpperCase)
.flatMap(orig -> wordPairCandidates(alpha, orig));
Set<String> dictionary = getDictionary();
Stream<Tuple2<String, String>> candidatesWithOriginalRemoved =
candidates.filter(t -> !t.getB().equals(t.getA()));
Stream<Tuple2<String, String>> candidatesWithUniqueFirstLastLetters =
candidatesWithOriginalRemoved.filter(t ->
!hasSameFirstOrLastLetter(t.getA(), t.getB()));
Stream<Tuple2<String, String>> validWordCandidates =
candidatesWithUniqueFirstLastLetters
.filter(t -> dictionary.contains(t.getB()));
Map<String, List<String>> validWordCandidateGroups =
validWordCandidates
.collect(
Collectors.groupingBy(Tuple2::getA,
Collectors.mapping(Tuple2::getB, Collectors.toList())));
validWordCandidateGroups.forEach((key, value) -> {
System.out.printf("Word: %s%n", key);
value.forEach(word -> System.out.printf("\t%s%n", word));
});
}
private static Stream<Tuple2<String, String>> wordPairCandidates
(Supplier<Stream<String>> alpha, String orig) {
String chopped = orig.substring(1, orig.length() - 1);
return
alpha.get().flatMap(c1 ->
alpha.get().map(c2 -> new Tuple2<>(orig, c1 + chopped + c2)));
}
private static boolean hasSameFirstOrLastLetter(String a, String b) {
return a.charAt(0) == b.charAt(0) ||
a.charAt(a.length() - 1) == b.charAt(b.length() - 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment