Imagine we have the following 5x5 matrix populated with integers between 1 and 3. The 1s are across the diagonals. The 2s are "second diagonal" close to the 1s. The 3s are also diagonal but the matrix is too small to see it properly.
1, 2, 3, 2, 1
2, 1, 2, 1, 2
3, 2, 1, 2, 3
2, 1, 2, 1, 2
1, 2, 3, 2, 1
What simple algorithm can generate this odd square matrix in 5x5 or NxN where N is odd?
7x7 would have integers up to 4.
This is not homework.
CodePudding user response:
Diagonals in a matrix can be defined with equations similar to the equation of a line in the plane. You know that a line in the plane, if it's not vertical, can be expressed by an equation of the form y = a * x b
.
Similarly, a diagonal in a matrix consists in the cells (i,j)
that satisfy an equation i = a * j b
.
Furthermore, a
is the directing coefficient of the line, and in the case of a diagonal, which is a line with angle 45°, a
has got to be 1 or -1.
Now you just need to identify the value of parameter b
for each diagonal.
For the main first diagonal (upperleft-bottomright), the equation is
i = j
; the parameters area = 1
andb = i - j = 0
.For the reversed first diagonal (bottomleft-upperright), the equation is
i = N - j - 1
; the parameters area = -1
andb = i j = N - 1
.
If two diagonals are adjacent, then the b
parameters for these two diagonals must differ by exactly 1. So for instance, the second diagonals will have b
in {-1, 1, N, N-2}
; the third diagonals will have b
in {-2, 2, N 1, N-3}
, etc.
Every cell is at the intersection of two diagonals. Since b
can always be computed as i-j
for the upperleft-bottomright diagonals, and i j
for the bottomleft-upperright
diagonals, we can easily find which two diagonals we are on by computing i-j
and i j
. Then, since you want to populate the cell with a number corresponding to the diagonal closest to center, use min
to choose which of the two diagonals is relevant.
We get the following algorithm:
for (i = 0; i < N; i )
for (j = 0; j < N; j )
M(i,j) = min(abs(i-j), abs(i j - (N-1))) 1
Illustration in python3:
def f(i,j, N):
return min(abs(i-j), abs(i j - (N-1))) 1
def M(N):
return [[f(i,j,N) for j in range(N)] for i in range(N)]
print(M(3))
#[[1, 2, 1],
# [2, 1, 2],
# [1, 2, 1]]
print(M(7))
#[[1, 2, 3, 4, 3, 2, 1],
# [2, 1, 2, 3, 2, 1, 2],
# [3, 2, 1, 2, 1, 2, 3],
# [4, 3, 2, 1, 2, 3, 4],
# [3, 2, 1, 2, 1, 2, 3],
# [2, 1, 2, 3, 2, 1, 2],
# [1, 2, 3, 4, 3, 2, 1]]
CodePudding user response:
OK, got it this time...
Try this:
CellValue[x,y] = MIN(ABS(x-y), ABS(N-(x y) 1)) 1
This is assuming a ones-based matrix. If you are using a zero-based array. then you would have to adjust it
CellValue[x,y] = MIN(ABS(x-y), ABS(N-(x y)-1)) 1