这个游戏背后的数学/计算原理是什么?
我的孩子们有这个有趣的游戏叫做Spot It! 游戏约束(我可以描述的最好的)是:
游戏的原理是:翻转两张牌,并且首先挑选匹配图片的人得到一个点。
这是澄清的图片:
(例如:从上面的2张卡片可以看出,匹配的图片是绿色的恐龙,在右下角和中间右侧的图片之间,这是一个小丑的头。)
我试图了解以下内容:
满足这些标准所需的不同图片的最小数量是多少?您如何确定?
使用伪代码(或Ruby),如何从N张图片阵列中生成55张游戏卡(其中N是问题1中的最小数)?
更新:
每张卡片的确出现两次以上的画面(与一些人猜测的相反)。 看到这张3张卡片,每张都有一个闪电:
有限投影几何
投影(平面)几何的公理与欧几里德几何稍有不同:
现在,添加“有限”到汤,你有问题:
我们可以只有2点的几何? 有3分? 用4? 用7?
关于这个问题仍然存在悬而未决的问题,但我们知道这一点:
Q
点的几何,则Q = n^2 + n + 1
并且n
称为几何的order
数。 n+1
个点。 n+1
行。 总行数也是Q
最后,如果n
是素数,那么确实存在n
阶几何。
有人可能会问,这与谜题有什么关系。
把card
而不是point
和picture
而不是line
和公理成为:
现在让我们取n=7
并得到Q = 7^2 + 7 + 1
order-7
有限几何。 这使Q=57
行(图片)和Q=57
点(卡片)。 我猜谜题制作者决定55比57更圆,剩下2张牌。
我们也得到n+1 = 8
,所以从每个点(卡片)开始,8行通过(出现8张图片),每行(图片)有8个点(出现在8张卡片中)。
下面是最着名的有7个点的有限投影(2阶)平面(几何)表示,称为Fano平面 ,从Noelle Evans复制 - 有限几何问题页面
我正在考虑创建一张图片来解释如何将上述2号飞机与7张卡片和7张图片拼成一个类似的拼图,但从math.exchange双胞胎问题中得出的链接恰恰就是这样一张图: Dobble-et- LA-几何学,finie
因此,总共有n张图片的池中有k = 55张包含m = 8张图片的卡片。 我们可以重申“我们需要多少张照片?”,以便我们可以在任意一张卡片之间构建一组只有一张共享图片的k卡片? 相当于问:
给定一个n维向量空间和所有向量的集合,其中包含正好m个元素等于一个,所有其他零,n有多大,以便我们可以找到一组k向量,其成对点积是全部等于1?
精确地(n选择m个)可能的向量来构建对。 所以我们至少需要足够大的n以便(n选择m)> = k。 这只是一个下限,所以为了实现成对兼容性约束,我们可能需要更高的n。
只是为了试验一下,我写了一个小的Haskell程序来计算有效的卡片集:
编辑:我刚看到Neil和Gajet的解决方案后意识到,我使用的算法并不总是找到最好的解决方案,所以下面的一切都不一定有效。 我会尽快更新我的代码。
module Main where
cardCandidates n m = cardCandidates' [] (n-m) m
cardCandidates' buildup 0 0 = [buildup]
cardCandidates' buildup zc oc
| zc>0 && oc>0 = zerorec ++ onerec
| zc>0 = zerorec
| otherwise = onerec
where zerorec = cardCandidates' (0:buildup) (zc-1) oc
onerec = cardCandidates' (1:buildup) zc (oc-1)
dot x y = sum $ zipWith (*) x y
compatible x y = dot x y == 1
compatibleCards = compatibleCards' []
compatibleCards' valid [] = valid
compatibleCards' valid (c:cs)
| all (compatible c) valid = compatibleCards' (c:valid) cs
| otherwise = compatibleCards' valid cs
legalCardSet n m = compatibleCards $ cardCandidates n m
main = mapM_ print [(n, length $ legalCardSet n m) | n<-[m..]]
where m = 8
由此产生的最大数量的兼容卡对于m =每张卡8张图片来说,对于前几个n从n中选择的不同数量的图片看起来像这样:
尽管由于组合爆炸,这个蛮力方法并没有得到很大的进展。 但我认为它可能仍然很有趣。
有趣的是,似乎对于给定的m,k随着n的增加而增加,直到某个n,之后它保持不变。
这意味着,对于每张卡片的每张照片数量,都有一定数量的照片可供选择,从而可以获得最大数量的合法卡片。 添加更多图片以选择过去的最佳数字不会增加合法卡片的数量。
前几个最优k是:
我只是找到了一种方法来处理57或58张照片,但现在我头疼得非常厉害,我会在睡好了8-10个小时后发布红宝石代码! 只是提示我的解决方案,每张7张牌都有相同的标记,总共可以使用我的解决方案构建56张牌。
这里是生成ypercube所谈论的全部57张卡片的代码。 它采用完全相同57图片,对不起家伙的我已经写了实际的C ++代码,但我们知道, vector <something>
是包含的类型值的数组something
很容易理解这个代码的作用。 并且该代码使用每个包含P+1
图片的P^2+P+1
图片并且仅共享1个图片来针对每个素数P值生成P^2+P+1
卡片。 这意味着我们可以使用7张图片,每张图片有3张图片(对于p = 2),13张图片使用13张图片(对于p = 3),31张图片使用31张图片(对于p = 5) (对于p = 7)等等...
#include <iostream>
#include <vector>
using namespace std;
vector <vector<int> > cards;
void createcards(int p)
{
cards.resize(0);
for (int i=0;i<p;i++)
{
cards.resize(cards.size()+1);
for(int j=0;j<p;j++)
{
cards.back().push_back(i*p+j);
}
cards.back().push_back(p*p+1);
}
for (int i=0;i<p;i++)
{
for(int j=0;j<p;j++)
{
cards.resize(cards.size()+1);
for(int k=0;k<p;k++)
{
cards.back().push_back(k*p+(j+i*k)%p);
}
cards.back().push_back(p*p+2+i);
}
}
cards.resize(cards.size()+1);
for (int i=0;i<p+1;i++)
cards.back().push_back(p*p+1+i);
}
void checkCards()
{
cout << "---------------------n";
for(unsigned i=0;i<cards.size();i++)
{
for(unsigned j=0;j<cards[i].size();j++)
{
printf("%3d",cards[i][j]);
}
cout << "n";
}
cout << "---------------------n";
for(unsigned i=0;i<cards.size();i++)
{
for(unsigned j=i+1;j<cards.size();j++)
{
int sim = 0;
for(unsigned k=0;k<cards[i].size();k++)
for(unsigned l=0;l<cards[j].size();l++)
if (cards[i][k] == cards[j][l])
sim ++;
if (sim != 1)
cout << "there is a problem between cards : " << i << " " << j << "n";
}
}
}
int main()
{
int p;
for(cin >> p; p!=0;cin>> p)
{
createcards(p);
checkCards();
}
}
再次抱歉延迟的代码。
链接地址: http://www.djcxy.com/p/6835.html上一篇: What are the mathematical/computational principles behind this game?