画阿基米德螺线

问题描述 投票:0回答:1

该函数接受奇数

n
并返回一个像这样的矩阵(对于 n=5)

[
[17, 16, 15, 14, 13],
[18, 5, 4, 3, 12],
[19, 6, 1, 2, 11],
[20, 7, 8, 9, 10],
[21, 22, 23, 24, 25]]

那么,

(1) 中心方块填满 1。

(2) 如果壳已填满 - 向右走。

(3) 如果您开始填充新壳 - 逆时针旋转。

编写此代码的正确方法是什么?我可以计算贝壳的大小

(n**2)-(n-2)**2
,但我没有看到一个简单的方法。

python-3.x algorithm matrix
1个回答
0
投票

解决了。这个解决方案有缺陷。例如,魔法操作

self.counter -= 2
就没有什么意义。无论如何,这就是解决方案。

import numpy as np


class Layer:
    def __init__(self, layer, matrix_size):
        self.layer_id = layer
        self.size = matrix_size
        self.step = 0
        self.last_h, self.last_w = self.size//2, self.size//2 + self.layer_id
        self.is_layer_ended = False

    def get_next_pos(self):
        if self.step == 0:
            pass
        elif self.step <= self.layer_id:
            self.last_h -= 1
        elif self.step <= self.layer_id * 3:
            self.last_w -= 1
        elif self.step <= self.layer_id * 5:
            self.last_h += 1
        elif self.step <= self.layer_id * 7:
            self.last_w += 1
        elif self.step < 8 * self.layer_id:
            self.last_h -= 1
        else:
            self.is_layer_ended = True
            self.last_w += 1
            self.last_h += 1
        self.step += 1


class Spiral:
    def __init__(self, matrix_size):
        self.size = matrix_size
        self.layer = Layer(1, 2)
        self.layer_count = 1
        self.max_layer = matrix_size//2
        self.counter = 1
        self.arr = np.zeros((self.size, self.size)).astype(np.int32)
        self.populate_inner()
        self.is_next_layer = True

    def compute_spiral(self):
        while self.layer_count <= self.max_layer:
            self.counter += 1
            self.process_next()
            # print(self.arr, '\n---\n')
        return self.arr

    def populate_inner(self):
        x = self.size//2
        self.arr[x, x] = self.counter
        self.layer = Layer(1, self.size)

    def process_next(self):
        if self.layer.is_layer_ended:
            self.goto_next_layer()
        else:
            self.keep_populating()

    def goto_next_layer(self):
        self.layer_count += 1
        self.counter -= 2
        self.layer = Layer(self.layer_count, self.size)
        if self.counter >= self.size**2:
            pass
        else:
            self.arr[self.layer.last_h, self.layer.last_w] = self.counter

    def keep_populating(self):
        self.layer.get_next_pos()
        if self.counter >= self.size**2+1:
            pass
        else:
            self.arr[self.layer.last_h, self.layer.last_w] = self.counter


sp = Spiral(7)
res = sp.compute_spiral()
print(res)
© www.soinside.com 2019 - 2024. All rights reserved.