-------------------- start of latin.curry ----------------------------
-- upto is a nondeterministic function that evaluates to
-- a number from 1 upto n
upto 1 = 1
upto n | n > 1 = n ? upto (n-1)
-- check if the lists r s have no element with the same value at the
-- same position
elems_diff r s = and $ zipWith (/=) r s
-- extend takes a list of columns, and extends each column with a
-- number for the next row. It checks the number agains the column and
-- against the previous numbers in the row.
extend :: [[Int]] -> Int -> [[Int]]
extend cols n = addnum cols [] where
addnum [] _ = []
addnum (col:cs) prev
| x =:= upto n &
(x `elem` prev) =:= False &
(x `elem` col) =:= False = (x:col) : addnum cs (x
rev)
where x free
latin_square n = latin_square_ n
where latin_square_ 0 = replicate n [] -- initalize columns to nil
latin_square_ m | m > 0 = extend (latin_square_ (m-1)) n
square2str s = unlines $ map format_col s
where format_col col = unwords $ map show col
main = mapIO_ (putStrLn . square2str) (findall (\s -> s =:= latin_square 5))
------------------------- end latin.curry -----------------------------