Advertisement
banovski

Ninety-Nine Haskell Problems: #6

Feb 20th, 2025 (edited)
423
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 3.60 KB | Source Code | 1 0
  1. -- Ninety-Nine Haskell Problems: Problem 6: find out whether a list is
  2. -- a palindrome.
  3.  
  4. -- Displaying results
  5.  
  6. main :: IO ()
  7. main = do
  8.   printResult l0
  9.   printResult l1
  10.   printResult l2
  11.   printResult l3
  12.   printResult l4
  13.   printResult l5
  14.  
  15. printResult :: Eq a => [a] -> IO ()
  16. printResult list = do
  17.   mapM_ (putStr . formatter) $ zip [1 ..] $ funcList <*> [list]
  18.   putStrLn ""
  19.  
  20. formatter :: (Show a) => (Int, a) -> String
  21. formatter (x, y) = show x ++ ") " ++ show y ++ "; "
  22.  
  23. funcList :: Eq a => [[a] -> Bool]
  24. funcList = [one, two, three, four, five, six, seven, eight]
  25.  
  26. -- Test lists
  27.  
  28. l0 :: [()]
  29. l0 = []
  30.  
  31. l1 :: [Int]
  32. l1 = [1,2,3]
  33.  
  34. l2 :: String
  35. l2 = "madamimadam"
  36.  
  37. l3 :: [Int]
  38. l3 = [1,2,4,8,16,8,4,2,1]
  39.  
  40. l4 :: [Bool]
  41. l4 = [True, False, False, True]
  42.  
  43. l5 :: [Float]
  44. l5 = [1.1]
  45.  
  46. -- palindrome detection functions definitions
  47. -- efficiency is measured in ticks; test list size: 2,000,000 values;
  48. -- optimization -Odph
  49.  
  50. -- 103,02
  51. one :: Eq a => [a] -> Bool
  52. one list = list == reverse list
  53.  
  54. -- 103,037
  55. two :: Eq a => [a] -> Bool
  56. two list = list == foldl (flip (:)) [] list
  57.  
  58. -- 149,995
  59. three :: Eq a => [a] -> Bool
  60. three [] = True
  61. three [_] = True
  62. three list =
  63.   let
  64.     reversedList = snd reversedAndMeasured
  65.     listLength = fst reversedAndMeasured
  66.     reversedAndMeasured = reverseAndMeasure list
  67.     reverseAndMeasure =
  68.       foldl (\(n, xs) x -> (n + 1, x:xs)) (0, []) :: [a] -> (Int, [a])
  69.     compareFirstHalves ol rl ll = aux ol rl (ll `div` 2 - 1) 0 True
  70.       where
  71.         aux (o:os) (r:rs) mi ci bool
  72.           | o /= r = False
  73.           | ci > mi = bool
  74.           | otherwise = aux os rs mi (ci + 1) bool
  75.   in
  76.     compareFirstHalves list reversedList listLength
  77.  
  78. -- 109,917
  79. four :: Eq a => [a] -> Bool
  80. four list =
  81.   let
  82.   fullLength = length list
  83.   firstHalf = div fullLength 2
  84.   firstHalfAdjusted = fullLength - firstHalf
  85.   in
  86.   reverse (take firstHalf list) == drop firstHalfAdjusted list
  87.  
  88. -- 401200
  89. five :: Eq a => [a] -> Bool
  90. five [] = True
  91. five [_] = True
  92. five list
  93.   | head list == last list = five $ (init . tail) list
  94.   | otherwise = False
  95.  
  96. -- 218500
  97. six :: Eq a => [a] -> Bool
  98. six [] = True
  99. six list = let
  100.   listLength = length list
  101.   maxIndex = listLength - 1
  102.   middleIndex = listLength `div` 2 - 1
  103.   in
  104.   aux list middleIndex 0 maxIndex True
  105.   where
  106.     aux lst mdi mni mxi bv
  107.       | mni > mdi = bv
  108.       | (lst !! mni) /= (lst !! mxi) = False
  109.       | otherwise = aux lst mdi (mni + 1) (mxi - 1) bv
  110.  
  111. -- 224,016
  112. seven :: Eq a => [a] -> Bool
  113. seven [] = True
  114. seven [_] = True
  115. seven list = let
  116.   listLength = length list
  117.   listHalfLength = div listLength 2
  118.   reversedList = reverse list
  119.   in
  120.   take listHalfLength list == take listHalfLength reversedList
  121.  
  122. -- 204,1
  123. eight :: Eq a => [a] -> Bool
  124. eight [] = True
  125. eight [_] = True
  126. eight list = let
  127.   countAndReverse c a [] = (c, a)
  128.   countAndReverse c a (x:xs) = countAndReverse (c + 1) (x:a) xs
  129.   countedAndReversed = countAndReverse 0 [] list
  130.   listLength = fst countedAndReversed
  131.   reversedList = snd countedAndReversed
  132.   listHalfLength = listLength `div` 2
  133.   in
  134.   take listHalfLength list == take listHalfLength reversedList
  135.  
  136. -- 1) True; 2) True; 3) True; 4) True; 5) True; 6) True; 7) True; 8) True;
  137. -- 1) False; 2) False; 3) False; 4) False; 5) False; 6) False; 7) False; 8) False;
  138. -- 1) True; 2) True; 3) True; 4) True; 5) True; 6) True; 7) True; 8) True;
  139. -- 1) True; 2) True; 3) True; 4) True; 5) True; 6) True; 7) True; 8) True;
  140. -- 1) True; 2) True; 3) True; 4) True; 5) True; 6) True; 7) True; 8) True;
  141. -- 1) True; 2) True; 3) True; 4) True; 5) True; 6) True; 7) True; 8) True;
  142.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement