2

I need to find all possible 5x5 matrix of integers 1-5 unique to each row and column (imagine a Sudoku) in R.

Is there any efficient way of doing this without creating all 120C5 matrices and then finding the fitting ones?

Thank you!

5
  • sapply(1:5, function(i) (1:5 - i) %% 5 + 1). (This was an easy one, but for future questions, please show some effort on your part. This isn't a free-code-service. If this is homework, I hope I get an "A".) Commented Nov 8, 2018 at 23:02
  • Hi sorry I need to find all possible combinations not just one - sorry for not making that clear. Commented Nov 8, 2018 at 23:05
  • 1
    It's an interesting problem, and one I may put on the back burner for a while. However, it's too much for quick Q/As on SO, so you may not get a response. Or you may, who knows. But this will be more effort than most questions (that I see) typically require. Good luck. Commented Nov 8, 2018 at 23:09
  • 1
    Such matrices are called latin squares. See stackoverflow.com/a/49203589/1320535 for how to generate random ones. Generating all of them is indeed not straightforward, see en.wikipedia.org/wiki/Latin_square#Algorithms. Commented Nov 8, 2018 at 23:18
  • 1
    I agree with @r2evans. This is a computationally interesting question. I strongly recommend that you yourself give this a try first. You can find resources on the net, and even here on SO. Show a code attempt at solving the problem, and I can guarantee that you will get a much better response (and you will learn a lot more as well). At the moment this reads too much like "gimme teh codez". Commented Nov 8, 2018 at 23:19

1 Answer 1

3

As I said in my comment above, matrices of this type are called Latin squares.

For a start, we already know that there are 56 so-called reduced Latin squares and 161280 all Latin squares of size 5. The reduced Latin squares are such that both the first column and the first row are just 1, 2, 3, 4, 5 (in this order). Given those reduced Latin squares, one may easily (as long as the size is not greater than 5) generate all Latin squares: permute all the rows except the first one and permute all the columns. Hence, as expected, 161280=5!*4!*56.

By restricting the first row and column one could generate 4!*3!*2!=288 matrices and check which 56 are Latin squares. However, I'm going to skip that and take their list from here.

First we read and rearrange the data

reduced <- read.table("http://users.cecs.anu.edu.au/~bdm/data/reduced5.txt", head = FALSE, colClasses = "character")
reduced <- lapply(1:nrow(reduced), function(r) matrix(as.numeric(unlist(strsplit(unlist(reduced[r, ]), ""))) + 1, 5))
length(reduced)
# [1] 56

Now let's generate all 5! and 4! permutations of 1, 2, 3, 4, 5 and 1, 2, 3, 4, respectively.

library(combinat)
perms5 <- permn(1:5)
perms4 <- permn(1:4)

Lastly, we go over all the reduced Latin squares and permute them in all possible ways

allLS <- sapply(reduced, function(m) {
  LS <- vector("list", gamma(6) * gamma(5))
  for(i in 1:gamma(5))
    for(j in 1:gamma(6))
      LS[[(i - 1) * gamma(6) + j]] <- m[perms4[[i]] + 1, perms5[[j]]]
  LS
})

Takes just a couple of seconds and we have the result

length(allLS)
# [1] 161280

It is easy to verify that they all are different

table(table(sapply(allLS, paste0, collapse = "")))
#      1 
# 161280 

and you could also check if they all are Latin squares.

Sign up to request clarification or add additional context in comments.

3 Comments

Very impressive, Julius! Now I can turn off my back-burner. (I really like list()[rep(...)] instead of replicate(n,NULL,simplify=F), too ... much faster.)
@r2evans, thanks! And now your comment reminded me of something even nicer and faster: vector("list", n). Around another 5 times faster than list()[rep(1, n)].
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (where n <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stable vector function ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.