= Solution
Choose each row from the <permutations> of the symbols:
``
squaresRows :: Int -> [[[Int]]]
squaresRows n
| n < 0 = error "negative order"
| otherwise = cp (replicate n (perms [1..n]))
latinRows :: Int -> [[[Int]]]
latinRows = filter valid . squaresRows
``
Every <Latin square> remains a candidate, because each of its rows is one of those <permutations>. Conversely every candidate has valid rows, so only its columns still need checking. There are \b[$(n!)^n$] candidates instead of $n^{n^2}$: at order four, $331\,776$ rather than more than four billion. The improvement is substantial but does not make exhaustive generation practical at arbitrary orders. One can replace `valid` by a column-only test here, since row validity is guaranteed by construction.
Back to article page