From 96d76454ba52151f908b2edbe30a1d5f9568bc87 Mon Sep 17 00:00:00 2001 From: Edoardo La Greca Date: Fri, 4 Jul 2025 17:54:02 +0200 Subject: add third exercise of lecture 3 --- lec03/Golf.hs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) 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 ( 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] -- cgit v1.2.3