填充此矩阵的简便方法?

Mr.*_*ard 7 wolfram-mathematica matrix fill

我想以n * n下列方式填充(n为奇数)矩阵:

_   _   _   23  22  21  20
_   _   24  10  9   8   37
_   25  11  3   2   19  36
26  12  4   1   7   18  35
27  13  5   6   17  34  _
28  14  15  16  33  _   _
29  30  31  32  _   _   _
Run Code Online (Sandbox Code Playgroud)

使用Mathematica的简单方法是什么?

Leo*_*rin 12

有了这个辅助函数:

Clear[makeSteps];
makeSteps[0] = {};
makeSteps[m_Integer?Positive] :=
  Most@Flatten[
    Table[#, {m}] & /@ {{-1, 0}, {-1, 1}, {0, 1}, {1, 0}, {1, -1}, {0, -1}}, 1];
Run Code Online (Sandbox Code Playgroud)

我们可以将矩阵构造为

constructMatrix[n_Integer?OddQ] :=
  Module[{cycles, positions},
    cycles = (n+1)/2;
    positions = 
       Flatten[FoldList[Plus, cycles + {#, -#}, makeSteps[#]] & /@ 
           Range[0, cycles - 1], 1];
    SparseArray[Reverse[positions, {2}] -> Range[Length[positions]]]];
Run Code Online (Sandbox Code Playgroud)

要获得您描述的矩阵,请使用

constructMatrix[7] // MatrixForm
Run Code Online (Sandbox Code Playgroud)

这背后的想法是检查连续数字1的位置遵循的模式.你可以看到这些形成了循环.第0个循环是微不足道的 - 在位置包含1号{0,0}(如果我们从中心计算位置).下一个循环是通过将第一个数字(2)置于位置{1,-1}并逐步增加以下步骤形成的{0, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 0}(当我们围绕中心移动时).第二个周期是类似的,但我们必须从头开始{2,-2},重复前面的每个步骤两次,并添加第六步(向上),重复一次:{0, -1}.第三个循环是类似的:从开始{3,-3},重复所有步骤3次,除了{0,-1}重复仅两次.辅助功能makeSteps使过程自动化.在主要功能中,我们必须一起收集所有位置,然后添加到它们,{cycles, cycles}因为它们是从具有位置的中心计算的{cycles,cycles}.最后,我们构建SparseArray了这些位置.


Pet*_*erT 8

我不知道Mathematica语法,但我想你可以使用这样的算法:

start in the middle of the matrix
enter a 1 into the middle
go up-right (y-1 / x+1)
set integer iter=1
set integer num=2
while cursor is in matrix repeat:
   enter num in current field 
   increase num by 1
   repeat iter times:
       go left (x-1 / y)
       enter num in current field 
       increase num by 1
   repeat iter times:
       go down-left (x-1 / y+1)
       enter num in current field 
       increase num by 1
   repeat iter times:
       go down (x / y+1)
       enter num in current field 
       increase num by 1
   repeat iter times:
       go right (x+1 / y)
       enter num in current field 
       increase num by 1
   repeat iter times:
       go up-right (x+1 / y-1)
       enter num in current field 
       increase num by 1
   repeat iter-1 times:
       go up (x / y-1)
       enter num in current field 
       increase num by 1
   go up-up-right (y-2 / x+1)
   increase iter by 1
Run Code Online (Sandbox Code Playgroud)

您也可以很容易地将此​​算法转换为功能版本或尾递归.

好吧,如果你没有出界,你必须检查while循环.如果n是奇数,那么你可以只计算num up:

m = floor(n/2)
num <= n*n - (m+m*m)
Run Code Online (Sandbox Code Playgroud)

我很确定有一个更简单的算法,但对我来说这是最直观的算法.