Identify all elements adjacent to a 1 in a binary matrix - r

I'm trying to create a function where at every time step in a matrix, the cells adjacent and diagonal to a 1 become 1 as well.
For example, something like this:
Input
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Output after first time step
1 1 1 0 0
1 1 1 0 0
1 1 1 0 0
0 0 0 0 0
0 0 0 0 0
So far, I have this:
A = matrix(0,nrow=5,ncol=5)
A[2,2]=1
for (i in 1:5){
for (j in 1:5){
if ((A[i,j]==1)) {
A[,(j+1)]=1
A[,(j-1)]=1
A[(i+1),]=1
A[(i-1),]=1
A[(i+1),(j+1)]=1
A[(i+1),(j-1)]=1
A[(i-1),(j+1)]=1
A[(i-1),(j-1)]=1
}
}
}
I'm not too sure how to integrate a function in there, so I can have the resulting matrix for whatever time step I want.

You could determine if a bit is set either in the matrix or the matrix when it is shifted in any of the 8 legitimate directions (right, left, up, down, up-right, down-right, down-left, up-left):
spread <- function(X) unname(X |
rbind(F, head(X, -1)) |
rbind(tail(X, -1), F) |
cbind(F, X[,-ncol(X)]) |
cbind(X[,-1], F) |
cbind(F, rbind(F, head(X, -1))[,-ncol(X)]) |
cbind(rbind(F, head(X, -1))[,-1], F) |
cbind(F, rbind(tail(X, -1), F)[,-ncol(X)]) |
cbind(rbind(tail(X, -1), F)[,-1], F)) * 1
X <- matrix(rep(c(0, 1, 0), c(6, 1, 18)), nrow=5)
spread(X)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 0 0
# [2,] 1 1 1 0 0
# [3,] 1 1 1 0 0
# [4,] 0 0 0 0 0
# [5,] 0 0 0 0 0
You can apply the function repeatedly to further spread the data:
spread(spread(X))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 1 0
# [2,] 1 1 1 1 0
# [3,] 1 1 1 1 0
# [4,] 1 1 1 1 0
# [5,] 0 0 0 0 0
spread(spread(spread(X)))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 1 1
# [2,] 1 1 1 1 1
# [3,] 1 1 1 1 1
# [4,] 1 1 1 1 1
# [5,] 1 1 1 1 1

This works for multiple 1's in the initial matrix that also can be in the first/last column/row.
A <- matrix(0, nrow = 5, ncol = 5)
A[2, 2] <- 1
A[5, 5] <- 1
A
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0 0 0 0
# [2,] 0 1 0 0 0
# [3,] 0 0 0 0 0
# [4,] 0 0 0 0 0
# [5,] 0 0 0 0 1
spread <- function(x) {
idx <- do.call(rbind, apply(which(x == 1, arr.ind = TRUE), 1,
function(y) expand.grid(y[1] + 1:-1, y[2] + 1:-1)))
idx <- idx[!(idx[, 1] %in% c(0, nrow(x) + 1) | idx[, 2] %in% c(0, ncol(x) + 1)), ]
x[as.matrix(idx)] <- 1
x
}
spread(A)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 0 0
# [2,] 1 1 1 0 0
# [3,] 1 1 1 0 0
# [4,] 0 0 0 1 1
# [5,] 0 0 0 1 1
spread(spread(A))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 1 0
# [2,] 1 1 1 1 0
# [3,] 1 1 1 1 1
# [4,] 1 1 1 1 1
# [5,] 0 0 1 1 1
Edit:
Here is a function with a parameter k (taking values 1, 2, ...) that denotes the step of spreading 1's:
spread <- function(x, k) {
idx <- do.call(rbind, apply(which(x == 1, arr.ind = TRUE), 1,
function(y) expand.grid(y[1] + k:-k, y[2] + k:-k)))
idx <- idx[idx[, 1] %in% 1:nrow(x) & idx[, 2] %in% 1:ncol(x), ]
x[as.matrix(idx)] <- 1
x
}
spread(A, 2)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 1 0
# [2,] 1 1 1 1 0
# [3,] 1 1 1 1 1
# [4,] 1 1 1 1 1
# [5,] 0 0 1 1 1

