max_x=5
len=max_x^2
middle=ceiling(max_x/2)
A=matrix(NA,max_x,max_x)
increments=Reduce(
f=function(lhs,rhs) c(lhs,(-1)^(rhs/2+1)*rep(1,rhs)),
x=2*(1:(max_x)),
init=0
)[1:len]
idx_x=Reduce(
f=function(lhs,rhs) c(lhs,rep(c(TRUE,FALSE),each=rhs)),
1:max_x,
init=FALSE
)[1:len]
increments_x=increments
increments_y=increments
increments_x[!idx_x]=0
increments_y[idx_x]=0
A[(middle+cumsum(increments_x)-1)*(max_x)+middle+cumsum(increments_y)]=1:(max_x^2)
Дает
#> A
# [,1] [,2] [,3] [,4] [,5]
#[1,] 21 22 23 24 25
#[2,] 20 7 8 9 10
#[3,] 19 6 1 2 11
#[4,] 18 5 4 3 12
#[5,] 17 16 15 14 13
Пояснение: Вектор increments
обозначает шаги по пути все большего числа. Это либо 0/+1/-1
для неизмененных/увеличения/уменьшения индексов строк и столбцов. Важно отметить, что эти числа не различают шаги по столбцам и строкам. Это управляется вектором idx_x
- он маскирует приращения, которые либо вдоль строки (TRUE
), либо столбец (FALSE
). В последней строке учитывается логика индексирования R (индекс матрицы увеличивается вдоль столбцов).
Edit: По просьбе О.П., здесь несколько больше информации о том, как рассчитывается increments
вектор.
Вы всегда проходите две последовательные прямые линии равной длины (по ряду или по столбцам). Длина, однако, увеличивается на 1 после того, как вы дважды ходили. Это соответствует аргументу x=2*(1:(max_x))
вместе с rep(1,rhs)
. Первые два последовательных шага находятся в увеличении направления столбцов/строк. Затем следуйте по двум направлениям в отрицательном направлении и так далее (чередуя). Это объясняется (-1)^(rhs/2+1)
.
Предлагаю сначала принять некоторые ответы на ваши предыдущие вопросы. – Julius