{- Seth Brown
   2014-12-13
   GHC 7.8.3
   sethbrown AT drbunsen DOT ORG
   Copyright 2014 Seth Brown. All rights reserved.
   data from: http://www.beeradvocate.com/lists/top/

   $ runghc ba-top-breweries.hs < data.txt
   ======================================
    Hill Farmstead Brewery,24
    Brasserie Cantillon,11
    The Bruery,10
    Russian River Brewing Company,9
    Alpine Beer Company,8
    Toppling Goliath Brewing Company,6
    Trillium Brewing Company,6
    AleSmith Brewing Company,5
    Firestone Walker Brewing Co.,5
    Founders Brewing Company,5
-}

import qualified Data.ByteString.Lazy.Char8 as LC
import qualified Data.List as DL
import qualified Control.Arrow as CA

main = LC.getContents >>= mapM_ putStrLn . proc

-- process input data and count most frequent breweries
proc xs =   top10
          . freqs
          . names 
          $ process xs

-- reduce over the input and capture brewery names
names xs = DL.foldl (\acc el -> if mod (fst el) 3 == 1
                                then (acc ++ [snd el])
                                else acc) [] xs

-- count and sort the frequencies of each brewery name
freqs xs =   DL.sortBy sortDescFreq
           . map (head CA.&&& length) . DL.group $ DL.sort xs 
             where
                sortDescFreq (_, i) (_, j)
                     | i > j = LT
                     | i < j = GT
                     | i == j = compare i j

-- filter the most frequent breweries
top10 xs = format . DL.takeWhile (\(i, el) -> i < 10) $ zip [0..] xs

-- stringify results into a list
format = map (\(i,(el, freq)) -> DL.intercalate "," [el, show freq])

-- lazy unpack bytestrings to an enumerated list of lines
process xs = (DL.zip [0..] . DL.lines . LC.unpack) xs