一个算法的拼字比赛
今年早些时候,我写了用MATLAB解决词梯子。在那个帖子里有很多感兴趣的,所以我想分享我的调查关于另一个基于应用。在这个脚本中,我试图创建一个模仿的难题纽约时报拼字比赛游戏。前提:你有七个字母,你的工作是找到所有可能的单词你可以用七个字母。您可以使用字母不止一次,但他们必须是四个或更多信长,他们都必须包括特殊中心的信。每一个拼字游戏都有至少一个“全字母短句”,这是使用所有的七个字母的单词。
作为一个例子,假设你有这个谜题。
从这个难题你可以创造毛孔,崇拜,采用,以及全字母短句。但是你不能创建POD(太短)或论文(不包括中间字母“O”)。
这里我没有那么多感兴趣解决难题。我想写一个脚本,该脚本可以创建一个拼字游戏。
构建字典
我们需要一些地面真理的法律词汇。这是谷歌的10000字的英语词典。小,但足够好为我们的目的。
url =“https://raw.githubusercontent.com/first20hours/google - 10000 english/master/google - 10000 english.txt”;
词库= webread (url);
把单词列表分割成字符串。
话说=分裂(字符串(单词表));
话说=低(单词);
拼字游戏避免字母S,它从来没有处理复数。让我们使用逻辑索引只保留的话,不包含一个年代。
保持= ~ words.contains (“s”);
单词=单词(保持);
其中,只保留四个字母的单词或更长。
保持=单词。strlength > = 4;
单词=单词(保持);
我喜欢这些字符串命令是如何容易阅读和理解!就像我们人类,显然使其工作最长通信的代码。我们不想聘用挑剔,奢侈的代码。
我们得到多少个字?
流(“现在调整字典包含% d \ n”长度(字))
我们扔掉大约一半的单词在我们的字典。
我们会从ASCII表示字母数几次,让我们投资于一个匿名helper函数。它会让下面的代码更容易阅读。
%一个匿名函数将ASCII值= 1,B = 2,…Z = 26。
ascii2letter = @(字符)abs(低(字符))-96;
试试
ascii2letter (“ABCXYZ”)
看起来不错!
建立一个26-column稀疏矩阵来表示独特的字母每个单词的用法。每个单词在字典里得到一行。每一个字母,这个词出现在1。
dictionaryLength =元素个数(单词);
=稀疏(dictionaryLength 26);
为我= 1:dictionaryLength
uniqueLetters =独特(话说(i) .char);
(我,ascii2letter (uniqueLetters)) = 1;
结束
nnz (a) /元素个数(a)
在22%满,这个矩阵稀疏矩阵并不十分稀疏。但这是一个有趣的借口玩稀疏的,让我们继续。这是一个间谍阴谋的矩阵。
间谍(a)
集(gca),…
XTick = 1,…
XTickLabel = num2cell (“一个”:“Z”),…
XTickLabelRotation = 0,…
XAxisLocation =“顶级”,…
PlotBoxAspectRatio = (1 1 1))
很多,我们需要放大。让我们来看看这个词标签编码。
第九= 1002;
%如果你想知道,我喜欢用“九”简称“指数”
单词(第九)
完整的((第九,:))
间谍((1001:1010:))
参照线([1 2 5 12])
yline(2,颜色=“红色”)
集(gca),…
XTick = 1,…
XTickLabel = num2cell (“一个”:“Z”),…
XTickLabelRotation = 0,…
XAxisLocation =“顶级”,…
YTick = 1:10,…
YTickLabels =话说(1001:1010))
注意,即使L在这个词中出现两次,它只有一个的矩阵。
只是为了好玩,让我们做一个字母的柱状图。这可能是一个有用的检查,我们在正确的轨道上。
allLetters = ascii2letter (char(加入(话说,”)));
直方图(allLetters)
集(gca),…
XTick = 1,…
XTickLabel = num2cell (“一个”:“Z”),…
XTickLabelRotation = 0)
正如所料,E是最常出现的信。Q是最少的,但是我们完全消灭。
是由多少个单词到底七个不同的字母?也就是说,有多少潜在的全字母短句游戏吗?
%总结整个行字母
%使用找到构建索引所有的单词,使用七个字母
ix7LetterWords =找到(和(2)= = 7);
长度(ix7LetterWords)
让我们来看看一些七个字母的单词。
num7LetterWords =元素个数(ix7LetterWords);
第九= ix7LetterWords (1:10);
disp(单词(第九(1:10)))
选择一个好的比赛的“种子”全字母短句。
第九=九(9);
disp(话说(ix))
多少个单词可以从相同的7个字母拼写吗?找到所有的单词使用种子词中的字母
第九lettersInSeedWord = (,,);
%找到所有的单词,没有种子词的来信。
%我们确保所有字母以外的贡献
%的种子字母总和为零。
ixWordsFromSeedWord =找到(和((:~ lettersInSeedWord), 2) = = 0);
流(' % d单词只使用七个字母出现在种子词。\ n”元素个数(ixWordsFromSeedWord))
出现最频繁的字母吗?
栏(和((ixWordsFromSeedWord,:)))
集(gca),…
XTick = 1,…
XTickLabel = num2cell (“一个”:“Z”),…
XTickLabelRotation = 0)
我们需要指定一个字母为“中心”的信必须出现在每一个字。让我们选择字母出现的次数最少。
vals =全(和((ixWordsFromSeedWord,:)));
瓦尔斯(vals = = 0) =正;
[~,ixlet] = min (val);
centerLetter = char (ixlet + 96);
删除所有的单词没有这封信
ixRequired =找到((:,ixlet));
ix2a =相交(ixWordsFromSeedWord ixRequired);
这是原始的种子词:
流(“% s \ n”、单词(ix))
这里有七个独特的字母:
sevenLetters =独特(char(话说(ix)));
流(“% s \ n”,sevenLetters);
中心所需的字母是:
流(“% s \ n”上(centerLetter));
这是全字母短句
ix3 =找到(和((ix2a:), 2) = = 7);
为i = 1:元素个数(ix3)
流(“% s \ n”单词(ix2a (ix3(我))));
结束
这是单词的完整列表
为i = 1:元素个数(ix2a)
流(“% s \ n”单词(ix2a(我)));
结束
其中一些是有些奇怪,但我们有字典,谢谢。
sixLetters = setdiff (sevenLetters centerLetter);
sixLetters = sixLetters (randperm (6));
现在的图形!使故事情节
%周长十六进制细胞集中从π/ 6 - 11 * 6π/弧度
t = 2 *π*(0:5)/ 6 + 2 *π/ 12;
r = 1.08 * sqrt (3);
x = r * cos (t);
y = r * sin (t);
班
hexplot(0, 0,上层(centerLetter),“# F7DA21”)
持有在
为i = 1:元素个数(x)
hexplot (x(我),(我),上层(sixLetters(我)),“# E6E6E6”)
结束
持有从
轴平等的
轴从
有你有它!很容易看到有价值的一个好的算法来生成游戏。一旦你的逻辑,你只需要每天运行一次,你的难题是准备好了。比较这个和劳动,进入一种纵横字谜。但谁知道呢?填字游戏也许会是另一个AI是擅长的东西。
函数hexplot (x, y,字母,颜色)
t = linspace(0, 2π,7);
补丁(cost + x,罪(t) + y,“白色”,…
EdgeColor =“没有”,…
FaceColor =颜色)
文本(x, y,信,…
字形大小= 24…
FontWeight =“大胆”,…
HorizontalAlignment =“中心”,…
VerticalAlignment =“中间”)
结束
评论
留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。