Haskell Quiz/Count and Say/Solution Dolio  Revision history
http://www.haskell.org/haskellwiki/index.php?title=Haskell_Quiz/Count_and_Say/Solution_Dolio&action=history
Revision history for this page on the wiki
en
MediaWiki 1.19.51+deb7u1
Sat, 26 Jul 2014 16:48:40 GMT

Dolio: new page
http://www.haskell.org/haskellwiki/index.php?title=Haskell_Quiz/Count_and_Say/Solution_Dolio&diff=15595&oldid=prev
http://www.haskell.org/haskellwiki/index.php?title=Haskell_Quiz/Count_and_Say/Solution_Dolio&diff=15595&oldid=prev
<p>new page</p>
<p><b>New page</b></p><div>[[Category:Haskell Quiz solutionsCount and Say]]<br />
<br />
While reading the description for this quiz, I thought it was a perfect problem to make use of the handy clusterBy function Tom Moertel recently [http://blog.moertel.com/articles/2007/09/01/clusterbyahandylittlefunctionforthetoolbox discussed on his blog]. So, I whipped up this solution to see how it'd work.<br />
<br />
<haskell><br />
module Main (main, say, search) where<br />
<br />
import Data.Char<br />
import Data.List<br />
import Data.Maybe<br />
import qualified Data.Map as M<br />
<br />
import Control.Arrow<br />
import Control.Monad<br />
import System.Environment<br />
<br />
clusterBy :: Ord b => (a > b) > [a] > [[a]]<br />
clusterBy p = M.elems . M.map reverse . M.fromListWith (++) . map (p &&& return)<br />
<br />
cluster :: Ord a => [a] > [[a]]<br />
cluster = clusterBy id<br />
<br />
speak :: Int > String<br />
speak 1 = "ONE"<br />
speak 2 = "TWO"<br />
speak 3 = "THREE"<br />
speak 4 = "FOUR"<br />
speak 5 = "FIVE"<br />
speak 6 = "SIX"<br />
speak 7 = "SEVEN"<br />
speak 8 = "EIGHT"<br />
speak 9 = "NINE"<br />
speak 10 = "TEN"<br />
speak 11 = "ELEVEN"<br />
speak 12 = "TWELVE"<br />
speak 13 = "THIRTEEN"<br />
speak 15 = "FIFTEEN"<br />
speak 18 = "EIGHTEEN"<br />
speak 20 = "TWENTY"<br />
speak 30 = "THIRTY"<br />
speak 40 = "FORTY"<br />
speak 50 = "FIFTY"<br />
speak 60 = "SIXTY"<br />
speak 70 = "SEVENTY"<br />
speak 80 = "EIGHTY"<br />
speak 90 = "NINETY"<br />
speak n  n < 20 = speak (n  10) ++ "TEEN"<br />
 n < 100 = speak (n  m) ++ speak m<br />
 otherwise = error "Unanticipated number."<br />
where m = n `mod` 10<br />
<br />
say :: String > String<br />
say = intercalate " " . map (\c > speak (length c) ++ " " ++ take 1 c)<br />
. cluster . filter isAlpha<br />
<br />
search :: String > Int<br />
search = (1+) . fromJust . search' []<br />
where search' l s = elemIndex s l `mplus` search' (s:l) (say s)<br />
<br />
main = print . search . map toUpper . head =<< getArgs<br />
</haskell></div>
Fri, 14 Sep 2007 20:45:35 GMT Dolio http://www.haskell.org/haskellwiki/Talk:Haskell_Quiz/Count_and_Say/Solution_Dolio