SirOsric
SirOsric

Reputation: 189

Creating a matrix of increasing concentric rings of numbers in R

I need to write a function in R that creates a matrix of increasing concentric rings of numbers. This function's argument is a number of layers. For example, if x = 3, matrix will look like following:

1 1 1 1 1  
1 2 2 2 1  
1 2 3 2 1  
1 2 2 2 1  
1 1 1 1 1

I have no idea how to do it. I would really appreciate any suggestions.

Upvotes: 8

Views: 594

Answers (4)

Nikhil Vandanapu
Nikhil Vandanapu

Reputation: 529

Here's the logic, implement it yourself in R.

  • Create a matrix with number of rows and columns equal to 2*x-1 and fill it with zeros and start traversing the array from (0,0) to (2*x-2,2*x-2).
  • Now, at each cell, calculate the 'level' of the cell. The level of the cell is the nearest distance of it from the four borders of the matrix, i.e. min(i,j,2*x-2-i,2*x-2-j).
  • This 'level' value is the one to be put in the cell.

Upvotes: 1

G. Grothendieck
G. Grothendieck

Reputation: 269556

1) Try this:

x <- 3 # input

n <- 2*x-1
m <- diag(n)
x - pmax(abs(row(m) - x), abs(col(m) - x))

giving:

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]    1    2    2    2    1
[3,]    1    2    3    2    1
[4,]    1    2    2    2    1
[5,]    1    1    1    1    1

2) A second approach is:

x <- 3 # input

n <- 2*x-1
mid <- pmin(1:n, n:1)  # middle row/column
outer(mid, mid, pmin)

giving the same result as before.

3) yet another approach having some similarities to the prior two approaches is:

x <- 3 # input

n <- 2*x-1
Dist <- abs(seq_len(n) - x)
x - outer(Dist, Dist, pmax)

Note: The above gives the sample matrix shown in the question but the subject of the question says the rings should be increasing which may mean increasing from the center to the outside so if that is what is wanted then try this where m, mid and Dist are as before:

pmax(abs(row(m) - x), abs(col(m) - x)) + 1

or

x - outer(mid, mid, pmin) + 1

or

outer(Dist, Dist, pmax) + 1

Any of these give:

     [,1] [,2] [,3] [,4] [,5]
[1,]    3    3    3    3    3
[2,]    3    2    2    2    3
[3,]    3    2    1    2    3
[4,]    3    2    2    2    3
[5,]    3    3    3    3    3

Upvotes: 20

Rorschach
Rorschach

Reputation: 32426

A recursive solution for kicks (odd n only)

f <- function(n) if (n == 1) 1 else `[<-`(matrix(1,n,n), 2:(n-1), 2:(n-1), 1+Recall(n-2))

f(5)

#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    1    1    1    1
# [2,]    1    2    2    2    1
# [3,]    1    2    3    2    1
# [4,]    1    2    2    2    1
# [5,]    1    1    1    1    1

Upvotes: 4

nicola
nicola

Reputation: 24480

Try this:

x<-3
res<-matrix(nrow=2*x-1,ncol=2*x-1)
for (i in 1:x) res[i:(2*x-i),i:(2*x-i)]<-i
res
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    1    1    1    1
#[2,]    1    2    2    2    1
#[3,]    1    2    3    2    1
#[4,]    1    2    2    2    1
#[5,]    1    1    1    1    1

Upvotes: 7

Related Questions