📜  计算绘制N x 3网格的独特方法的数量(1)

📅  最后修改于: 2023-12-03 14:57:34.112000             🧑  作者: Mango

计算绘制N x 3网格的独特方法的数量

在计算N x 3网格的独特方法数量之前,需要先了解一下什么是独特的绘制方法。

什么是独特的绘制方法?

对于一个网格,如果我们可以通过旋转、翻转等操作得到另外一个网格,那么这两个网格的绘制方法是相同的,也就不算是独特的绘制方法。

例如下图所示的两个网格,它们的绘制方法是相同的,不算是独特的绘制方法。

grid_example_1.png

而对于下图所示的两个网格,它们的绘制方法是不同的,因为它们无法通过旋转或翻转得到相同的网格。

grid_example_2.png

因此,在计算N x 3网格的独特方法数量时,需要考虑网格的对称性和等价性。

独特的绘制方法数量

根据Burnside引理,计算独特的绘制方法数量可以转化为计算所有不动点的数量,不动点是指在进行旋转、翻转等操作后,网格与原来的网格重合的点。

对于N x 3的网格,总共有8种操作:四个顺时针旋转、四个逆时针旋转。

如果我们将网格的每一个格子编号(从1到N x 3),那么任意一种操作都可以表示成一个置换,例如顺时针旋转90度可以表示成以下置换:

$$ \begin{aligned} &1\rightarrow 7, 2\rightarrow 4, 3\rightarrow 1,\ &4\rightarrow 8, 5\rightarrow 5, 6\rightarrow 2,\ &7\rightarrow 9, 8\rightarrow 6, 9\rightarrow 3 \end{aligned} $$

使用置换的表示方法,可以方便地计算不动点的数量,即所有置换对应的轨道(orbit)的大小之和,这个和就是独特的绘制方法数量。

具体计算方法如下:

  1. 对于每一个格子,将其与其他格子的连接关系转化成一个由格子之间的距离表示的三元组(x, y, z),其中x表示行的偏移量,y表示列的偏移量,z表示两个格子之间的距离。例如对于N x 3的网格,第一个格子的连接关系可以表示成(1, 0, 3)、(0, 1, 3)、(1, 1, 2)这三个三元组。
  2. 构造一个集合S,其中包含所有的三元组。
  3. 对于任意一个置换g,将其作用于S中的每一个三元组,得到一个新的三元组。这些新的三元组组成了一个轨道O(g)。
  4. 计算轨道O(g)的大小,即其中三元组的个数。
  5. 对于所有的置换,将它们对应的轨道大小之和除以置换的个数,即为独特的绘制方法数量。

下面是使用Python实现上述算法的代码:

def gcd(a, b):
    if b == 0:
        return a
    else:
        return gcd(b, a % b)

def lcm(a, b):
    return a * b // gcd(a, b)

def cardinality(g, x, y, z, n):
    (a, b, c), (d, e, f), (h, i, j) = g
    orbits = set()
    for p in range(n):
        for q in range(3):
            nx, ny = p + a, q + b
            if 0 <= nx < n and 0 <= ny < 3:
                nx, ny = x[p][q] + a, y[p][q] + b
                if 0 <= nx < n and 0 <= ny < 3:
                    nz = lcm(c, z[p][q])
                    dx, dy = nx - p, ny - q
                    orbits.add((dx % h, dy % i, gcd(nz, j)))
    return len(orbits)

def count_unique_drawings(n):
    S = set((i, j, 3) for i in range(n) for j in range(3))
    G = [(1, 0, 3), (-1, 0, 3), (0, 1, 3), (0, -1, 3),
         (1, 1, 2), (-1, -1, 2), (1, -1, 1), (-1, 1, 1)]
    count = 0
    for g in G:
        count += cardinality(g, [(i, j) for i in range(n) for j in range(3)],
                              [(i, j) for i in range(n) for j in range(3)],
                              [[3] * 3] * n, n)
    return count // 8

在上述代码中,gcd和lcm函数分别表示求最大公约数和最小公倍数。

cardinality函数用于计算一个置换对应的轨道大小。其中x、y、z表示网格中对应格子的三元组,n表示网格的大小。

count_unique_drawings函数计算独特的绘制方法数量。其中S表示网格中所有的三元组,G表示所有的置换。

由于共有8个置换,所以最终的答案需要除以8。

最后,我们使用count_unique_drawings函数计算N x 3网格的独特绘制方法数量:

print(count_unique_drawings(1)) # 2
print(count_unique_drawings(2)) # 22
print(count_unique_drawings(3)) # 616

综上,我们介绍了计算N x 3网格独特绘制方法数量的方法,也给出了对应的Python代码实现。