-- Compile with:
--    ghc -fforce-recomp -cpp -DVERSION=X --make -O2 test.hs -o test
-- Where X is the function (v0, v1...etc) you want to test

module Main where

import qualified Data.ByteString.Lazy as BB
import qualified Data.ByteString.Lazy.Char8 as B
import System
import Data.Char

main = do
  [f] <- getArgs
  putStrLn . show . BB.length . VERSION =<< myfilter f

myfilter f = (filter (\x -> not (B.null x) && B.head x /= '>') . B.lines) `fmap` B.readFile f

v0 ls = BB.pack $ map (read . B.unpack) $ B.words $ B.unlines ls

v1 ls = BB.pack (map int $ B.words $ B.unlines ls)
    where
    int = fromIntegral . fst . fromJust' . B.readInt
    fromJust' = maybe (error "Error in qual format") id

v2 ls = BB.pack [lookup x | x <- concatMap B.words ls]
    where
    lookup x = case B.readInt x of Just (v,_) -> fromIntegral v
                                   Nothing -> error "Unparsable qual value"

v3 ls = BB.pack $ go 0 ls
    where
    isDigit x = x <= 58 && x >= 48
    go i (s:ss) = case BB.uncons s of Just (c,rs) -> if isDigit c then go (c - 48 + 10*i) (rs:ss)
                                                     else let rs' = BB.dropWhile (not . isDigit) rs
                                                          in if BB.null rs' then i : go 0 ss else i : go 0 (rs':ss)
                                      Nothing -> i : go 0 ss
    go _ [] = []

v4 ls = BB.pack $ readInts $ B.unlines ls
    where readInts xs = case B.readInt xs of Just (i,rest) -> fromIntegral i : readInts (B.dropWhile Data.Char.isSpace rest)
                                             Nothing -> []
{-
v5 ls = BB.pack $ go 0 ls
    where
    isDigit x = x <= 58 && x >= 48
    go i (s:ss) = case uncons s of (c,rs) -> if isDigit c then go (c - 48 + 10*i) (rs:ss)
                                             else let rs' = BB.dropWhile (not . isDigit) rs
                                                  in if BB.null rs' then i : go 0 ss else i : go 0 (rs':ss)
    go _ [] = []
    uncons x = (BB.unsafeHead x, BB.unsafeTail x) -- Data.ByteString.Unsafe, but only strict
-}
