I would like to populate an n * n
(n being odd) matrix in the following way:
_ _ _ 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 _ _ _
What is an easy way to do this using Mathematica?
With this helper function:
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];
We can construct the matrix as
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]]]];
To get the matrix you described, use
constructMatrix[7] // MatrixForm
The idea behind this is to examine the pattern that the positions of consecutive numbers 1.. follow. You can see that these form the cycles. The zeroth cycle is trivial - contains a number 1 at position {0,0}
(if we count positions from the center). The next cycle is formed by taking the first number (2) at position {1,-1}
and adding to it one by one the following steps: {0, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 0}
(as we move around the center). The second cycle is similar, but we have to start with {2,-2}
, repeat each of the previous steps twice, and add the sixth step (going up), repeated only once: {0, -1}
. The third cycle is analogous: start with {3,-3}
, repeat all the steps 3 times, except {0,-1}
which is repeated only twice. The auxiliary function makeSteps
automates the process. In the main function then, we have to collect all positions together, and then add to them {cycles, cycles}
since they were counted from the center, which has a position {cycles,cycles}
. Finally, we construct the SparseArray
out of these positions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With