X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;ds=sidebyside;f=src%2Ftask5%2Ftask5-lines.hs;fp=src%2Ftask5%2Ftask5-lines.hs;h=64fc8eb485f6ce52755c1c345a12573288f17d89;hb=8df06839ba3dc64b556e964e5e04d65c0a01cf8e;hp=0000000000000000000000000000000000000000;hpb=5fcd6565317ea77d297bf3c6a349754f9bbd94cf;p=summerofcode2018soln.git diff --git a/src/task5/task5-lines.hs b/src/task5/task5-lines.hs new file mode 100644 index 0000000..64fc8eb --- /dev/null +++ b/src/task5/task5-lines.hs @@ -0,0 +1,74 @@ +{-# LANGUAGE OverloadedStrings #-} + +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as TIO +import Data.Char (isSpace) + + +main :: IO () +main = do + text_all <- TIO.readFile "data/05-instructions.txt" + let text = T.lines text_all + let uncommented = map deComment text + let expanded = map expand uncommented + print $ countNonSpace uncommented + print $ countNonSpace expanded + -- TIO.writeFile "data/05-output.ppm" $ T.unlines expanded + + +countNonSpace :: [Text] -> Int +countNonSpace = sum . map (T.length . T.filter (\c -> not (isSpace c))) + + +-- Remove comments +deComment :: Text -> Text +deComment text = deComment' (extractFirstComment text) text + +-- If there are no comments, return the text as-is +-- If there is a first comment, decomment the rest +deComment' :: Maybe (Text, Text) -> Text -> Text +deComment' Nothing text = text +deComment' (Just (prefix, suffix)) _ = prefix `T.append` (deComment suffix) + +-- Monad notation to string togeether all the Maybes +extractFirstComment :: Text -> Maybe (Text, Text) +extractFirstComment text = + do (prefix, commentSuffix) <- maybeBreakOn "<" text + (_, suffix) <- maybeBreakOn ">" commentSuffix + return (prefix, suffix) + + +-- Expand compression +expand :: Text -> Text +expand text = expand' (extractFirstExpander text) text + +-- If there are no compression markers, return the text +-- If there's one, expand it, and try again. +expand' :: Maybe (Text, Int, Int, Text) -> Text -> Text +expand' Nothing text = text +expand' (Just (prefix, expandLen, expandCount, suffix)) _ = + expand (expandedPrefix `T.append` suffix) + where unexpandedPrefix = T.dropEnd expandLen prefix + group = T.takeEnd expandLen prefix + expanded = T.replicate expandCount group + expandedPrefix = unexpandedPrefix `T.append` expanded + +extractFirstExpander :: Text -> Maybe (Text, Int, Int, Text) +extractFirstExpander text = + do (prefix, suffix) <- maybeBreakOn ":" text + (expanderLenT, suffix') <- maybeBreakOn ":" suffix + (expanderCountT, suffix'') <- maybeBreakOn ":" suffix' + let expanderLen = read $ T.unpack expanderLenT + let expanderCount = read $ T.unpack expanderCountT + return (prefix, expanderLen, expanderCount, suffix'') + + +-- Uses Text.breakOn, but puts the result in a Maybe +-- Also drops the needle from the returned suffix. +maybeBreakOn :: Text -> Text -> Maybe (Text, Text) +maybeBreakOn needle haystack = + if T.null suffix + then Nothing + else Just (prefix, T.drop (T.length needle) suffix) + where (prefix, suffix) = T.breakOn needle haystack