「ログイン・ログアウトの解析」のパーサ部分
30分プログラム、その535。http://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_022をやってみよう。
が、残念ながら30分では終わりそうにないので、今日はパーサ部分だけにチャレンジ。リスト操作とパターンマッチを駆使すればできそうな気がするけど、あえてParsecで。
でも、tryが必要なのに気がつかず、30分をオーバーしてしまった。
使い方
*Main> run dataset "1 2\n3\n1 2 3 0\n4\n1 2 3\n" "Dataset {pc = 1, student = 2, recoards = [Logout 3 2 1], queries = [Query 3 1 2]}
ソースコード
import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Char -- Node data Dataset = Dataset { pc :: Int , student :: Int , recoards :: [Recoard], queries :: [Query] } deriving Show data Recoard = Login Student PC Time | Logout Student PC Time deriving Show data Query = Query Student Time Time deriving Show type Student = Int type Time = Int type PC = Int -- Parser int :: Parser Int int = do n <- many1 digit many $ char ' ' return $ read n recoard :: Parser Recoard recoard = do t <- int pc <- int student <- int s <- int if s == 0 then return $ Logout student pc t else return $ Login student pc t query :: Parser Query query = do from <- int to <- int student <- int return $ Query student from to recoardFields :: Parser [Recoard] recoardFields = do int char '\n' (try recoard) `endBy` (char '\n') queryFields :: Parser [Query] queryFields = do int char '\n' query `endBy` (char '\n') --dataset :: Parser DataSet dataset = do pc <- int student <- int char '\n' recoards <- recoardFields queries <- queryFields return $ Dataset { pc = pc, student = student, recoards= recoards, queries = queries } file = do datasets <- many1 dataset string "0 0" eof return datasets -- driver run :: Show a => Parser a -> String -> String run p input = case (parse p "" input) of Left err -> show err Right x -> show x main = interact $ run dataset