RosettaCodeData/Task/Knuth-shuffle/Haskell/knuth-shuffle-1.hs
2023-07-01 13:44:08 -04:00

17 lines
470 B
Haskell

import System.Random (randomRIO)
mkRands :: Int -> IO [Int]
mkRands = mapM (randomRIO . (,) 0) . enumFromTo 1 . pred
replaceAt :: Int -> a -> [a] -> [a]
replaceAt i c l =
let (a, b) = splitAt i l
in a ++ c : drop 1 b
swapElems :: (Int, Int) -> [a] -> [a]
swapElems (i, j) xs
| i == j = xs
| otherwise = replaceAt j (xs !! i) $ replaceAt i (xs !! j) xs
knuthShuffle :: [a] -> IO [a]
knuthShuffle xs = (foldr swapElems xs . zip [1 ..]) <$> mkRands (length xs)