-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWordleHelper.java
163 lines (129 loc) · 5.03 KB
/
WordleHelper.java
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package wordle;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import java.util.function.*;
import java.util.stream.*;
// @author Mouli, 2022/01/30
public class WordleHelper {
public static void main(String[] args) {
// green string length must be 5
String green = "A....";
// yellow list size must be 5
List<String> yellow =
Arrays.asList("", "L", "", "", "P");
// no restriction in length
String grey = "PP";
Wordle.of(green, yellow, grey).findClosest();
}
}
class Wordle {
private final String green;
private final List<String> yellow;
private final String grey;
// get Dictionary
private final List<String> dict = Dictionary.getDict();
// private constructor
private Wordle(String green, List<String> yellow, String grey) {
// green string to uppercase
this.green = green.toUpperCase();
// yellow list to uppercase
yellow.replaceAll(String::toUpperCase);
this.yellow = yellow;
// grey string to uppercase
this.grey = grey.toUpperCase();
}
// use static method to initialise Wordle
public static Wordle of(String green, List<String> yellow, String grey) {
return new Wordle(green, yellow, grey);
}
// find the closest match
public void findClosest() {
filterGrey();
filterYellow();
filterGreen();
}
// remove words containing `grey` letters
// from dictionary
private void filterGrey() {
// convert grey string to char list
var greys = grey.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.toList());
// map each char of greys with their frequencies
var freqMap = greys.stream()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()));
// loop the green string
// if grey char list contains char from
// green string then increment value of
// the key of freqMap by 1 each time
IntStream.range(0, green.length())
.filter(i -> greys.contains(green.charAt(i)))
.forEach(i -> freqMap.merge(
green.charAt(i), 1L, Long::sum));
// remove those words from dictionary which
// contains grey letters of given frequencies
freqMap.forEach((key, value) ->
dict.removeIf(word ->
word.matches(
(".*"+key).repeat(value.intValue()) +".*")));
}
private void filterYellow() {
// only extract those words that contains
// yellow letters
yellow.forEach(s ->
dict.removeIf(str -> !str.contains(s)));
// remove those words from Dictionary that
// contains yellow letters in same position
IntStream.range(0, yellow.size())
.<Predicate<? super String>>
mapToObj(i -> s ->
String.valueOf(s.charAt(i))
.equals(yellow.get(i))
)
.forEach(dict::removeIf);
}
private void filterGreen() {
// check for words that contains `green`
// letters in given position
dict.forEach(word ->
Map.of(green, word)
.entrySet().stream()
.filter(e ->
IntStream.range(0, e.getKey().length())
.noneMatch(i ->
e.getKey().charAt(i) != '.'
&& ( e.getKey().charAt(i)
!= e.getValue().charAt(i))
)
)
.map(Map.Entry::getValue)
.forEach(System.out::println));
}
}
interface Dictionary {
static List<String> getDict() {
try(var dictIs = new URL(
// dictionary url
"https://raw.githubusercontent.com/seanpatlan/wordle-words/main/valid-words.csv").openStream()) {
return
Pattern.compile("\n")
.splitAsStream(
new String(dictIs.readAllBytes()))
.map(s ->
// replacing non alphabets
s.replaceAll("[^a-zA-Z]", "")
// making words uppercase
.toUpperCase())
// extracting only those words from
// dictionary that are of length 5
.filter(s -> s.length() == 5)
.distinct()
.collect(Collectors.toList());
} catch (Exception e) {
return List.of();
}
}
}