This works but might need some retooling for more general cases, i.e. your going to run into problems with multiple 1 in the initial matrix. If such a generalization is required please let me know and I'll gladly attempt to produce one. Or just use either josilber's or Julius's answer.
M <- as.matrix(read.table(textConnection("0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0")))
my_spread <- function(m){
e <- which(m == 1, arr.ind = TRUE)
r <- c(e[, 1] - 1, e[, 1], e[, 1] + 1)
l <- c(e[, 2] - 1, e[, 2], e[, 2] + 1)
#dealing with border cases
r <- r[nrow(m) >= r]
l <- l[ncol(m) >= l]
m[as.matrix(expand.grid(r,l))] <- 1
m
}
my_spread(M)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 0 0
[2,] 1 1 1 0 0
[3,] 1 1 1 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
my_spread(my_spread(M))
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 0
[2,] 1 1 1 1 0
[3,] 1 1 1 1 0
[4,] 1 1 1 1 0
[5,] 0 0 0 0 0
my_spread(my_spread(my_spread(M)))
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 1 1 1 1 1
[3,] 1 1 1 1 1
[4,] 1 1 1 1 1
[5,] 1 1 1 1 1

Related

Creating a specific matrix in R

I want to create the following matrix
A <- matrix(0,n,n)
for(i in 1:n){
for(j in 1:n){
if(abs(i - j) == 1) A1[i,j] <- 1
}
}
Is there another way to create such a matrix? I just want to avoid using for-loop.
A simple option is using outer + abs
> +(abs(outer(1:n,1:n,`-`))==1)
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0 1 0 0 0 0 0
[2,] 1 0 1 0 0 0 0
[3,] 0 1 0 1 0 0 0
[4,] 0 0 1 0 1 0 0
[5,] 0 0 0 1 0 1 0
[6,] 0 0 0 0 1 0 1
[7,] 0 0 0 0 0 1 0
where n <- 7
Create a matrix with 0 values
Subtract row index with column index.
Replace values in matrix with 1 where the difference is 1 or -1
n <- 5
A <- matrix(0,n,n)
inds <- row(A) - col(A)
A[abs(inds) == 1] <- 1
A
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0 1 0 0 0
#[2,] 1 0 1 0 0
#[3,] 0 1 0 1 0
#[4,] 0 0 1 0 1
#[5,] 0 0 0 1 0
where row(A) - col(A) (inds) returns :
inds
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0 -1 -2 -3 -4
#[2,] 1 0 -1 -2 -3
#[3,] 2 1 0 -1 -2
#[4,] 3 2 1 0 -1
#[5,] 4 3 2 1 0
Using tidyverse - crossing to get the combinations of sequence, then
get the absolute difference (-) between the columns, check if it is equal to 1, and reshape from 'long' to 'wide' with pivot_wider
library(dplyr)
library(tidyr)
crossing(n1 = 1:n, n2 = 1:n) %>%
mutate(new = +(abs((n1 - n2)) == 1)) %>%
pivot_wider(names_from = n2, values_from = new)
-output
# A tibble: 5 x 6
# n1 `1` `2` `3` `4` `5`
# <int> <int> <int> <int> <int> <int>
#1 1 0 1 0 0 0
#2 2 1 0 1 0 0
#3 3 0 1 0 1 0
#4 4 0 0 1 0 1
#5 5 0 0 0 1 0
Or another option with diag from base R
+(abs(row(diag(n)) - col(diag(n))) == 1)
-output
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0 1 0 0 0
#[2,] 1 0 1 0 0
#[3,] 0 1 0 1 0
#[4,] 0 0 1 0 1
#[5,] 0 0 0 1 0
You can reduce the amount of code by using the function stats::toeplitz, which follows the idea in the answer by Ronak Shah.
f1 <- function(n)
{
A <- matrix(0,n,n)
inds <- row(A) - col(A)
A[abs(inds) == 1] <- 1
A
}
n <- 10
A1 <- f1(n)
A2 <- toeplitz(c(0,1,rep(0,n-2)))
all.equal(A1, A2)
#[1] TRUE

Obtain matrices by switch a one and a zero-Local search

Let's start with the following matrix.
M <- matrix(c(0,0,0,1,0,0,1,1,
0,0,1,0,0,1,1,0,
0,0,0,0,0,1,1,1,
0,0,0,1,1,0,1,0,
0,0,0,1,1,1,0,0,
0,0,1,0,1,0,0,1),nrow = 8,ncol = 6)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 0 0 0 0 0
[2,] 0 0 0 0 0 0
[3,] 0 1 0 0 0 1
[4,] 1 0 0 1 1 0
[5,] 0 0 0 1 1 1
[6,] 0 1 1 0 1 0
[7,] 1 1 1 1 0 0
[8,] 1 0 1 0 0 1
I want to obtain set of matrices by switching ones and zeros. For each column, starting from column 1, I wanna obtain set of matrices by switching 1 in (4,1) with 0 in (1,1), (2,1), (3,1), (5,1), (6,1) and then do the same for 1s in (7,1) and (8,1). Then continue to the other columns. There are altogether
90 matrices (15 for each column, 15*6) after switching. This is just an example. I have bigger size matrices. How do I generalize for other cases?
Here's a solution. You could wrap the whole thing up into a function. It produces a list of lists of matrices, results, where results[[i]] is a list of matrices with the ith column switched.
column_switcher = function(x) {
ones = which(x == 1)
zeros = which(x == 0)
results = matrix(rep(x, length(ones) * length(zeros)), nrow = length(x))
counter = 1
for (one in ones) {
for (zero in zeros) {
results[one, counter] = 0
results[zero, counter] = 1
counter = counter + 1
}
}
return(results)
}
switched = lapply(1:ncol(M), function(col) column_switcher(M[, col]))
results = lapply(seq_along(switched), function(m_col) {
lapply(1:ncol(switched[[m_col]]), function(i) {
M[, m_col] = switched[[m_col]][, i]
return(M)
})
})
results[[1]]
# [[1]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1 0 0 0 0 0
# [2,] 0 0 0 0 0 0
# [3,] 0 1 0 0 0 1
# [4,] 0 0 0 1 1 0
# [5,] 0 0 0 1 1 1
# [6,] 0 1 1 0 1 0
# [7,] 1 1 1 1 0 0
# [8,] 1 0 1 0 0 1
#
# [[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 0 0 0 0 0 0
# [2,] 1 0 0 0 0 0
# [3,] 0 1 0 0 0 1
# [4,] 0 0 0 1 1 0
# [5,] 0 0 0 1 1 1
# [6,] 0 1 1 0 1 0
# [7,] 1 1 1 1 0 0
# [8,] 1 0 1 0 0 1
#
# ...
Checking the length of the list and the lengths of the sublists, they're all there.
length(results)
# [1] 6
lengths(results)
# [1] 15 15 15 15 15 15

Changing the values in a binary matrix

