Select Git revision
solve.hs 2.37 KiB
-- Day 7
{-# LANGUAGE BangPatterns #-}
import Data.List
while :: (a -> Bool) -> (a -> a) -> a -> a
while p f = go where go !x = if p x then go (f x) else x
cleanUpNav :: [String] -> [String]
cleanUpNav = filter (\x -> not $ "$ cd .." `isInfixOf` x || (x == "$ ls"))
getDirName :: String -> String -> String
getDirName x prefix = if prefix `isPrefixOf` x
then last $ words x
else ""
getUntilCommand :: [String] -> [String]
getUntilCommand [] = []
getUntilCommand (x:xs) = if head x /= '$'
then x:getUntilCommand xs
else []
getDirNameContent :: [String] -> [(String, [String])]
getDirNameContent [] = []
getDirNameContent (x:xs) = if "$ cd " `isPrefixOf` x
then (getDirName x "$ cd ", getUntilCommand xs) : getDirNameContent xs
else getDirNameContent xs
findDir :: String -> [(String, [String])] -> (String, [String])
findDir n = head . filter (\(x, _) -> x == n)
unwrapDir :: String -> [(String, [String])] -> [String]
unwrapDir dirName navStack = snd $ findDir dirName navStack
filesInNestedDir :: String -> [(String, [String])]-> [String]
filesInNestedDir x stack = if "dir" `isPrefixOf` x
then unwrapDir (getDirName x "dir ") stack
else [x]
filesForDir :: [String] -> [(String, [String])] -> [[String]]
filesForDir [x] stack = [filesInNestedDir x stack]
filesForDir (x:xs) stack = filesInNestedDir x stack : filesForDir xs stack
containsDirs :: [String] -> Bool
containsDirs l = filter ("dir" `isPrefixOf`) l /= []
goUntilNoDir :: [String] -> [(String, [String])] -> [String]
goUntilNoDir currentDir stack = if containsDirs currentDir
then goUntilNoDir (concat (filesForDir currentDir stack)) stack
else currentDir
getFilesInDirs :: [(String, [String])] -> [(String, [String])]
getFilesInDirs stack = map (\(x, y) ->
(x, goUntilNoDir y stack)) stack
getFileSize :: String -> Int
getFileSize = read . head . words
solve1 :: [(String, [String])] -> Int
solve1 s = sum $ filter (\x -> x <= 100000) $ map (\(_, y) -> sum $ map (getFileSize) y) s
readInput :: IO [(String, [String])]
readInput = readFile "./sample.txt" >>= return . getDirNameContent . cleanUpNav . lines
main :: IO ()
main = readInput >>= print . solve1