lomuto求第k小元素 python_用Python解数独[2]:求列值域和九宫格值域

aec9eecc539c604959d6b2bf98eedcfa.png

目录

  1. 用Python解数独[0]
  2. 用Python解数独[1]:求每个单元格的行值域
  3. 用Python解数独[2]:求列值域和九宫格值域
  4. 用Python解数独[3]:求总值域
  5. 用Python解数独[4]:缩减值域
  6. 用Python解数独[5]:检测唯一值缩减值域
  7. 用Python解数独[6]:递归获得最终答案
  8. 用Python解数独[7]:递归(完结篇)

[2][1] 解决数独问题基本思路

2、求每个单元格的列值域

上回书说到,行值域已经得到,求列值域和九宫格值域的方法和行值域应该是一样的,但问题在于,如何表达列和九宫格,或者说如何用代码把数独里的每一列、每一个九宫格表达出来。

soduku 

有一种很笨的方法:

第1列是由每一行的第1个元素组成的,用代码表示就是

soduku_col 

第n列就是由每一行的第n个元素组成的,我们把上面的代码重复执行9遍就行了:

soduku_col 

将代码整理为函数:

def 

当然其实Python有一个现成的函数——zip(),就是做这件事情的,代码可以修改

soduku_col 

我们看到zip函数里的参数是"*soduku",这个用法大家可以自行查询下,等价于下面这种写法:

soduku_col 
如果参数是"soduku",相当于输入的参数是soduku,参数数量是1个; 如果参数是"*soduku",相当于将列表soduku中的每一个元素当作参数,参数数量就是9个;

求列值域,有以下几步:

  • 根据当前数独数组,通过zip函数得到由每一列组成的新数独数组;
  • 根据rowValueRange(行值域函数),求新数独数组的“行值域”;
  • 通过zip函数将得到的“行值域数组”进行一次行列转换,从而得到原数独数组的列值域;
def 

3、求每个单元格的九宫格值域

我们用了列值域的处理经验,求九宫格值域的关键就是这个“九宫格转换函数”,如果把一个数独数组,转化为数独九宫格数组,这个问题看起来有点难,我们先回顾一下数独

424e75c8337a38d2c533ef737a14067c.png

如果表示第一个九宫格,它由前三行的前三个元素组成,如果用代码表示可以这样写:

soduku_matrix 

如果我们愿意,我们可以用类似的方法得到剩余8个九宫格,但这样的代码好像有些粗暴,有更好的方法吗?我们观察数独棋盘,我们发现九宫格是以3为单位的:

第一个九宫格:前三行的前三个元素;
第二个九宫格:前三行的中间三个元素;
第三个九宫格:前三行的后三个元素;
......

我们可以加入整除操作:

soduku_matrix 

那么如何建立k , l 与九宫格下标的关系呢:

k = 0, l = 0 ,下标 m = 0
k = 0, l = 1 ,下标 m = 1
k = 0, l = 2 ,下标 m = 2
k = 1, l = 0 ,下标 m = 3
k = 1, l = 1 ,下标 m = 4
k = 1, l = 2 ,下标 m = 5
k = 2, l = 0 ,下标 m = 6
k = 2, l = 1 ,下标 m = 7
k = 2, l = 2 ,下标 m = 8

m与k , l应该是一种线性关系,因此列方程:m = ak + bl,得到 m = 3k + l

所以代码可以改为:

soduku_matrix 

我们整理出九宫格转换函数和九宫格值域函数:

def 
数独数组a通过九宫格转化为数独数组b,然后数独数组b通过九宫格转化,可以再转化为数独数组a。这个大家可以自己观察数独棋盘体会一下。

现在我们已经获得了一个单元格的行值域、列值域和九宫格值域,可以考虑通过三个值域来获得这个单元格的总值域了。这个问题可以抽象为有lista , listb和listc,求三个列表的交集。

下面我们的项目代码将变得越来越复杂,但其实并没有引入其它复杂的概念,依然是循环、条件判断和列表相关方法,预知后事如何,且听下回分解!


下一篇链接:用Python解数独[3]:求总值域

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值