{-# LANGUAGE PatternGuards #-} import Data.List import Data.Ord import Data.Char import Data.Maybe import Text.Printf data BattState = Charging | Discharging | Charged deriving (Show, Eq) data LogEntry = LogEntry { time :: Int, descap :: Int, lastfull :: Int, state :: BattState, rate :: Int, remcap :: Int } deriving (Show) parse str | [time_s, descap_s, lastfull_s, _, state_s, rate_s, remcap_s, _] <- words str = let divisor = if state_s `elem` words "charging discharging charged" then 1 else 1000 valid = state_s /= "-" in if not valid then Nothing else Just $ LogEntry { time = read time_s, descap = read descap_s `div` divisor, lastfull = read lastfull_s `div` divisor, state = case state_s of "charging" -> Charging "discharging" -> Discharging "charged" -> Charged "Charging" -> Charging "Discharging" -> Discharging "Full" -> Charged, rate = read rate_s `div` divisor, remcap = read remcap_s `div` divisor } parse str = error $ "Could not parse " ++ str showLog (LogEntry time descap lastfull state rate remcap) = printf "%d %d %d - %s %d %d - " time descap lastfull state_s rate remcap where state_s = case state of Charging -> "charging" Discharging -> "discharging" Charged -> "charged" skiplen = 4 * 60 * 60 -- 4h -- First entry skip (delta,lasttime) le | lasttime + skiplen < time le - delta || lasttime > time le - delta = let time' = lasttime + skiplen delta' = time le - delta - time' in ((delta + delta', time'), le { time = time' }) | otherwise = let time' = time le - delta in ((delta, time'), le { time = time' }) normalize les = snd $ mapAccumL skip (firstime, 0) les where firstime = time (head les) anonymize = unlines . map showLog . normalize . catMaybes . map parse . lines main = interact anonymize