mukesh tiwari | 8 Mar 11:23 2013
Picon

Parsing email id

Hello Everyone
I am trying to learn parsec. I wrote this code to solve the problem ( http://www.spoj.com/problems/MAIN12C/ ) but getting time limit exceed so how can I improve this code ? In case of indentation, I have pasted the code at ideone ( http://ideone.com/AmxvZq ).

import Data.List
import qualified Text.Parsec.ByteString as PB
import Text.Parsec.Prim
import Text.Parsec.Char
import Text.Parsec.Combinator
import qualified Data.ByteString.Char8 as BS
import Control.Applicative hiding ( ( <|> ) , many )

validChars :: PB.Parser Char
validChars  = alphaNum <|> oneOf "._"

dontCare :: PB.Parser Char
dontCare = oneOf "~! <at> #$%^&*()<>?,."

{--
emailAddress :: PB.Parser  String
emailAddress = do
             _ <- many dontCare
             fi <- alphaNum
             se <- validChars
             th <- validChars
             fo <- validChars
             ft <- validChars
             restAddr <- many validChars
             let addr = fi : se : th : fo : ft : restAddr
             char ' <at> '
             dom <- many1 alphaNum
             rest <- try ( string ".com" <|> string ".org" 
                  <|>  string ".edu" ) <|> try ( string ".co.in" )
             _ <- many dontCare
             return $  addr ++ (  ' <at> ': dom ++ rest )
  
--}
         
emailAddress :: PB.Parser String
emailAddress = conCatfun <$> ( many dontCare *> alphaNum ) <*> validChars <*>
               validChars <*> validChars <*> validChars <*> many alphaNum  <*>
               ( char ' <at> ' *> many1 alphaNum ) <*> ( try ( string ".com" <|>
               string ".org" <|>  string ".edu" ) <|> try ( string ".co.in" )
               <* many dontCare ) where
                conCatfun a b c d e f dom rest =
                       ( a : b : c : d : e : f ) ++ ( ' <at> ' : dom ++ rest )


collectEmail :: BS.ByteString -> String
collectEmail email = case  parse emailAddress "" email of
                        Right addr -> addr
                        Left err ->  ""

process :: ( Int , [ String ] ) -> BS.ByteString
process ( k , xs ) = ( BS.pack "Case " ) `BS.append` ( BS.pack . show $ k )
          `BS.append` ( BS.pack ": " ) `BS.append` ( BS.pack . show $ k )
          `BS.append` ( BS.pack "\n" ) `BS.append` ( BS.pack 
          (  unlines . filter ( not . null ) $  xs ) )

main = BS.interact $ BS.concat .  map process . zip [ 1.. ] . map ( map collectEmail .
       BS.words ) . tail . BS.lines

Regards
Mukesh Tiwari


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane