使用 Groovy™ 检查 Wordle
作者: Paul King
发布时间:2023-02-08 12:00AM
Donald Raab 的这篇文章介绍了如何使用 Smalltalk 和 Java 以及 Eclipse Collections 编写 Wordle 检查器。让我们看看如何在 Groovy 中做同样的事情。我们可以很容易地将 Eclipse Collections 与 Groovy 一起使用,但在这篇博客中,我们只使用 JDK collections。
在 Wordle 中,我们必须尝试猜测一个隐藏的单词。对于我们做出的每一个猜测,我们都会得到一个结果。对于每个位置正确的字母,返回大写字母。有时我们会猜对字母,但位置不正确。在这种情况下,结果中会出现小写字母。结果中出现的字母次数永远不会超过隐藏单词中出现的次数。
首先,我们的测试用例(来自原始文章)
def triples = [
[".....", "aaaaa", "bbbbb"],
["A....", "aaaaa", "abbbb"],
[".A...", "aaaaa", "babbb"],
["..A..", "aaaaa", "bbabb"],
["...A.", "aaaaa", "bbbab"],
["....A", "aaaaa", "bbbba"],
[".a...", "abbbb", "caccc"],
["..a..", "abbbb", "ccacc"],
["...a.", "abbbb", "cccac"],
["....a", "abbbb", "cccca"],
["A....", "abbbb", "accca"],
["A....", "abbbb", "accaa"],
["A..a.", "aabbb", "accaa"],
["AA...", "aabbb", "aacaa"],
["...aa", "aabbb", "cccaa"],
["..A..", "bbabb", "aaaaa"],
["AAAAA", "aaaaa", "aaaaa"],
["BRAVO", "bravo", "bravo"]]
现在我们将编写我们的方法,用于检查隐藏单词中的字母列表与我们猜测中的字母列表。与原始文章相比,它与一些 Smalltalk 解决方案和几个 Java 解决方案有相似之处。
def checkGuess(hs, gs) {
def remaining = hs.groupBy() // (1)
def matches = [hs, gs].transpose().collect{ h, g -> // (2)
if (h == g) { remaining[g].pop(); g.toUpperCase() }
else '.'
}
gs.eachWithIndex { g, i -> // (3)
if (matches[i] == '.' && remaining[g]?.remove(g)) {
matches[i] = g
}
}
matches.join()
}
-
我们将隐藏的字母分组。我们的袋子等价物。
-
在第一遍中,我们使用一个 zip 运算符(在 Groovy 中称为
transpose
)收集精确匹配。 -
在第二遍中,我们收集匹配但位置不同的字母。
最后,我们根据测试用例检查我们的方法
triples.each { result, hidden, guess ->
assert result == checkGuess(hidden.toList(), guess.toList())
}