48 lines
1.7 KiB
Haskell
48 lines
1.7 KiB
Haskell
import Data.List
|
|
import Numeric
|
|
import Control.Arrow
|
|
import Control.Monad
|
|
import Text.Printf
|
|
import System.Environment
|
|
import Data.Function
|
|
|
|
type Date = String
|
|
type Value = Double
|
|
type Flag = Bool
|
|
|
|
readFlg :: String -> Flag
|
|
readFlg = (> 0).read
|
|
|
|
readNum :: String -> Value
|
|
readNum = fst.head.readFloat
|
|
|
|
take2 = takeWhile(not.null).unfoldr (Just.splitAt 2)
|
|
|
|
parseData :: [String] -> (Date,[(Value,Flag)])
|
|
parseData = head &&& map(readNum.head &&& readFlg.last).take2.tail
|
|
|
|
sumAccs :: (Date,[(Value,Flag)]) -> (Date, ((Value,Int),[Flag]))
|
|
sumAccs = second (((sum &&& length).concat.uncurry(zipWith(\v f -> [v|f])) &&& snd).unzip)
|
|
|
|
maxNAseq :: [Flag] -> [(Int,Int)]
|
|
maxNAseq = head.groupBy((==) `on` fst).sortBy(flip compare)
|
|
. concat.uncurry(zipWith(\i (r,b)->[(r,i)|not b]))
|
|
. first(init.scanl(+)0). unzip
|
|
. map ((fst &&& id).(length &&& head)). group
|
|
|
|
main = do
|
|
file:_ <- getArgs
|
|
f <- readFile file
|
|
let dat :: [(Date,((Value,Int),[Flag]))]
|
|
dat = map (sumAccs. parseData. words).lines $ f
|
|
summ = ((sum *** sum). unzip *** maxNAseq.concat). unzip $ map snd dat
|
|
totalFmt = "\nSummary\t\t accept: %d\t total: %.3f \taverage: %6.3f\n\n"
|
|
lineFmt = "%8s\t accept: %2d\t total: %11.3f \taverage: %6.3f\n"
|
|
maxFmt = "Maximum of %d consecutive false readings, starting on line /%s/ and ending on line /%s/\n"
|
|
-- output statistics
|
|
putStrLn "\nSome lines:\n"
|
|
mapM_ (\(d,((v,n),_)) -> printf lineFmt d n v (v/fromIntegral n)) $ take 4 $ drop 2200 dat
|
|
(\(t,n) -> printf totalFmt n t (t/fromIntegral n)) $ fst summ
|
|
mapM_ ((\(l, d1,d2) -> printf maxFmt l d1 d2)
|
|
. (\(a,b)-> (a,(fst.(dat!!).(`div`24))b,(fst.(dat!!).(`div`24))(a+b)))) $ snd summ
|