praxis

Various programming exercises.
Log | Files | Refs

commit d6a1d6c2114f5a076ddcc828de869806bb765d65
parent 93c1c0aa179fb8e13fcbe100a75168acc1c48fbf
Author: Jared Tobin <jared@jtobin.ca>
Date:   Wed, 27 Jun 2018 11:41:38 +1200

Add tally exercise.

Diffstat:
A20180514_tally/Tally.hs | 29+++++++++++++++++++++++++++++
1 file changed, 29 insertions(+), 0 deletions(-)

diff --git a/20180514_tally/Tally.hs b/20180514_tally/Tally.hs @@ -0,0 +1,29 @@ +{-# OPTIONS_GHC -Wall #-} +{-# LANGUAGE BangPatterns #-} + +import Data.Char (isLower, toLower) +import Data.List as L (foldl', sortBy) +import Data.Function (on) +import Data.Monoid (mempty) +import qualified Data.Map.Strict as MS + +tally :: String -> [(Char, Int)] +tally = sortBy (flip compare `on` snd) . MS.toList . accum + +accum :: String -> MS.Map Char Int +accum = L.foldl' alg mempty where + alg !acc score = + let adjuster val = case (val, isLower score) of + (Nothing, True) -> Just 1 + (Nothing, False) -> Just (negate 1) + (Just s, True) -> Just (succ s) + (Just s, False) -> Just (pred s) + + in MS.alter adjuster (toLower score) acc + +test :: String +test = "EbAAdbBEaBaaBBdAccbeebaec" + +main :: IO () +main = print (tally test) +