定义如下时如何生成正六边形序列?

How to generate regular hexagon sequence when it is defined as follow?

正六边形序列定义如下

  1. 最高的六边形是1。
  2. 下一个六边形在前一个六边形的顺时针方向上。
  3. 如果下一个六边形已经有编号,则内部最高六边形被编号。
  4. 序列是从左上到右下读取所有六边形生成的。 例如,序列是 当n=1时, 1个 当n=2时, 1-6-2-7-5-3-4 当n=3时, 1-12-2-11-13-3-18-14-10-19-4-17-15-9-16-5-8-6-7

如何生成n的正六边形序列?

我使用了一些观察结果:

  1. 注意所需的行数是 4 * n - 3
  2. 请注意,要表示一行,我们需要 2 个向量:
  • 如果我们在六边形的右边,我们就追加到那个数组的前面
  • 如果我们在六边形的左侧,我们追加到该数组的右侧
  1. 注意,如果我们在六边形的右侧,我们需要向下跳一行,如果我们在左侧,我们需要向上跳一行
  2. 请注意,如果我们在六边形的垂直边缘(左侧或右侧),我们需要跳 2 行:左侧垂直向上跳 2 行,右侧垂直向下跳 2 行
from collections import deque

def hexagon_pattern(n):
    if n == 1:
        return [1]

    # Denotes how many rows we need
    n_rows = 4 * n - 3
    
    # Create a row as a tuple of left half and right half
    # This is done as if we are in the right half of the
    # hexagon, we append to the left, otherwise we append to
    # the right
    rows = [(deque([]), deque([])) for i in range(n_rows)]
    
    # Denotes the dimension of a line (how many numbers)
    # we push to a line
    # Obs: this starts from n - 1 and continues to 0
    # If this is 0, it means we have to fill in only the number
    # in the center of the hexagon
    line_dim = n - 1
    
    # Denotes the number that needed to be introduced in the pattern
    crt_num = 1
    
    # Start row to the current hexagon
    # Obs: the start row of next hexagon is at a distance of 2
    # from the previous start row of the previous hexagon
    start_row = 0
    
    # We have n hexagon patterns to fill in
    while n:
        # Every hexagon pattern start at a different row
        crt_row = start_row
        
        # Indicator that we are at the middle number
        if line_dim == 0:
            rows[crt_row][0].append(crt_num)
            break

        # For every level we have a hexagon
        for line_no in range(6):
            # We have to fill in the hexagon edge
            for _ in range(line_dim):
                if crt_row >= n_rows:
                    continue
                
                if line_no < 3:
                    # We are on the right part of a hexagon (first 3 edges)
                    rows[crt_row][1].appendleft(crt_num)
                else:
                    # We are on the left part of a hexagon (last 3 edges)
                    rows[crt_row][0].append(crt_num)
                
                # Increment the number to be added in pattern
                crt_num += 1
                
                # If we are on the right vertical line of the hexagon, then we jump 2 lines down
                if line_no == 1:
                    crt_row += 2
                # If we are on the left vertical line of the hexagon, then we jump 2 lines up
                elif line_no == 4:
                    crt_row -= 2
                # If we are on the right side of the hexagon we jump one line down
                elif line_no < 3:
                    crt_row += 1
                # If we are on the left side of the hexagon we jump one line up
                else:
                    crt_row -= 1
        
        n -= 1
        line_dim -= 1
        start_row += 2
    
    # We concatenate the two halves of every row
    # After that, we concatanate all the sublists in a single list
    result = sum(list(filter(lambda l: l, map(lambda t: list(t[0] + t[1]), rows))), [])
    
    return result
            
if __name__ == '__main__':
    print(hexagon_pattern(1))
    print(hexagon_pattern(2))
    print(hexagon_pattern(3))