Consider the 8 by 6 binary matrix, M:
M <- matrix(c(0,0,1,1,0,0,1,1,
0,1,1,0,0,1,1,0,
0,0,0,0,1,1,1,1,
0,1,0,1,1,0,1,0,
0,0,1,1,1,1,0,0,
0,1,1,0,1,0,0,1),nrow = 8,ncol = 6)
Here is the M
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 0 0 0 0 0
[2,] 0 1 0 1 0 1
[3,] 1 1 0 0 1 1
[4,] 1 0 0 1 1 0
[5,] 0 0 1 1 1 1
[6,] 0 1 1 0 1 0
[7,] 1 1 1 1 0 0
[8,] 1 0 1 0 0 1
The following matrix contains the column index of the 1's in matrix M
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 2 5 2 3 2
[2,] 4 3 6 4 4 3
[3,] 7 6 7 5 5 5
[4,] 8 7 8 7 6 8
Let's denote that
ind <- matrix(c(3,4,7,8,
2,3,6,7,
5,6,7,8,
2,4,5,7,
3,4,5,6,
2,3,5,8),nrow = 4, ncol=6)
I'm trying to change a single position of 1 into 0in each column of M.
For an example, one possibility of index of1s in each column would be (4,2,5,4,3,2), i.e. 4th position of Column1, 2nd position of Column2, 5thposition of Column3 and so on. Let N be the resulting matrices. This will produce the following matrix N
N <- matrix(c(0,0,1,0,0,0,1,1,
0,0,1,0,0,1,1,0,
0,0,0,0,0,1,1,1,
0,1,0,0,1,0,1,0,
0,0,0,1,1,1,0,0,
0,0,1,0,1,0,0,1),nrow = 8,ncol = 6)
Here is that N
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 0 0 0 0 0
[2,] 0 0 0 1 0 0
[3,] 1 1 0 0 0 1
[4,] 0 0 0 0 1 0
[5,] 0 0 0 1 1 1
[6,] 0 1 1 0 1 0
[7,] 1 1 1 1 0 0
[8,] 1 0 1 0 0 1
For EACH of the resulting matrices of N, I do the following calculations.
X <- cbind(c(rep(1,nrow(N))),N)
ans <- sum(diag(solve(t(X)%*%X)[-1,-1]))
Then, I want to obtain the matrix N, which produce the smallest value of ans. How do I do this efficiently?
Let me know if this works.
We first build a conversion function that I'll need, and we build also the reverse function as you may need it at some point:
ind_to_M <- function(ind){
M <- matrix(rep(0,6*8),ncol=6)
for(i in 1:ncol(ind)){M[ind[,i],i] <- 1}
return(M)
}
M_to_ind <- function(M){apply(M==1,2,which)}
Then we will build a matrix of possible ways to ditch a value
all_possible_ways_to_ditch_value <- 1:4
for (i in 2:ncol(M)){
all_possible_ways_to_ditch_value <- merge(all_possible_ways_to_ditch_value,1:4,by=NULL)
}
# there's probably a more elegant way to do that
head(all_possible_ways_to_ditch_value)
# x y.x y.y y.x y.y y
# 1 1 1 1 1 1 1 # will be used to ditch the 1st value of ind for every column
# 2 2 1 1 1 1 1
# 3 3 1 1 1 1 1
# 4 4 1 1 1 1 1
# 5 1 2 1 1 1 1
# 6 2 2 1 1 1 1
Then we iterate through those, each time storing ans and N (as data is quite small overall).
ans_list <- list()
N_list <- list()
for(j in 1:nrow(all_possible_ways_to_ditch_value)){
#print(j)
ind_N <- matrix(rep(0,6*3),ncol=6) # initiate ind_N as an empty matrix
for(i in 1:ncol(M)){
ind_N[,i] <- ind[-all_possible_ways_to_ditch_value[j,i],i] # fill with ind except for the value we ditch
}
N <- ind_to_M(ind_N)
X <- cbind(c(rep(1,nrow(N))),N)
ans_list[[j]] <- try(sum(diag(solve(t(X)%*%X)[-1,-1])),silent=TRUE) # some systems are not well defined, we'll just ignore the errors
N_list[[j]] <- N
}
We finally retrieve the minimal ans and the relevant N
ans <- ans_list[[which.min(ans_list)]]
# [1] -3.60288e+15
N <- N_list[[which.min(ans_list)]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 0 0 0 0 0 0
# [2,] 0 1 0 1 0 1
# [3,] 1 1 0 0 1 1
# [4,] 1 0 0 1 1 0
# [5,] 0 0 1 1 1 1
# [6,] 0 1 1 0 0 0
# [7,] 1 0 1 0 0 0
# [8,] 0 0 0 0 0 0
EDIT:
To get minimal positive ans
ans_list[which(!sapply(ans_list,is.numeric))] <- Inf
ans <- ans_list[[which.min(abs(unlist(ans_list)))]]
# [1] 3.3
N <- N_list[[which.min(abs(unlist(ans_list)))]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 0 0 0 0 0 0
# [2,] 0 1 0 1 0 0
# [3,] 1 1 0 0 0 1
# [4,] 1 0 0 0 1 0
# [5,] 0 0 0 1 1 1
# [6,] 0 1 1 0 1 0
# [7,] 1 0 1 1 0 0
# [8,] 0 0 1 0 0 1
EDIT 2 : to generalize the number of rows of ind to ditch
It seems to give the same result for ans for n_ditch = 1, and results make sense for n_ditch = 2
n_ditch <- 2
ditch_possibilities <- combn(1:4,n_ditch) # these are all the possible sets of indices to ditch for one given columns
all_possible_ways_to_ditch_value <- 1:ncol(ditch_possibilities) # this will be all the possible sets of indices of ditch_possibilities to test
for (i in 2:ncol(M)){
all_possible_ways_to_ditch_value <- merge(all_possible_ways_to_ditch_value,1:ncol(ditch_possibilities),by=NULL)
}
ans_list <- list()
N_list <- list()
for(j in 1:nrow(all_possible_ways_to_ditch_value)){
#print(j)
ind_N <- matrix(rep(0,6*(4-n_ditch)),ncol=6) # initiate ind_N as an empty matrix
for(i in 1:ncol(M)){
ind_N[,i] <- ind[-ditch_possibilities[,all_possible_ways_to_ditch_value[j,i]],i] # fill with ind except for the value we ditch
}
N <- ind_to_M(ind_N)
X <- cbind(c(rep(1,nrow(N))),N)
ans_list[[j]] <- try(sum(diag(solve(t(X)%*%X)[-1,-1])),silent=TRUE) # some systems are not well defined, we'll just ignore the errors
N_list[[j]] <- N
}

Operate on every two columns in a matrix

Q1=c(0,1,0,1,0,1,0,1)
Q2=c(1,0,0,0,1,1,1,0)
Q3=c(0,0,0,0,0,0,0,0)
Q4=c(1,0,0,0,1,1,1,0)
Q = cbind(Q1,Q2, Q3, Q4)
Q = matrix(Q, 8, 4)
[,1] [,2] [,3] [,4]
[1,] 0 1 0 1
[2,] 1 0 0 0
[3,] 0 0 0 0
[4,] 1 0 0 0
[5,] 0 1 0 1
[6,] 1 1 0 1
[7,] 0 1 0 1
[8,] 1 0 0 0
I want to write a function
ifelse(Q[1]==1||Q[2]==1, 1,0)
and then keep increasing for column 3 and 4
ifelse(Q[3]==1||Q[4]==1, 1,0)
Return matrix
This is my code:
n = function(n){
x <- matrix(n row= 8,n col=n)
for(i in 1:n){
for (j in 1: 4){
i = 1
j = 1
x[,i]= apply(Q, 1, function(x)if else(x[j]==1||x[j+1]==1, 1,0))
j = j+2
}
return(x)
}
}
n(1)
n(2)
[,1] [,2]
[1,] 1 NA
[2,] 1 NA
[3,] 0 NA
[4,] 1 NA
[5,] 1 NA
[6,] 1 NA
[7,] 1 NA
I think I did something wrong,the new matrix suppose, plus I have over 100 columns, so I have to write increase loop every 2 columns
[,1] [,2]
[1,] 1 1
[2,] 1 0
[3,] 0 0
[4,] 1 0
[5,] 1 1
[6,] 1 1
[7,] 1 1
Thanks guys,now this time I got right. We can group by how many variables you want. I have 2 ways to do that, the first one is not good, the second one is better
> Q1=c(0,1,0,1,0,1,0,1)
> Q2=c(1,0,0,0,1,1,1,0)
> Q3=c(0,0,0,0,0,0,0,0)
> Q4=c(1,0,0,0,1,1,1,0)
> Q5=c(1,0,0,0,1,1,1,0)
> Q6=c(0,0,0,0,0,0,0,0)
> Q7=c(1,0,0,0,1,1,1,0)
> Q8=c(0,0,0,0,0,0,0,0)
> Q9=c(1,0,0,0,1,1,1,0)
> Q = cbind(Q1,Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9)
> Q = matrix(Q, 8, 9)
> Q
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 0 1 0 1 1 0 1 0 1
[2,] 1 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0 0
[4,] 1 0 0 0 0 0 0 0 0
[5,] 0 1 0 1 1 0 1 0 1
[6,] 1 1 0 1 1 0 1 0 1
[7,] 0 1 0 1 1 0 1 0 1
[8,] 1 0 0 0 0 0 0 0 0
This is the first way
> x <- list(1:3,4:6,7:9)
> do.call(cbind, lapply(x, function(i) ifelse(rowSums(Q[,i]>=1), 1,0)))
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 0 0
[3,] 0 0 0
[4,] 1 0 0
[5,] 1 1 1
[6,] 1 1 1
[7,] 1 1 1
[8,] 1 0 0
>
This is the second way, it's better
> Q.t <- data.frame(t(Q))
> n <- 3
> Q.t$groups <- rep(seq(1:(ncol(Q)/n)), each = n, len = (ncol(Q)))
> QT <- data.table(Q.t)
> setkey(QT, groups)
> Q.level <- QT[,lapply(.SD,sum), by = groups]
> Q.level <- t(Q.level)
> Q.level <- Q.level[-1,]
> apply(Q.level,2, function(x) ifelse(x>=1,1,0))
[,1] [,2] [,3]
X1 1 1 1
X2 1 0 0
X3 0 0 0
X4 1 0 0
X5 1 1 1
X6 1 1 1
X7 1 1 1
X8 1 0 0
>

How to generate a matrix to store all non-empty subsets of a set

Suppose I have a set N={1,2,3}, then we can list all its 7 non-empty subsets.
n=3 # number of elements in a set
a=2^n-1 # number of non-empty subsets for that set
subsets=lapply(1:n, function(x) combn(n, x)) # list all the non-empty subest
subsets
Now I want to put these subsets into a matrix and organized like:
if n=3 or in an index matrix:
1 0 0 1 0 0
0 2 0 0 1 0
0 0 3 0 0 1
1 2 0 1 1 0
1 0 3 1 0 1
0 2 3 0 1 1
1 2 3 1 1 1
Anyone knows how to write the code that could be easily extended to any n (=4, 5, 6...)? I tried this:
subindex=matrix(c(0), nrow=a, ncol=n)
i=1
while(i<=a){
j=n
b=2^(n-1)
N=i
while(N>0){
if(b<=N) {subindex[i,j]=1}&{N=N-b}
b=trunc(b/2)
j=j-1
}
i=i+1
}
subindex
But the index matrix I get is wrong in row 3 and 4. If n=4, then there are more errors... Can anybody correct this or simplify this code? or just write a completely new code. Really appreciate.
n <- 4
lapply(seq_len(n), function(i)t(combn(n, i, FUN = tabulate, nbins = n)))
# [[1]]
# [,1] [,2] [,3] [,4]
# [1,] 1 0 0 0
# [2,] 0 1 0 0
# [3,] 0 0 1 0
# [4,] 0 0 0 1
#
# [[2]]
# [,1] [,2] [,3] [,4]
# [1,] 1 1 0 0
# [2,] 1 0 1 0
# [3,] 1 0 0 1
# [4,] 0 1 1 0
# [5,] 0 1 0 1
# [6,] 0 0 1 1
#
# [[3]]
# [,1] [,2] [,3] [,4]
# [1,] 1 1 1 0
# [2,] 1 1 0 1
# [3,] 1 0 1 1
# [4,] 0 1 1 1
#
# [[4]]
# [,1] [,2] [,3] [,4]
# [1,] 1 1 1 1

Resources