RosettaCodeData/Task/Random-Latin-squares/Haskell/random-latin-squares-1.hs
2023-07-01 13:44:08 -04:00

28 lines
702 B
Haskell

import Data.List (permutations, (\\))
latinSquare :: Eq a => [a] -> [a] -> [[a]]
latinSquare [] [] = []
latinSquare c r
| head r /= head c = []
| otherwise = reverse <$> foldl addRow firstRow perms
where
-- permutations grouped by the first element
perms =
tail $
fmap
(fmap . (:) <*> (permutations . (r \\) . return))
c
firstRow = pure <$> r
addRow tbl rows =
head
[ zipWith (:) row tbl
| row <- rows,
and $ different (tail row) (tail tbl)
]
different = zipWith $ (not .) . elem
printTable :: Show a => [[a]] -> IO ()
printTable tbl =
putStrLn $
unlines $
unwords . map show <$> tbl