前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >九宫格数独游戏

九宫格数独游戏

作者头像
WolframChina
发布2018-05-31 10:42:41
1.1K0
发布2018-05-31 10:42:41
举报
文章被收录于专栏:WOLFRAMWOLFRAM

数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据 9x9 盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫 (3x3) 内的数字均含1 - 9,不重复。

数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1 - 9 的数字。使1 - 9 每个数字在每一行、每一列和每一宫中都只出现一次,所以又称 "九宫格"。

这种九宫格游戏全面考验做题者观察能力和推理能力,虽然玩法简单,但数字排列方式却千变万化,很多人认为数独游戏是训练头脑的绝佳方式。2013年在北京还举办过第八届世界数独锦标赛。由国内的世智联授权组织每年还举办一次中国数独锦标赛。

上面文字摘自网络,下面是 Kampas 老先生教你如何设计九宫格数独游戏。整个笔记本可以去 Wolfram 社区下载(http://community.wolfram.com/groups/-/m/t/974303)。

给出数值,形式为 {row, column, value}:

代码语言:javascript
复制
In[1]:= input = {{1, 4, 4}, {1, 5, 9}, {1, 8, 5}, {2, 1, 6}, {2, 5, 3}, {3, 1, 4}, {3,
     2, 5}, {3, 4, 6}, {3, 5, 2}, {3, 7, 3}, {3, 9, 7}, {4, 1, 5}, {4, 3, 
    2}, {4, 4, 7}, {4, 7, 9}, {4, 8, 8}, {5, 1, 3}, {5, 3, 6}, {5, 7, 2}, {5, 
    9, 1}, {6, 2, 9}, {6, 3, 1}, {6, 6, 2}, {6, 7, 6}, {6, 9, 5}, {7, 1, 
    2}, {7, 3, 5}, {7, 5, 1}, {7, 6, 4}, {7, 8, 3}, {7, 9, 8}, {8, 5, 8}, {8, 
    9, 9}, {9, 2, 1}, {9, 5, 7}, {9, 6, 3}};

显示给定数值:

代码语言:javascript
复制
In[2]:= viewmat = Table["", {9}, {9}];

In[3]:= Do[viewmat[[input[[i, 1]], input[[i, 2]]]] = ToString[input[[i, 3]]], {i, 
  Length[input]}];

In[4]:= Grid[viewmat, Frame -> All]

变量为 9 x 9 x 9 的矩阵:

代码语言:javascript
复制
In[5]:= varmat = Table[m[i, j, k], {i, 9}, {j, 9}, {k, 9}];

用列表给出变量:

代码语言:javascript
复制
In[6]:= vars = Flatten[varmat];

限制输入单元的值为给定值:

代码语言:javascript
复制
In[7]:= cons1 = (varmat[[Sequence @@ #]] == 1 &) /@ input
 
Out[7]= {m[1, 4, 4] == 1, m[1, 5, 9] == 1, m[1, 8, 5] == 1, m[2, 1, 6] == 1, 
 m[2, 5, 3] == 1, m[3, 1, 4] == 1, m[3, 2, 5] == 1, m[3, 4, 6] == 1, 
 m[3, 5, 2] == 1, m[3, 7, 3] == 1, m[3, 9, 7] == 1, m[4, 1, 5] == 1, 
 m[4, 3, 2] == 1, m[4, 4, 7] == 1, m[4, 7, 9] == 1, m[4, 8, 8] == 1, 
 m[5, 1, 3] == 1, m[5, 3, 6] == 1, m[5, 7, 2] == 1, m[5, 9, 1] == 1, 
 m[6, 2, 9] == 1, m[6, 3, 1] == 1, m[6, 6, 2] == 1, m[6, 7, 6] == 1, 
 m[6, 9, 5] == 1, m[7, 1, 2] == 1, m[7, 3, 5] == 1, m[7, 5, 1] == 1, 
 m[7, 6, 4] == 1, m[7, 8, 3] == 1, m[7, 9, 8] == 1, m[8, 5, 8] == 1, 
 m[8, 9, 9] == 1, m[9, 2, 1] == 1, m[9, 5, 7] == 1, m[9, 6, 3] == 1}

每个单元的二进制变量的和为 1:

代码语言:javascript
复制
In[8]:= cons2 = Flatten @ 
   Table[ (Sum[varmat[[i, j, k]], {k, 9}] == 1), {i, 9}, {j, 9}];

行的不同限制:

代码语言:javascript
复制
In[9]:= cons3 = Flatten @ 
   Table[ (Sum[varmat[[i, j, k]], {i, 9}] == 1), {j, 9}, {k, 9}];

列的不同限制:

代码语言:javascript
复制
In[10]:= cons4 = Flatten @ 
   Table[ (Sum[varmat[[i, j, k]], {j, 9}] == 1), {i, 9}, {k, 9}];

子矩阵的不同限制:

代码语言:javascript
复制
In[11]:= sm[di_, dj_] := 
 Flatten [Table[{i, j}, {i, 1 + 3*(di - 1), 3*di}, {j, 1 + 3*(dj - 1), 3*dj}],1]

In[12]:= cons5 = Flatten @ 
   Table[(Total[m[Sequence @@ #, k] & /@ sm[i, j]] == 1), {i, 3}, {j, 3}, {k, 9}];

把变量的范围限定在 0 到 1 之间:

代码语言:javascript
复制
In[13]:= cons6 = Thread[0 <= vars <= 1];

对限制进行组合:

代码语言:javascript
复制
In[14]:= Length[allcons = Join[cons1, cons2, cons3, cons4, cons5, cons6]]

Out[14]= 1089

对问题进行求解,指定变量为整数:

代码语言:javascript
复制
In[15]:= AbsoluteTiming[
 sol = FindMinimum[{0, allcons, Element[vars, Integers]}, vars];]

Out[15]= {0.342467, Null}

求每个单元的值:

代码语言:javascript
复制
In[16]:= resmat = Table[Sum[k*m[i, j, k], {k, 9}], {i, 9}, {j, 9}] /. sol[[2]]

Out[16]= {{1, 2, 3, 4, 9, 7, 8, 5, 6}, {6, 8, 7, 1, 3, 5, 4, 9, 2}, {4, 5, 9, 6, 2, 8, 
  3, 1, 7}, {5, 4, 2, 7, 6, 1, 9, 8, 3}, {3, 7, 6, 8, 5, 9, 2, 4, 1}, {8, 9, 
  1, 3, 4, 2, 6, 7, 5}, {2, 6, 5, 9, 1, 4, 7, 3, 8}, {7, 3, 4, 5, 8, 6, 1, 2, 
  9}, {9, 1, 8, 2, 7, 3, 5, 6, 4}}

显示输入和结果:

代码语言:javascript
复制
In[17]:= {Grid[viewmat, Frame -> All], Grid[resmat, Frame -> All]}

检查结果:

代码语言:javascript
复制
In[18]:= And @@ Table[Unequal[Sequence @@ resmat[[i]]], {i, 9}]

Out[18]= True

In[19]:= And @@ Table[Unequal[Sequence @@ Transpose[resmat][[i]]], {i, 9}]

Out[19]= True

In[20]:= And @@ Flatten @ 
  Table[Unequal[resmat[[Sequence @@ #]] & /@ sm[i, j]], {i, 3}, {j, 3}]

Out[20]= True

在 Wolfram 演示项目中还可以直接下载九宫格数独游戏(http://demonstrations.wolfram.com/SudokuGame/),装上 CDF Player(http://www.wolfram.com/cdf-player/), 小朋友就可以直接玩了。有 60 种不同的难度供你选择噢。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WOLFRAM 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档