Latin Squares in reduced form: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
(11 intermediate revisions by 9 users not shown)
Line 8:
* 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|OEIS A002860]].
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F dList(n, =start)
start--
V a = Array(0 .< n)
a[start] = a[0]
a[0] = start
a.sort_range(1..)
V first = a[1]
[[Int]] r
F recurse(Int last) -> N
I (last == @first)
L(v) @a[1..]
I L.index + 1 == v
R
V b = @a.map(x -> x + 1)
@r.append(b)
R
L(i) (last .< 0).step(-1)
swap(&@a[i], &@a[last])
@recurse(last - 1)
swap(&@a[i], &@a[last])
recurse(n - 1)
R r
 
F printSquare(latin, n)
L(row) latin
print(row)
print()
 
F reducedLatinSquares(n, echo)
I n <= 0
I echo
print(‘[]’)
R 0
E I n == 1
I echo
print([1])
R 1
 
V rlatin = [[0] * n] * n
L(j) 0 .< n
rlatin[0][j] = j + 1
 
V count = 0
F recurse(Int i) -> N
V rows = dList(@n, i)
 
L(r) 0 .< rows.len
@rlatin[i - 1] = rows[r]
V justContinue = 0B
V k = 0
L !justContinue & k < i - 1
L(j) 1 .< @n
I @rlatin[k][j] == @rlatin[i - 1][j]
I r < rows.len - 1
justContinue = 1B
L.break
I i > 2
R
k++
I !justContinue
I i < @n
@recurse(i + 1)
E
@count++
I @echo
printSquare(@rlatin, @n)
 
recurse(2)
R count
 
print("The four reduced latin squares of order 4 are:\n")
reducedLatinSquares(4, 1B)
 
