Created
September 17, 2020 12:53
-
-
Save dhinojosa/82b8e5edeedbbed26d7c461b069c2d79 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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