Mathematica 中使用模式匹配的填字游戏
假设我从 Mathematica 词典中选择所有 3 个字符单词:
all3 = Characters /@ Select[DictionaryLookup[], StringLength[#] == 3 &];
并且我想形成完整的类似拼字游戏的集合,例如:
A B E
R A Y
E R E
可以水平和垂直阅读单词的位置。
显然,可以通过递归和回溯来找到集合。但是:
1)有没有办法使用模式来解决它?
2)对于哪些维度有有效的解决方案?
编辑
我为DictionaryLookup[]
编写了问题,只是因为它是一个大小合理的可变长度记录数据库。我真正的问题与字典查找无关,而是与某种织机模式有关。
Suppose I select all 3 char words from the Mathematica dictionary:
all3 = Characters /@ Select[DictionaryLookup[], StringLength[#] == 3 &];
and I want to form full scrabble-like sets, like:
A B E
R A Y
E R E
Where the words can be read horizontally and vertically.
Clearly, the sets can be found with recursion and backtracking. But:
1) Is there a way to solve it using patterns?
2) For which dimensions are there valid solutions?
Edit
I wrote the question for DictionaryLookup[]
just because it's a reasonable sized database of variable length records. My real problem is not related to Dictionary lookups but to a certain kind of loom patterns.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定您是否会考虑以下基于模式的方法 - 但它有效,并且可以想象它可以扩展到许多维度,尽管使用
all3
数据集,它可能会很早就解决。 ..这个想法是从一个空白的填字游戏开始:
然后递归地执行以下操作:对于给定的模式,依次查看行,并(在填写完任何一个后)在具有最少的行上展开模式匹配数:
对于给定的候选模式,尝试沿两个维度进行完成,并保留产生最少的维度:
我首先进行递归广度以便能够使用 Union,但对于更大的问题可能需要深度优先。性能一般:笔记本电脑需要 8 分钟才能找到示例问题中的 116568 个匹配项:
原则上,应该可以将其递归到更高的维度,即使用填字游戏列表而不是维度 3 的单词列表。将模式与列表匹配在列表长度中是线性的,对于 100000+ 大小的单词列表来说,这会非常慢......
I am not sure if you would consider the following approach pattern based -- but it works, and it can conceivably be extended to many dimensions, although with the
all3
dataset, it would probably konk out rather early...The idea is to start with a blank crossword:
and then recursively do the following: For a given pattern, look at the rows in turn and (after filling out any with exactly one completion) expand the pattern on the row with the fewest number of matches:
For a given candidate pattern, try out the completion along both dimensions and keep the one that yield the fewest:
I do the recursion breadth first to be able to use Union, but depth first might be necessary for bigger problems. Performance is so-so: 8 laptop minutes to find the 116568 matches in the example problem:
In principle, it should be possible to recurse this into higher dimensions, i.e. using the crosswords list instead of the wordlist for dimension 3. If the time to match a pattern against a list is linear in the list-length, this would be quite slow with a 100000+ sized wordlist...
另一种方法是使用 SatisfiabilityInstances 和约束,指定每一行和每一列都必须是有效单词。下面的代码需要 40 秒才能使用 200 个三字母单词的字典获得前 5 个解决方案。您可以将
SatisfiabilityInstances
替换为SatisfiabilityCount
来获取此类填字游戏的数量。(来源:yaroslavvb.com)
这种方法使用变量如
{{i,j},"c"}
表示单元格{i,j}
获取字母“c”。使用BooleanCountingFunction
每个单元格都被限制只能得到一个字母,每一行和每一列都被限制为一个有效的单词。例如,第一行必须是“ace”或“bar”的约束如下所示An alternative approach is to use
SatisfiabilityInstances
with constraints specifying that every row and every column must be a valid word. Code below takes 40 seconds to get first 5 solutions using dictionary of 200 three-letter words. You could replaceSatisfiabilityInstances
withSatisfiabilityCount
to get the number of such crosswords.(source: yaroslavvb.com)
This approach uses variables like
{{i,j},"c"}
to indicate the cell{i,j}
gets letter "c". Each cell is constrained get exactly one letter withBooleanCountingFunction
, every row and column is constrained to make a valid word. For instance, constraint that first row must be either "ace" or "bar" looks like this