Numpy 数独游戏中的跨度技巧

NumPy的ndarray类中有一个跨度(strides)属性域,实现为一个元组。在遍历数组时,用跨度来指明每一个维度上的步进值是多少字节。我们将巧妙运用跨度技巧,把数独谜题划分为3×3的九宫格形式。
对数独游戏规则的解释超出了本章的范围,请访问 http://en.wikipedia.org/wiki/Sudoku 获取更多相关信息。

具体步骤

  1. 定义数独谜题数组。

首先定义数独谜题数组,其内容就是一个真实的、已经解开的数独谜题。

sudoku = numpy.array([
    [2, 8, 7, 1, 6, 5, 9, 4, 3],
    [9, 5, 4, 7, 3, 2, 1, 6, 8],
    [6, 1, 3, 8, 4, 9, 7, 5, 2],
    [8, 7, 9, 6, 5, 1, 2, 3, 4],
    [4, 2, 1, 3, 9, 8, 6, 7, 5],
    [3, 6, 5, 4, 2, 7, 8, 9, 1],
    [1, 9, 8, 5, 7, 3, 4, 2, 6],
    [5, 4, 2, 9, 1, 6, 3, 8, 7],
    [7, 3, 6, 2, 8, 4, 5, 1, 9]
    ])  
  1. 计算跨度。

ndarray类的itemsize域指明数组中每个元素所占用的字节数。利用itemsize来计算跨度:

strides = sudoku.itemsize *  
    numpy.array([27, 3, 9, 1])
  1. 划分九宫格。

用numpy.lib.stride_tricks模块中的as_strided函数,把谜题数组划分为九宫格的形式:

squares = numpy.lib.stride_tricks.as_strided 
    (sudoku, shape=shape, strides=strides)
print(squares)

这样就能把各个宫格分别打印出来。

[[[[2 8 7]
    [9 5 4]
    [6 1 3]]

    [[1 6 5]
     [7 3 2]
     [8 4 9]]

    [[9 4 3]
     [1 6 8]
     [7 5 2]]]

    [[[8 7 9]
     [4 2 1]
     [3 6 5]]

    [[6 5 1]
     [3 9 8]
     [4 2 7]]

    [[2 3 4]
     [6 7 5]
     [8 9 1]]]

    [[[1 9 8]
     [5 4 2]
     [7 3 6]] 

    [[5 7 3]
     [9 1 6]
     [2 8 4]]

    [[4 2 6]
     [3 8 7]
     [5 1 9]]]]  

本攻略的完整代码如下:

import numpy

sudoku = numpy.array([
    [2, 8, 7, 1, 6, 5, 9, 4, 3],
    [9, 5, 4, 7, 3, 2, 1, 6, 8],
    [6, 1, 3, 8, 4, 9, 7, 5, 2],
    [8, 7, 9, 6, 5, 1, 2, 3, 4],
    [4, 2, 1, 3, 9, 8, 6, 7, 5],
    [3, 6, 5, 4, 2, 7, 8, 9, 1],
    [1, 9, 8, 5, 7, 3, 4, 2, 6],
    [5, 4, 2, 9, 1, 6, 3, 8, 7],
    [7, 3, 6, 2, 8, 4, 5, 1, 9]
    ])

shape = (3, 3, 3, 3)

strides = sudoku.itemsize * numpy.array([27, 3, 9, 1])

squares = numpy.lib.stride_tricks.as_strided
    (sudoku, shape=shape, strides=strides)
print(squares)

攻略小结

我们应用跨度技巧,把数独谜题划分为3×3的九宫格形式。跨度告诉我们,在遍历数独数组时,每一步需要跳过多少字节。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程