diff options
author | Edoardo La Greca | 2025-07-04 17:54:02 +0200 |
---|---|---|
committer | Edoardo La Greca | 2025-07-04 17:55:26 +0200 |
commit | 96d76454ba52151f908b2edbe30a1d5f9568bc87 (patch) | |
tree | 76a66b414f8ccb481969bf729096e0336b59cc6f | |
parent | 0935026210bbedfe1d261622f4dd8976b03de54e (diff) |
add third exercise of lecture 3
-rw-r--r-- | lec03/Golf.hs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lec03/Golf.hs b/lec03/Golf.hs index de3af42..f4b988b 100644 --- a/lec03/Golf.hs +++ b/lec03/Golf.hs @@ -1,4 +1,6 @@ module Golf where +import Data.List +import Data.Maybe -- Exercise 1 @@ -40,3 +42,49 @@ localMaxima (x1:x2:x3:xs) | all (<x2) [x1,x3] = x2 : localMaxima (x2:x3:xs) | otherwise = localMaxima (x2:x3:xs) localMaxima l = [] + +-- Exercise 3 + +-- Explanation: +-- `Occs` is a type alias for a list of occurrences. +type Occs a = [(a, Int)] + +-- Explanation: +-- `bar` takes two arguments and returns a string that represents a bar from a +-- bar chart. The first argument is the maximum space available for the bar +-- while the second is the bar's length. The function uses two `replicate` calls +-- to first draw the bar and then add some padding in the unused space. If the +-- bar length exceeds the available space, the bar is cut using `drop`, which +-- removes the length in excess. +bar :: Int -> Int -> String +bar max n + | max >= n = replicate n '*' ++ replicate (max-n) ' ' + | otherwise = drop (n-max) $ replicate n '*' + +-- Explanation: +-- `occ` takes a list of occurrences and a single occurring element. With them, +-- it returns the amount of occurrences the element has, or 0 if the element +-- does not occur. +-- I chose to keep this function separate from the main `histogram` function for +-- the sake of readability. I found that histogram is already complex enough to +-- add anything else to it. +occ :: Eq a => Occs a -> a -> Int +occ o e = fromMaybe 0 $ lookup e o + +-- Explanation: +-- `histogram` takes a list of `Integer`s and returns a string that represents a +-- bar chart with the number of occurrences for each value between 0 and 9. The +-- function operates as follows. First, it draw the bars in horizontal style, +-- from left to right. Bars are drawn as the local variable `bars` says: it +-- draws bars for all values from 0 to 9 by mapping those values to the bar +-- function, with the maximum space being the maximum of all the second elements +-- of the occurrence pairs (see `Occs`) and the length being the length of the +-- current value (see `occ`). After drawing the bars, they are transposed, so +-- that they are shown as columns, and a footer is inserted at the beginning. +-- The footer comes first because the chart is then completely reversed (the +-- last row becomes the first, etc.) and the lines are joined using `unlines`. +histogram :: [Integer] -> String +histogram l = unlines $ reverse $ ["0123456789", "=========="] ++ transpose bars + where + count = map (\e -> (head e, length e)) $ group $ sort l + bars = map (bar (maximum $ map snd count) . occ count) [0..9] |