competition (empty) → 0.2.0.0
raw patch · 5 files changed
+202/−0 lines, 5 filesdep +basedep +filepathdep +parsecsetup-changed
Dependencies added: base, filepath, parsec
Files
- Code/Competition.hs +70/−0
- Code/Competition/Parsers.hs +84/−0
- LICENSE +20/−0
- Setup.hs +2/−0
- competition.cabal +26/−0
+ Code/Competition.hs view
@@ -0,0 +1,70 @@+module Code.Competition (+ Solveable(..), Parseable(..), runCompetition, runSolution, runWriteSolution+) where++-- getArgs+import System.Environment (getArgs)+import System.FilePath (replaceExtension)++-- Parsing+import Text.ParserCombinators.Parsec (parse, ParseError, GenParser)+import Code.Competition.Parsers (probfile)++------------------------+-- Type Classes+------------------------++-- Solveable denotes any type that represents a solveable problem+class (Show a) => Solveable p a where+ solve :: p -> a++class Parseable p where+ problem :: GenParser Char st p++------------------------+-- parsers+------------------------++parseProblemFile :: Parseable p => String -> Either ParseError [p]+parseProblemFile input = parse (probfile problem) "(unknown)" input++------------------------+-- Main and IO+------------------------++runCompetition :: (Solveable p a, Parseable p, Show p) => IO [(p, a)]+runCompetition = do+ args <- getArgs+ inputFn <- return $ head args+ let outputFn = if length args >= 2 then (args !! 1) else (replaceExtension inputFn ".out")+ (output, probans) <- runWriteSolution inputFn outputFn+ putStr output+ return probans++runSolution :: (Solveable p a, Parseable p, Show p) => String -> IO (String, [(p, a)])+runSolution inputFn = do+ input <- readFile inputFn+ problems <- case parseProblemFile input of+ Left pe -> handleParseError pe+ Right xs -> return xs+ answers <- return $ map solve problems+ output <- return $ (unlines . caseify) answers+ return (output, zip problems answers)++runWriteSolution :: (Solveable p a, Parseable p, Show p) => String -> String -> IO (String, [(p, a)])+runWriteSolution inputFn outputFn = do+ (output, probans) <- runSolution inputFn+ writeFile outputFn output+ return (output, probans)++handleParseError :: Parseable p => ParseError -> IO [p]+handleParseError err = do+ putStrLn $ show err+ return []++------------------------+-- Helpers+------------------------++caseify :: Show a => [a] -> [String]+caseify as = map (\(i,a) -> "Case #" ++ (show i) ++ ": " ++ (show a)) (zip [1..] as)
+ Code/Competition/Parsers.hs view
@@ -0,0 +1,84 @@+module Code.Competition.Parsers (+ probfile,+ grid, nmgrid,+ ints, intn, int,+ floats, floatn, float,+ andSpace,+ eol+) where+++-- Parsing+import Text.ParserCombinators.Parsec (GenParser, count, char, space, digit, many, eof)++------------------------+-- A grid of n rows and m columns (no spaces separated)+------------------------++grid :: Int -> Int -> GenParser Char st a -> GenParser Char st [[a]]+grid n m p = count n pline+ where+ pline = do+ ret <- count m p+ eol+ return ret++-- A grid with n and m at the top+nmgrid :: GenParser Char st a -> GenParser Char st [[a]]+nmgrid p = do+ [n,m] <- intn 2+ grid n m p++------------------------+-- A whole problem file+------------------------++probfile :: GenParser Char st prob -> GenParser Char st [prob]+probfile probparse = do+ [t] <- intn 1+ probs <- count t probparse+ eof+ return probs++------------------------+-- Ints+------------------------++ints :: GenParser Char st [Int]+ints = many (andSpace int)++intn :: Int -> GenParser Char st [Int]+intn n = count n (andSpace int)++int :: GenParser Char st Int+int = do+ tokens <- many digit+ return $ read tokens++------------------------+-- Floats+------------------------++floats :: GenParser Char st [Int]+floats = many (andSpace int)++floatn :: Int -> GenParser Char st [Float]+floatn n = count n (andSpace float)++float :: GenParser Char st Float+float = do+ predot <- many digit+ char '.'+ postdot <- many digit+ return $ read (predot ++ "." ++ postdot)++-- Helpers++eol :: GenParser Char st Char+eol = char '\n'++andSpace :: GenParser Char st a -> GenParser Char st a+andSpace ap = do+ a <- ap+ space+ return a
+ LICENSE view
@@ -0,0 +1,20 @@+The MIT License (MIT)++Copyright (c) 2013 Metric Feat LLC++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of+the Software, and to permit persons to whom the Software is furnished to do so,+subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ competition.cabal view
@@ -0,0 +1,26 @@+-- Initial competition.cabal generated by cabal init. For further+-- documentation, see http://haskell.org/cabal/users-guide/++name: competition+version: 0.2.0.0+synopsis: Helpers and runners for code competitions+-- description:+homepage: github.com/yanatan16/haskell-competition+license: MIT+license-file: LICENSE+author: Jon Eisen+maintainer: jon@joneisen.me+-- copyright:+category: Code Competitions+build-type: Simple+cabal-version: >=1.8++library+ exposed-modules: Code.Competition, Code.Competition.Parsers++ extensions: MultiParamTypeClasses++ -- other-modules:+ build-depends: base < 5,+ filepath >= 1,+ parsec ==3.1.5