It seems to work. It generates a list of all possible combinations, then removes everything that matches the previously selected lines, leaving only one at the end.
matriz <- function(n){
combs <- as.matrix(expand.grid(rep(list(LETTERS[1:n]),n)))
combs <- combs[apply(combs,1,function(r) all(LETTERS[1:n] %in% r)),]
mat <- matrix(NA,nrow=n,ncol=n)
for(i in 1:(n-1)){
mat[i,] <- combs[sample(1:nrow(combs),1),]
combs <- combs[!apply(combs,1,function(r) any(r == mat[i,])),]
}
mat[n,] <- combs
return(mat)
}
> matriz(5)
[,1] [,2] [,3] [,4] [,5]
[1,] "B" "D" "A" "E" "C"
[2,] "E" "C" "D" "B" "A"
[3,] "D" "A" "B" "C" "E"
[4,] "A" "E" "C" "D" "B"
[5,] "C" "B" "E" "A" "D"
> matriz(5)
[,1] [,2] [,3] [,4] [,5]
[1,] "D" "C" "E" "B" "A"
[2,] "E" "A" "C" "D" "B"
[3,] "A" "D" "B" "C" "E"
[4,] "B" "E" "D" "A" "C"
[5,] "C" "B" "A" "E" "D"
A slightly faster version with a package combinat
would be
library(combinat)
matriz <- function(n){
combs <- do.call(rbind,permn(LETTERS[1:n]))
mat <- matrix(NA,nrow=n,ncol=n)
Both can be quite slow for n> 10 or so. However, if you created one real square m
, then all the others will be permutations m[sample(nrow(m)),sample(ncol(m))]
, so this might be a faster approach if you make a lot of them.