Tally.hs (770B)
1 {-# OPTIONS_GHC -Wall #-} 2 {-# LANGUAGE BangPatterns #-} 3 4 import Data.Char (isLower, toLower) 5 import Data.List as L (foldl', sortBy) 6 import Data.Function (on) 7 import Data.Monoid (mempty) 8 import qualified Data.Map.Strict as MS 9 10 tally :: String -> [(Char, Int)] 11 tally = sortBy (flip compare `on` snd) . MS.toList . accum 12 13 accum :: String -> MS.Map Char Int 14 accum = L.foldl' alg mempty where 15 alg !acc score = 16 let adjuster val = case (val, isLower score) of 17 (Nothing, True) -> Just 1 18 (Nothing, False) -> Just (negate 1) 19 (Just s, True) -> Just (succ s) 20 (Just s, False) -> Just (pred s) 21 22 in MS.alter adjuster (toLower score) acc 23 24 test :: String 25 test = "EbAAdbBEaBaaBBdAccbeebaec" 26 27 main :: IO () 28 main = print (tally test) 29