summaryrefslogtreecommitdiff
path: root/lec03
diff options
context:
space:
mode:
authorEdoardo La Greca2025-07-04 17:54:02 +0200
committerEdoardo La Greca2025-07-04 17:55:26 +0200
commit96d76454ba52151f908b2edbe30a1d5f9568bc87 (patch)
tree76a66b414f8ccb481969bf729096e0336b59cc6f /lec03
parent0935026210bbedfe1d261622f4dd8976b03de54e (diff)
add third exercise of lecture 3
Diffstat (limited to 'lec03')
-rw-r--r--lec03/Golf.hs48
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]