RosettaCodeData/Task/Kolakoski-sequence/Haskell/kolakoski-sequence.hs
2023-07-01 13:44:08 -04:00

32 lines
1,004 B
Haskell

import Data.List (group)
import Control.Monad (forM_)
replicateAtLeastOne :: Int -> a -> [a]
replicateAtLeastOne n x = x : replicate (n-1) x
zipWithLazy :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWithLazy f ~(x:xs) ~(y:ys) = f x y : zipWithLazy f xs ys
kolakoski :: [Int] -> [Int]
kolakoski items = s
where s = concat $ zipWithLazy replicateAtLeastOne s $ cycle items
rle :: Eq a => [a] -> [Int]
rle = map length . group
sameAsRleUpTo :: Int -> [Int] -> Bool
sameAsRleUpTo n s = r == take (length r) prefix
where prefix = take n s
r = init $ rle prefix
main :: IO ()
main = forM_ [([1, 2], 20),
([2, 1], 20),
([1, 3, 1, 2], 30),
([1, 3, 2, 1], 30)]
$ \(items, n) -> do
putStrLn $ "First " ++ show n ++ " members of the sequence generated by " ++ show items ++ ":"
let s = kolakoski items
print $ take n s
putStrLn $ "Possible Kolakoski sequence? " ++ show (sameAsRleUpTo n s)
putStrLn ""