A Latin square of size n is an arrangement of n symbols in an n-by-n square in such a way that each row and column has each symbol appearing exactly once.

A randomised Latin square generates random configurations of the symbols for any given n.

Example n=4 randomised Latin square

0 2 3 1
2 1 0 3
3 0 1 2
1 3 2 0
Task

 Create a function/routine/procedure/method/... that given n generates a randomised Latin square of size n.
 Use the function to generate and show here, two randomly generated squares of size 5.
Note
 
Strict Uniformity in the random generation is a hard problem and not a requirement of the task.

Reference

 Wikipedia: Latin square
 OEIS: A002860


import std.array;
import std.random;
import std.stdio;
 
alias Matrix = int[][];
 
void latinSquare(int n) {
    if (n <= 0) {
        writeln("[]");
        return;
    }
 
    Matrix latin = uninitializedArray!Matrix(n, n);
    foreach (row; latin) {
        for (int i = 0; i < n; i++) {
            row[i] = i;
        }
    }
    // first row
    latin[0].randomShuffle;
 
    // middle row(s)
    for (int i = 1; i < n - 1; i++) {
        bool shuffled = false;
 
        shuffling:
        while (!shuffled) {
            latin[i].randomShuffle;
            for (int k = 0; k < i; k++) {
                for (int j = 0; j < n; j++) {
                    if (latin[k][j] == latin[i][j]) {
                        continue shuffling;
                    }
                }
            }
            shuffled = true;
        }
    }
 
    // last row
    for (int j = 0; j < n; j++) {
        bool[] used = uninitializedArray!(bool[])(n);
        used[] = false;
 
        for (int i = 0; i < n - 1; i++) {
            used[latin[i][j]] = true;
        }
        for (int k = 0; k < n; k++) {
            if (!used[k]) {
                latin[n - 1][j] = k;
                break;
            }
        }
    }
 
    printSquare(latin);
}
 
void printSquare(Matrix latin) {
    foreach (row; latin) {
        writeln(row);
    }
}
 
void main() {
    latinSquare(5);
    writeln;
 
    latinSquare(5);
    writeln;
 
    latinSquare(10);
}