print(‘The size of the set of reduced latin squares for the following orders’)
print("and hence the total number of latin squares of these orders are:\n")
L(n) 1..6
V size = reducedLatinSquares(n, 0B)
V f = factorial(n - 1)
f *= f * n * size
print(‘Order #.: Size #<4 x #.! x #.! => Total #.’.format(n, size, n, n - 1, f))</syntaxhighlight>
 
{{out}}
<pre>
The four reduced latin squares of order 4 are:
 
[1, 2, 3, 4]
[2, 1, 4, 3]
[3, 4, 1, 2]
[4, 3, 2, 1]
 
[1, 2, 3, 4]
[2, 1, 4, 3]
[3, 4, 2, 1]
[4, 3, 1, 2]
 
[1, 2, 3, 4]
[2, 4, 1, 3]
[3, 1, 4, 2]
[4, 3, 2, 1]
 
[1, 2, 3, 4]
[2, 3, 4, 1]
[3, 4, 1, 2]
[4, 1, 2, 3]
 
The size of the set of reduced latin squares for the following orders
and hence the total number of latin squares of these orders are:
 
Order 1: Size 1 x 1! x 0! => Total 1
Order 2: Size 1 x 2! x 1! => Total 2
Order 3: Size 1 x 3! x 2! => Total 12
Order 4: Size 4 x 4! x 3! => Total 576
Order 5: Size 56 x 5! x 4! => Total 161280
Order 6: Size 9408 x 6! x 5! => Total 812851200
</pre>
 
=={{header|C sharp|C#}}==
{{trans|D}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 161 ⟶ 280:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>The four reduced latin squares of order 4 are:
Line 197 ⟶ 316:
=={{header|C++}}==
{{trans|C#}}
<langsyntaxhighlight lang="cpp">#include <algorithm>
#include <functional>
#include <iostream>
Line 345 ⟶ 464:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>The four reduced lating squares of order 4 are:
Line 380 ⟶ 499:
=={{header|D}}==
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.algorithm;
import std.array;
import std.range;
Line 507 ⟶ 626:
writefln("Order %d: Size %-4d x %d! x %d! => Total %d", n, size, n, n - 1, f);
}
}</langsyntaxhighlight>
{{out}}
<pre>The four reduced latin squares of order 4 are:
Line 544 ⟶ 663:
===The Function===
This task uses [[Permutations/Derangements#F.23]]
<langsyntaxhighlight lang="fsharp">
// Generate Latin Squares in reduced form. Nigel Galloway: July 10th., 2019
let normLS α=
Line 551 ⟶ 670:
let rec normLS n g=seq{for i in fG n N.[g] do if g=α-2 then yield [|1..α|]::(List.rev (i::n)) else yield! normLS (i::n) (g+1)}
match α with 1->seq[[[|1|]]] |2-> seq[[[|1;2|];[|2;1|]]] |_->Seq.collect(fun n->normLS [n] 1) N.[0]
</syntaxhighlight>
</lang>
===The Task===
<langsyntaxhighlight lang="fsharp">
normLS 4 |> Seq.iter(fun n->List.iter(printfn "%A") n;printfn "");;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 578 ⟶ 697:
[|4; 3; 2; 1|]
</pre>
<langsyntaxhighlight lang="fsharp">
let rec fact n g=if n<2 then g else fact (n-1) n*g
[1..6] |> List.iter(fun n->let nLS=normLS n|>Seq.length in printfn "order=%d number of Reduced Latin Squares nLS=%d nLS*n!*(n-1)!=%d" n nLS (nLS*(fact n 1)*(fact (n-1) 1)))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 594 ⟶ 713:
=={{header|Go}}==
This reuses the dList function from the [[Permutations/Derangements#Go]] task, suitably adjusted for the present one.
<langsyntaxhighlight lang="go">package main
 
import (
Line 730 ⟶ 849:
fmt.Printf("Order %d: Size %-4d x %d! x %d! => Total %d\n", n, size, n, n-1, f)
}
}</langsyntaxhighlight>
 
{{out}}
Line 766 ⟶ 885:
Order 6: Size 9408 x 6! x 5! => Total 812851200
</pre>
 
=={{header|Haskell}}==
The solution uses permutation generator given by '''Data.List''' package and List monad for generating all possible latin squares as a fold of permutation list.
 
<syntaxhighlight lang="haskell">import Data.List (permutations, (\\))
import Control.Monad (foldM, forM_)
 
latinSquares :: Eq a => [a] -> [[[a]]]
latinSquares [] = []
latinSquares set = map reverse <$> squares
where
squares = foldM addRow firstRow perm
perm = tail (groupedPermutations set)
firstRow = pure <$> set
addRow tbl rows = [ zipWith (:) row tbl
| row <- rows
, and $ different (tail row) (tail tbl) ]
different = zipWith $ (not .) . elem
groupedPermutations :: Eq a => [a] -> [[[a]]]
groupedPermutations lst = map (\x -> (x :) <$> permutations (lst \\ [x])) lst
 
printTable :: Show a => [[a]] -> IO ()
printTable tbl = putStrLn $ unlines $ unwords . map show <$> tbl
</syntaxhighlight>
 
It is slightly optimized by grouping permutations by the first element according to a set order. Partitioning reduces the filtering procedure by factor of an initial set size.
 
'''Examples'''
<pre>λ> latinSquares "abc"
[["abc","bca","cab"]]
 
λ> mapM_ printTable $ take 3 $ latinSquares [1..9]
1 2 3 4 5 6 7 8 9
2 9 4 8 1 7 3 6 5
3 8 2 5 9 1 4 7 6
4 7 5 6 2 9 8 1 3
5 6 9 1 3 8 2 4 7
6 5 1 7 4 2 9 3 8
7 4 6 3 8 5 1 9 2
8 3 7 9 6 4 5 2 1
9 1 8 2 7 3 6 5 4
 
1 2 3 4 5 6 7 8 9
2 9 4 8 1 7 3 5 6
3 8 2 5 9 1 4 6 7
4 7 5 6 2 9 8 1 3
5 6 9 1 3 8 2 7 4
6 5 1 7 4 2 9 3 8
7 4 6 3 8 5 1 9 2
8 3 7 9 6 4 5 2 1
9 1 8 2 7 3 6 4 5
 
1 2 3 4 5 6 7 8 9
2 9 4 8 1 7 3 6 5
3 8 2 5 9 1 4 7 6
4 7 5 6 2 9 1 3 8
5 6 9 1 3 8 2 4 7
6 5 1 7 4 2 8 9 3
7 4 6 3 8 5 9 1 2
8 3 7 9 6 4 5 2 1
9 1 8 2 7 3 6 5 4</pre>
 
'''Tasks'''
<syntaxhighlight lang="haskell">task1 = do
putStrLn "Latin squares of order 4:"
mapM_ printTable $ latinSquares [1..4]
 
task2 = do
putStrLn "Sizes of latin squares sets for different orders:"
forM_ [1..6] $ \n ->
let size = length $ latinSquares [1..n]
total = fact n * fact (n-1) * size
fact i = product [1..i]
in printf "Order %v: %v*%v!*%v!=%v\n" n size n (n-1) total</syntaxhighlight>
 
<pre>λ> task1 >> task2
Latin squares of order 4:
1 2 3 4
4 1 2 3
3 4 1 2
2 3 4 1
 
1 2 3 4
2 4 1 3
3 1 4 2
4 3 2 1
 
1 2 3 4
2 1 4 3
4 3 1 2
3 4 2 1
 
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
 
Sizes of latin squares sets for different orders:
Order 1: 1*1!*0!=1
Order 2: 1*2!*1!=2
Order 3: 1*3!*2!=12
Order 4: 4*4!*3!=576
Order 5: 56*5!*4!=161280
Order 6: 9408*6!*5!=812851200</pre>
 
=={{header|J}}==
Implementation:
<syntaxhighlight lang="j">
redlat=: {{
perms=: (A.&i.~ !)~ y
sqs=. i.1 1,y
for_j.}.i.y do.
p=. (j={."1 perms)#perms
sel=.-.+./"1 p +./@:="1/"2 sqs
sqs=.(#~ 1-0*/ .="1{:"2),/sqs,"2 1 sel#"2 p
end.
}}
</syntaxhighlight>
 
Task examples:
 
<syntaxhighlight lang="j"> redlat 4
0 1 2 3
1 0 3 2
2 3 0 1
3 2 1 0
 
0 1 2 3
1 0 3 2
2 3 1 0
3 2 0 1
 
0 1 2 3
1 2 3 0
2 3 0 1
3 0 1 2
 
0 1 2 3
1 3 0 2
2 0 3 1
3 2 1 0
#@redlat every 1 2 3 4 5 6
1 1 1 4 56 9408
(#@redlat every 1 2 3 4 5 6)*(!1 2 3 4 5 6x)*(!0 1 2 3 4 5x)
1 2 12 576 161280 812851200
</syntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">
import java.math.BigInteger;
import java.util.ArrayList;
Line 975 ⟶ 1,241:
 
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,009 ⟶ 1,275:
Size = 6, 9408 * 720 * 120 = 812,851,200
</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with recent versions of gojq''' (e.g. f0faa22 (August 22, 2021))
 
''' Preliminaries'''
<syntaxhighlight lang="jq">def count(s): reduce s as $x (0; .+1);
 
def factorial: reduce range(2;.+1) as $i (1; . * $i);
 
def permutations:
if length == 0 then []
else
range(0;length) as $i
| [.[$i]] + (del(.[$i])|permutations)
end ;
</syntaxhighlight>
'''Latin Squares'''
<syntaxhighlight lang="jq">def clash($row2; $row1):
any(range(0;$row2|length); $row1[.] == $row2[.]);
 
# Input is a row; stream is a stream of rows
def clash(stream):
. as $row | any(stream; clash($row; .)) ;
 
# Emit a stream of latin squares of size .
def latin_squares:
. as $n
 
# Emit a stream of arrays of permutation of 1 .. $n inclusive, and beginning with $i
| def permutations_beginning_with($i):
[$i] + ([range(1; $i), range($i+1; $n + 1)] | permutations);
 
# input: an array of rows, $rows
# output: a stream of all the permutations starting with $i
# that are permissible relative to $rows
def filter_permuted($i):
. as $rows
| permutations_beginning_with($i)
| select( clash($rows[]) | not ) ;
 
# input: an array of the first few rows (at least one) of a latin square
# output: a stream of possible immediate-successor rows
def next_latin_square_row:
filter_permuted(1 + .[-1][0]);
 
# recursion makes completing a latin square a snap
def complete_latin_square:
if length == $n then .
else next_latin_square_row as $next
| . + [$next] | complete_latin_square
end;
 
[[range(1;$n+1)]]
| complete_latin_square ;
</syntaxhighlight>
'''The Task'''
<syntaxhighlight lang="jq">def task:
"The reduced latin squares of order 4 are:",
(4 | latin_squares),
"",
(range(1; 7)
| . as $i
| count(latin_squares) as $c
| ($c * factorial * ((.-1)|factorial)) as $total
| "There are \($c) reduced latin squares of order \(.); \($c) * \(.)! * \(.-1)! is \($total)"
) ;
 
task</syntaxhighlight>
{{out}}
Invocation: jq -nrc -f latin-squares.jq
<pre>
The reduced latin squares of order 4 are:
[[1,2,3,4],[2,1,4,3],[3,4,1,2],[4,3,2,1]]
[[1,2,3,4],[2,1,4,3],[3,4,2,1],[4,3,1,2]]
[[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3]]
[[1,2,3,4],[2,4,1,3],[3,1,4,2],[4,3,2,1]]
 
There are 1 reduced latin squares of order 1; 1 * 1! * 0! is 1
There are 1 reduced latin squares of order 2; 1 * 2! * 1! is 2
There are 1 reduced latin squares of order 3; 1 * 3! * 2! is 12
There are 4 reduced latin squares of order 4; 4 * 4! * 3! is 576
There are 56 reduced latin squares of order 5; 56 * 5! * 4! is 161280
There are 9408 reduced latin squares of order 6; 9408 * 6! * 5! is 812851200
</pre>
 
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using Combinatorics
 
clash(row2, row1::Vector{Int}) = any(i -> row1[i] == row2[i], 1:length(row2))
Line 1,052 ⟶ 1,404:
testlatinsquares()
</langsyntaxhighlight>{{out}}
<pre>
The four reduced latin squares of order 4 are:
Line 1,085 ⟶ 1,437:
=={{header|Kotlin}}==
{{trans|D}}
<langsyntaxhighlight lang="scala">typealias Matrix = MutableList<MutableList<Int>>
 
fun dList(n: Int, sp: Int): Matrix {
Line 1,205 ⟶ 1,557:
println("Order $n: Size %-4d x $n! x ${n - 1}! => Total $f".format(size))
}
}</langsyntaxhighlight>
{{out}}
<pre>The four reduced latin squares of order 4 are:
Line 1,241 ⟶ 1,593:
=={{header|MiniZinc}}==
===The Model (lsRF.mnz)===
<syntaxhighlight lang="minizinc">
<lang MiniZinc>
%Latin Squares in Reduced Form. Nigel Galloway, September 5th., 2019
include "alldifferent.mzn";
Line 1,247 ⟶ 1,599:
array[1..N,1..N] of var 1..N: p; constraint forall(n in 1..N)(p[1,n]=n /\ p[n,1]=n);
constraint forall(n in 1..N)(alldifferent([p[n,g]|g in 1..N])/\alldifferent([p[g,n]|g in 1..N]));
</syntaxhighlight>
</lang>
===The Tasks===
;displaying the four reduced Latin Squares of order 4
<syntaxhighlight lang="minizinc">
<lang MiniZinc>
include "lsRF.mzn";
output [show_int(1,p[i,j])++
Line 1,258 ⟶ 1,610:
else "" endif
| i,j in 1..4 ] ++ ["\n"];
</syntaxhighlight>
</lang>
When the above is run using minizinc --all-solutions -DN=4 the following is produced:
{{out}}
Line 1,337 ⟶ 1,689:
=={{header|Nim}}==
{{trans|Go, Python, D, Kotlin}}
We use the Go algorithm but have chosen to create two types, Row and matrixMatrix, to simulate sequences starting at index 1. So, the indexes and tests are somewhat different.
 
<langsyntaxhighlight Nimlang="nim">import algorithm, math, sequtils, strformat
 
type
Line 1,446 ⟶ 1,798:
let size = reducedLatinSquares(n, false)
let f = fac(n - 1)^2 * n * size
echo &"Order {n}: Size {size:<4} x {n}! x {n - 1}! => Total {f}"</langsyntaxhighlight>
 
{{out}}
Line 1,481 ⟶ 1,833:
=={{header|Perl}}==
It takes a little under 2 minutes to find order 7.
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Latin_Squares_in_reduced_form
Line 1,513 ⟶ 1,865:
length $s <= 1 ? $s :
map { my $f = $_; map "$f$_", perm( $s =~ s/$_//r ) } split //, $s;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,554 ⟶ 1,906:
A Simple backtracking search.<br>
aside: in phix here is no difference between res[r][c] and res[r,c]. I mixed them here, using whichever felt the more natural to me.
<!--<syntaxhighlight lang="phix">-->
<lang Phix>string aleph = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
<span style="color: #004080;">string</span> <span style="color: #000000;">aleph</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">rfls</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">count_only</span><span style="color: #0000FF;">=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aleph</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- too big...</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">count_only</span><span style="color: #0000FF;">?</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- {1..n}</span>
<span style="color: #000000;">vcs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- valid for cols</span>
<span style="color: #000000;">vrs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- valid for rows</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (main workspace/one element of result)</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">count_only</span><span style="color: #0000FF;">?</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:{})</span>
<span style="color: #000000;">vcs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- (not strictly necessary)</span>
<span style="color: #000000;">vrs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- """</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">&</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">vrs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">vcs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">-- place with backtrack:
-- if we successfully place [n,n] add to results and backtrack
-- terminate when we fail to place or backtrack from [2,2]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">rrc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">rrc</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- backtrack (/undo)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">vrs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">][</span><span style="color: #000000;">rrc</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- sanity check</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">vcs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">][</span><span style="color: #000000;">rrc</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- ""</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">vrs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">][</span><span style="color: #000000;">rrc</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rrc</span>
<span style="color: #000000;">vcs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">][</span><span style="color: #000000;">rrc</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rrc</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">rrc</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">vrs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">and</span> <span style="color: #000000;">vcs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #000000;">vrs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">vcs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span> <span style="color: #008080;">and</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count_only</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">result</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000080;font-style:italic;">-- (here, backtracking == not advancing)</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">else</span>
<span style="color: #000080;font-style:italic;">-- backtrack</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">and</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">reduced_form_latin_squares</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rfls</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">line</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">aleph</span><span style="color: #0000FF;">[</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">line</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"There are %d reduced form latin squares of order %d:\n%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">reduced_form_latin_squares</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
function rfls(integer n, bool count_only=true)
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
if n>length(aleph) then ?9/0 end if -- too big...
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">6</span> <span style="color: #008080;">do</span>
if n=1 then return iff(count_only?1:{{1}}) end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">size</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rfls</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
sequence tn = tagset(n), -- {1..n}
<span style="color: #004080;">atom</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">size</span>
vcs = repeat(tn,n), -- valid for cols
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Order %d: Size %-4d x %d! x %d! =&gt; Total %d\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">size</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">})</span>
vrs = repeat(tn,n), -- valid for rows
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
res = repeat(tn,n) -- (main workspace/one element of result)
<!--</syntaxhighlight>-->
object result = iff(count_only?0:{})
vcs[1] = {} -- (not strictly necessary)
vrs[1] = {} -- """
for i=2 to n do
res[i] = i & repeat(0,n-1)
vrs[i][i] = 0
vcs[i][i] = 0
end for
integer r = 2, c = 2
while true do
-- place with backtrack:
-- if we successfully place [n,n] add to results and backtrack
-- terminate when we fail to place or backtrack from [2,2]
integer rrc = res[r,c]
if rrc!=0 then -- backtrack (/undo)
if vrs[r][rrc]!=0 then ?9/0 end if -- sanity check
if vcs[c][rrc]!=0 then ?9/0 end if -- ""
res[r,c] = 0
vrs[r][rrc] = rrc
vcs[c][rrc] = rrc
end if
bool found = false
for i=rrc+1 to n do
if vrs[r][i] and vcs[c][i] then
res[r,c] = i
vrs[r][i] = 0
vcs[c][i] = 0
found = true
exit
end if
end for
if found then
if r=n and c=n then
if count_only then
result += 1
else
result = append(result,res)
end if
-- (here, backtracking == not advancing)
elsif c=n then
c = 2
r += 1
else
c += 1
end if
else
-- backtrack
if r=2 and c=2 then exit end if
c -= 1
if c=1 then
r -= 1
c = n
end if
end if
end while
return result
end function
procedure reduced_form_latin_squares(integer n)
sequence res = rfls(n,false)
for k=1 to length(res) do
for i=1 to n do
string line = ""
for j=1 to n do
line &= aleph[res[k][i][j]]
end for
res[k][i] = line
end for
res[k] = join(res[k],"\n")
end for
string r = join(res,"\n\n")
printf(1,"There are %d reduced form latin squares of order %d:\n%s\n",{length(res),n,r})
end procedure
 
reduced_form_latin_squares(4)
puts(1,"\n")
for n=1 to 6 do
integer size = rfls(n)
atom f = factorial(n)*factorial(n-1)*size
printf(1,"Order %d: Size %-4d x %d! x %d! => Total %d\n", {n, size, n, n-1, f})
end for</lang>
{{out}}
<pre>
Line 1,679 ⟶ 2,033:
"2 minutes and 23s"
</pre>
 
=={{header|Picat}}==
Using Constraint modelling.
====The four solutions for N=4====
<syntaxhighlight lang="picat">import cp.
 
main =>
N = 4,
latin_square_reduced_form(N, X),
foreach(Row in X)
println(Row.to_list)
end,
nl,
fail.
 
latin_square_reduced_form(N, X) =>
X = new_array(N,N),
X :: 1..N,
foreach(I in 1..N)
all_different([X[I,J] : J in 1..N]),
all_different([X[J,I] : J in 1..N]),
X[1,I] #= I,
X[I,1] #= I
end,
solve(X).</syntaxhighlight>
 
{{out}}
<pre>[1,2,3,4]
[2,1,4,3]
[3,4,1,2]
[4,3,2,1]
 
[1,2,3,4]
[2,1,4,3]
[3,4,2,1]
[4,3,1,2]
 
[1,2,3,4]
[2,3,4,1]
[3,4,1,2]
[4,1,2,3]
 
[1,2,3,4]
[2,4,1,3]
[3,1,4,2]
[4,3,2,1]</pre>
 
====Number of solutions====
<syntaxhighlight lang="picat">import cp.
 
main =>
foreach(N in 1..7)
Count = count_all(latin_square_reduced_form(N, _X)),
printf("%2d %10d x %d! x %d! %16w\n",N,Count,N,N-1, Count*factorial(N)*factorial(N-1))
end,
nl.</syntaxhighlight>
 
{{out}}
<pre> 1 1 x 1! x 0! 1
2 1 x 2! x 1! 2
3 1 x 3! x 2! 12
4 4 x 4! x 3! 576
5 56 x 5! x 4! 161280
6 9408 x 6! x 5! 812851200
7 16942080 x 7! x 6! 61479419904000</pre>
 
For N=1..6 this model takes 23ms. For N=1..7 it takes 28.1s.
 
=={{header|Python}}==
{{trans|D}}
<langsyntaxhighlight lang="python">def dList(n, start):
start -= 1 # use 0 basing
a = range(n)
Line 1,778 ⟶ 2,199:
f = factorial(n - 1)
f *= f * n * size
print "Order %d: Size %-4d x %d! x %d! => Total %d" % (n, size, n, n - 1, f)</langsyntaxhighlight>
{{out}}
<pre>The four reduced latin squares of order 4 are:
Line 1,814 ⟶ 2,235:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line># utilities: factorial, sub-factorial, derangements
sub postfix:<!>($n) { (constant f = 1, |[\×] 1..*)[$n] }
sub prefix:<!>($n) { (1, 0, 1, -> $a, $b { ($++ + 2) × ($b + $a) } ... *)[$n] }
Line 1,844 ⟶ 2,265:
for 1..6 -> $n {
printf "Order $n: Size %-4d x $n! x {$n-1}! => Total %d\n", $_, $_ * $n! * ($n-1)! given LS-reduced($n).elems
}</langsyntaxhighlight>
{{out}}
<pre>1 2 3 4
Line 1,871 ⟶ 2,292:
Order 4: Size 4 x 4! x 3! => Total 576
Order 5: Size 56 x 5! x 4! => Total 161280
Order 6: Size 9408 x 6! x 5! => Total 812851200</pre>
 
=={{header|Ruby}}==
{{trans|D}}
<syntaxhighlight lang="ruby">def printSquare(a)
for row in a
print row, "\n"
end
print "\n"
end
 
def dList(n, start)
start = start - 1 # use 0 based indexing
a = Array.new(n) {|i| i}
a[0], a[start] = a[start], a[0]
a[1..] = a[1..].sort
first = a[1]
 
r = []
recurse = lambda {|last|
if last == first then
# bottom of recursion, reached once for each permutation
# test if permutation is deranged
a[1..].each_with_index {|v, j|
if j + 1 == v then
return # no, ignore it
end
}
# yes, save a copy with 1 based indexing
b = a.map { |i| i + 1 }
r << b
return
end
 
i = last
while i >= 1 do
a[i], a[last] = a[last], a[i]
recurse.call(last - 1)
a[i], a[last] = a[last], a[i]
i = i - 1
end
}
 
recurse.call(n - 1)
return r
end
 
def reducedLatinSquares(n, echo)
if n <= 0 then
if echo then
print "[]\n\n"
end
return 0
end
if n == 1 then
if echo then
print "[1]\n\n"
end
return 1
end
 
rlatin = Array.new(n) { Array.new(n, Float::NAN)}
 
# first row
for j in 0 .. n - 1
rlatin[0][j] = j + 1
end
 
count = 0
recurse = lambda {|i|
rows = dList(n, i)
 
for r in 0 .. rows.length - 1
rlatin[i - 1] = rows[r].dup
catch (:outer) do
for k in 0 .. i - 2
for j in 1 .. n - 1
if rlatin[k][j] == rlatin[i - 1][j] then
if r < rows.length - 1 then
throw :outer
end
if i > 2 then
return
end
end
end
end
if i < n then
recurse.call(i + 1)
else
count = count + 1
if echo then
printSquare(rlatin)
end
end
end
end
}
 
# remaining rows
recurse.call(2)
return count
end
 
def factorial(n)
if n == 0 then
return 1
end
prod = 1
for i in 2 .. n
prod = prod * i
end
return prod
end
 
print "The four reduced latin squares of order 4 are:\n"
reducedLatinSquares(4, true)
 
print "The size of the set of reduced latin squares for the following orders\n"
print "and hence the total number of latin squares of these orders are:\n"
for n in 1 .. 6
size = reducedLatinSquares(n, false)
f = factorial(n - 1)
f = f * f * n * size
print "Order %d Size %-4d x %d! x %d! => Total %d\n" % [n, size, n, n - 1, f]
end</syntaxhighlight>
{{out}}
<pre>The four reduced latin squares of order 4 are:
[1, 2, 3, 4]
[2, 1, 4, 3]
[3, 4, 1, 2]
[4, 3, 2, 1]
 
[1, 2, 3, 4]
[2, 1, 4, 3]
[3, 4, 2, 1]
[4, 3, 1, 2]
 
[1, 2, 3, 4]
[2, 4, 1, 3]
[3, 1, 4, 2]
[4, 3, 2, 1]
 
[1, 2, 3, 4]
[2, 3, 4, 1]
[3, 4, 1, 2]
[4, 1, 2, 3]
 
The size of the set of reduced latin squares for the following orders
and hence the total number of latin squares of these orders are:
Order 1 Size 1 x 1! x 0! => Total 1
Order 2 Size 1 x 2! x 1! => Total 2
Order 3 Size 1 x 3! x 2! => Total 12
Order 4 Size 4 x 4! x 3! => Total 576
Order 5 Size 56 x 5! x 4! => Total 161280
Order 6 Size 9408 x 6! x 5! => Total 812851200</pre>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Option Strict On
 
Imports Matrix = System.Collections.Generic.List(Of System.Collections.Generic.List(Of Integer))
 
Module Module1
 
Sub Swap(Of T)(ByRef a As T, ByRef b As T)
Dim u = a
a = b
b = u
End Sub
 
Sub PrintSquare(latin As Matrix)
For Each row In latin
Dim it = row.GetEnumerator
Console.Write("[")
If it.MoveNext Then
Console.Write(it.Current)
End If
While it.MoveNext
Console.Write(", ")
Console.Write(it.Current)
End While
Console.WriteLine("]")
Next
Console.WriteLine()
End Sub
 
Function DList(n As Integer, start As Integer) As Matrix
start -= 1 REM use 0 based indexes
Dim a = Enumerable.Range(0, n).ToArray
a(start) = a(0)
a(0) = start
Array.Sort(a, 1, a.Length - 1)
Dim first = a(1)
REM recursive closure permutes a[1:]
Dim r As New Matrix
 
Dim Recurse As Action(Of Integer) = Sub(last As Integer)
If last = first Then
REM bottom of recursion. you get here once for each permutation
REM test if permutation is deranged.
For j = 1 To a.Length - 1
Dim v = a(j)
If j = v Then
Return REM no, ignore it
End If
Next
REM yes, save a copy with 1 based indexing
Dim b = a.Select(Function(v) v + 1).ToArray
r.Add(b.ToList)
Return
End If
For i = last To 1 Step -1
Swap(a(i), a(last))
Recurse(last - 1)
Swap(a(i), a(last))
Next
End Sub
Recurse(n - 1)
Return r
End Function
 
Function ReducedLatinSquares(n As Integer, echo As Boolean) As ULong
If n <= 0 Then
If echo Then
Console.WriteLine("[]")
Console.WriteLine()
End If
Return 0
End If
If n = 1 Then
If echo Then
Console.WriteLine("[1]")
Console.WriteLine()
End If
Return 1
End If
 
Dim rlatin As New Matrix
For i = 0 To n - 1
rlatin.Add(New List(Of Integer))
For j = 0 To n - 1
rlatin(i).Add(0)
Next
Next
REM first row
For j = 0 To n - 1
rlatin(0)(j) = j + 1
Next
 
Dim count As ULong = 0
Dim Recurse As Action(Of Integer) = Sub(i As Integer)
Dim rows = DList(n, i)
 
For r = 0 To rows.Count - 1
rlatin(i - 1) = rows(r)
For k = 0 To i - 2
For j = 1 To n - 1
If rlatin(k)(j) = rlatin(i - 1)(j) Then
If r < rows.Count - 1 Then
GoTo outer
End If
If i > 2 Then
Return
End If
End If
Next
Next
If i < n Then
Recurse(i + 1)
Else
count += 1UL
If echo Then
PrintSquare(rlatin)
End If
End If
outer:
While False
REM empty
End While
Next
End Sub
 
REM remiain rows
Recurse(2)
Return count
End Function
 
Function Factorial(n As ULong) As ULong
If n <= 0 Then
Return 1
End If
Dim prod = 1UL
For i = 2UL To n
prod *= i
Next
Return prod
End Function
 
Sub Main()
Console.WriteLine("The four reduced latin squares of order 4 are:")
Console.WriteLine()
ReducedLatinSquares(4, True)
 
Console.WriteLine("The size of the set of reduced latin squares for the following orders")
Console.WriteLine("and hence the total number of latin squares of these orders are:")
Console.WriteLine()
For n = 1 To 6
Dim nu As ULong = CULng(n)
 
Dim size = ReducedLatinSquares(n, False)
Dim f = Factorial(nu - 1UL)
f *= f * nu * size
Console.WriteLine("Order {0}: Size {1} x {2}! x {3}! => Total {4}", n, size, n, n - 1, f)
Next
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>The four reduced latin squares of order 4 are:
 
[1, 2, 3, 4]
[2, 1, 4, 3]
[3, 4, 1, 2]
[4, 3, 2, 1]
 
[1, 2, 3, 4]
[2, 1, 4, 3]
[3, 4, 2, 1]
[4, 3, 1, 2]
 
[1, 2, 3, 4]
[2, 4, 1, 3]
[3, 1, 4, 2]
[4, 3, 2, 1]
 
[1, 2, 3, 4]
[2, 3, 4, 1]
[3, 4, 1, 2]
[4, 1, 2, 3]
 
The size of the set of reduced latin squares for the following orders
and hence the total number of latin squares of these orders are:
 
Order 1: Size 1 x 1! x 0! => Total 1
Order 2: Size 1 x 2! x 1! => Total 2
Order 3: Size 1 x 3! x 2! => Total 12
Order 4: Size 4 x 4! x 3! => Total 576
Order 5: Size 56 x 5! x 4! => Total 161280
Order 6: Size 9408 x 6! x 5! => Total 812851200</pre>
 
Line 1,878 ⟶ 2,648:
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./sort" for Sort
import "./math" for Int
import "./fmt" for Fmt
 
// generate derangements of first n numbers, with 'start' in first place.
Line 1,992 ⟶ 2,762:
f = f * f * n * size
Fmt.print("Order $d: Size $-4d x $d! x $d! => Total $d", n, size, n, n-1, f)
}</langsyntaxhighlight>
 
{{out}}
Line 2,032 ⟶ 2,802:
{{trans|Go}}
This reuses the dList function from the [[Permutations/Derangements#zkl]] task, suitably adjusted for the present one.
<langsyntaxhighlight lang="zkl">fcn reducedLatinSquare(n,write=False){
if(n<=1) return(n);
rlatin:=n.pump(List(), List.createLong(n,0).copy); // matrix of zeros
Line 2,071 ⟶ 2,841:
println();
}
fcn fact(n){ ([1..n]).reduce('*,1) }</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">println("The four reduced latin squares of order 4 are:");
reducedLatinSquare(4,True);
 
Line 2,080 ⟶ 2,850:
size,f,f := reducedLatinSquare(n), fact(n - 1), f*f*n*size;;
println("Order %d: Size %-4d x %d! x %d! -> Total %,d".fmt(n,size,n,n-1,f));
}</langsyntaxhighlight>
{{out}}
<pre>
9,485

edits