A Latin Square is in its reduced form if the first row and first column contain items in their natural order. The order n is the number of items. For any given n there is a set of reduced Latin Squares whose size increases rapidly with n. g is a number which identifies a unique element within the set of reduced Latin Squares of order n. The objective of this task is to construct the set of all Latin Squares of a given order and to provide a means which given suitable values for g any element within the set may be obtained.

For a reduced Latin Square the first row is always 1 to n. The second row is all Permutations/Derangements of 1 to n starting with 2. The third row is all Permutations/Derangements of 1 to n starting with 3 which do not clash (do not have the same item in any column) with row 2. The fourth row is all Permutations/Derangements of 1 to n starting with 4 which do not clash with rows 2 or 3. Likewise continuing to the nth row.

Demonstrate by:

 displaying the four reduced Latin Squares of order 4.
 for n = 1 to 6 (or more) produce the set of reduced Latin Squares; produce a table which shows the size of the set of reduced Latin Squares and compares this value times n! times (n-1)! with the values in OEIS A002860.


fcn reducedLatinSquare(n,write=False){
   if(n<=1) return(n);
   rlatin:=n.pump(List(), List.createLong(n,0).copy);  // matrix of zeros
   foreach i in (n){ rlatin[0][i]=i+1 }  // first row: (1,2,3..n)
 
   count:=Ref(0);
   // recursive closure to compute reduced latin squares and count or print them
   rows,rsz := derangements(n), rows.len();
   recurse:='wrap(i){
      foreach r in (rsz){	      // top
         if(rows[r][0]!=i) continue;  // filter by first column, ignore all but i
         rlatin[i-1]=rows[r].copy();
	 foreach k,j in ([0..i-2],[1..n-1]){	// nested loop: foreach foreach
	    if(rlatin[k][j] == rlatin[i-1][j]){
	       if(r < rsz-1) continue(3);	// -->top
	       if(i>2) return();
	    }
	 }
	 if(i<n) self.fcn(i + 1, vm.pasteArgs(1));  // 'wrap hides local data (ie count, rows, etc)
	 else{
	    count.inc();
	    if(write) printSquare(rlatin,n);
	 }
      }
   };
   recurse(2);   // remaining rows
   return(count.value);
}
fcn derangements(n,i){
   enum:=[1..n].pump(List);
   Utils.Helpers.permuteW(enum).tweak('wrap(perm){
      if(perm.zipWith('==,enum).sum(0)) Void.Skip
      else perm
   }).pump(List);
}
fcn printSquare(matrix,n){
   matrix.pump(Console.println,fcn(l){ l.concat(", ","[","]") });
   println();
}
fcn fact(n){ ([1..n]).reduce('*,1) }