Generation of random Latin Squares (such that each latin square of a given size is equally likely) is a deceptively difficult problem.
This post describes my own implementation, loosely based on the Java implementation described by Ignacio Gallego Sagastume which implements the rather ingenious method of Jacobson and Matthews
Basics
A Latin square is an 
Here’s an example, containing the numbers 1 to 5.
It’s easy to quickly verify that each of the numbers 1 to 5 appear exactly once in each row and column.
Other example Latin squares appear in the graphical header of this post.
Jacobson and Matthews
In their paper, Jacobson and Matthews present an algorithm for generating random Latin squares.
Their work relies on two main insights. First, that a Latin square is equivalent to an incidence matrix.
That’s an 
These incidence matrices correspond to Latin squares: if you start with an incidence matrix and fix two dimensions (I choose 
Their ingenious step is to generalize this idea of incidence matrix. They frame the “exactly one element in each line is 1” to “if you fix 
The transition step
Jacobson and Matthews define the transition step based on whether you’ve currently got a perfect incidence matrix (that is, one with no -1 entry), or an imperfect one (that is, one with a single -1 entry).
In the perfect case, they pick 
Next, they choose 
Now, 
The transition step is to add 1 to the element 
Implementation
To implement the algorithm efficiently, we’d like the transition function to take O(1) time. The slow part, with a naive implementation, will be finding the 1 elements in the (perfect or imperfect) incidence matrix.
I take a similar, but slightly more efficient, approach to Sagastume’s Java implementation.
The matrix 
xy [n][n]int // an array of n by n integers
yz [n][n]int
xz [n][n]int
perfect bool
m [3]int
mxy, myz, mxz int
(as a pedantic side note, the xy, yz and xz arrays are actually slices in go to allow for n to be varied at runtime).
The correspondence to the 
- xy[i][j]==kimplies
- yz[j][k]==iimplies
- xz[i][k]==jimplies
- perfectdescribes whether- if mcontains the coordinates of the -1 entry …
- … and the entries m[0],m[1],mxy,m[0],mxz,m[2],myz,m[1],m[2]of
This representation makes finding 1’s in the incidence matrix efficient, and has
the property that xy, yz and xz each correspond to a Latin square representation
of the incidence matrix when the incidence matrix is proper.
The full go source code is here, and is set up to output a random 25x25 Latin square when run.
The code is small and fast enough to run on the go playground, which you
can find here by clicking here. The playground
version has a Seed and N parameter that you can change to get different Latin squares.
package main
import (
	"fmt"
	"math/rand"
	"time"
)
func rand2(a, b int) (int, int) {
	if rand.Intn(2) == 0 {
		return a, b
	}
	return b, a
}
func Latin(n int) [][]int {
	xy := make([][]int, n)
	xz := make([][]int, n)
	yz := make([][]int, n)
	for i := 0; i < n; i++ {
		xy[i] = make([]int, n)
		yz[i] = make([]int, n)
		xz[i] = make([]int, n)
	}
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			k := (i + j) % n
			xy[i][j] = k
			xz[i][k] = j
			yz[j][k] = i
		}
	}
	var mxy, mxz, myz int
	var m [3]int
	proper := true
	minIter := n * n * n
	for iter := 0; iter < minIter || !proper; iter++ {
		var i, j, k, i2, j2, k2 int
		var i2_, j2_, k2_ int
		if proper {
			// Pick a random 0 in the array
			i, j, k = rand.Intn(n), rand.Intn(n), rand.Intn(n)
			for xy[i][j] == k {
				i, j, k = rand.Intn(n), rand.Intn(n), rand.Intn(n)
			}
			// find i2 such that [i2, j, k] is 1. same for j2, k2
			i2 = yz[j][k]
			j2 = xz[i][k]
			k2 = xy[i][j]
			i2_, j2_, k2_ = i, j, k
		} else {
			i, j, k = m[0], m[1], m[2]
			// find one such that [i2, j, k] is 1, same for j2, k2.
			// each is either the value stored in the corresponding
			// slice, or one of our three temporary "extra" 1s.
			// That's because (i, j, k) is -1.
			i2, i2_ = rand2(yz[j][k], myz)
			j2, j2_ = rand2(xz[i][k], mxz)
			k2, k2_ = rand2(xy[i][j], mxy)
		}
		proper = xy[i2][j2] == k2
		if !proper {
			m = [3]int{i2, j2, k2}
			mxy = xy[i2][j2]
			myz = yz[j2][k2]
			mxz = xz[i2][k2]
		}
		xy[i][j] = k2_
		xy[i][j2] = k2
		xy[i2][j] = k2
		xy[i2][j2] = k
		yz[j][k] = i2_
		yz[j][k2] = i2
		yz[j2][k] = i2
		yz[j2][k2] = i
		xz[i][k] = j2_
		xz[i][k2] = j2
		xz[i2][k] = j2
		xz[i2][k2] = j
	}
	return xy
}
func main() {
	rand.Seed(time.Now().UnixNano())
	const N = 25
	for _, row := range Latin(N) {
		for _, c := range row {
			fmt.Printf("%3d ", c+1)
		}
		fmt.Printf("\n")
	}
}
