From 6f152ab3659b985865668edb6750f443fa0fcf8a Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Wed, 7 Dec 2022 16:43:56 +0530 Subject: [PATCH] day7: clean up a bit and add comments Signed-off-by: Amneesh Singh --- day7'.hs | 22 ++++++++++++---------- day7.hs | 32 +++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/day7'.hs b/day7'.hs index f5c0022..2659d10 100644 --- a/day7'.hs +++ b/day7'.hs @@ -22,32 +22,34 @@ main = do ) tree +type Filesystem = Tree (String, Int) + tail' :: [a] -> [a] tail' = drop 1 -emptyFs :: String -> Tree (String, Int) +emptyFs :: String -> Filesystem emptyFs n = Node (n, 0) [] -insertFs :: Tree (String, Int) -> String -> Tree (String, Int) -> Tree (String, Int) +insertFs :: Filesystem -> String -> Filesystem -> Filesystem insertFs (Node n xs) name dir = Node (fst n, snd n + snd (rootLabel dir)) (dir : xs) -totalSize :: [Tree (String, Int)] -> Int +totalSize :: [Filesystem] -> Int totalSize = sum . map (snd . rootLabel) -ls :: [[String]] -> [Tree (String, Int)] +ls :: [[String]] -> [Filesystem] ls = map (\[a, b] -> Node (b, read a) []) . filter ((/= "dir") . head) -parse :: [[String]] -> Tree (String, Int) -> Tree (String, Int) +parse :: [[String]] -> Filesystem -> Filesystem parse input fs = snd $ parse' input fs -parse' :: [[String]] -> Tree (String, Int) -> ([[String]], Tree (String, Int)) +parse' :: [[String]] -> Filesystem -> ([[String]], Filesystem) parse' input fs - | null input || cur !! 1 == "cd" && cur !! 2 == ".." = (tail' input, fs) - | cur !! 1 == "ls" = + | null input || cur == ["$", "cd", ".."] = (tail' input, fs) + | cur == ["$", "ls"] = let (children, rest) = span ((/= "$") . head) (tail' input) - childFs = ls children + leaves = ls children name = fst $ rootLabel fs - in parse' rest (Node (name, totalSize childFs) childFs) + in parse' rest (Node (name, totalSize leaves) leaves) | otherwise = let name = cur !! 2 (nextInput, newFs) = parse' (tail' input) (emptyFs name) diff --git a/day7.hs b/day7.hs index c7e5ff7..d3233f3 100644 --- a/day7.hs +++ b/day7.hs @@ -1,7 +1,7 @@ import Data.Tree -- this solution assumes that empty directories can exist, --- if you want to ignore that, there is a slightly more compact code as day7'.hs +-- if you want to ignore that, there is a slightly different code in day7'.hs -- needs cleaning and improvement main :: IO () @@ -26,36 +26,46 @@ main = do ) tree +type Filesystem = Tree (String, Int) + tail' :: [a] -> [a] tail' = drop 1 -emptyFs :: String -> Tree (String, Int) +-- wrapper to create an empty tree +emptyFs :: String -> Filesystem emptyFs n = Node (n, 0) [] -replaceFs :: Tree (String, Int) -> String -> Tree (String, Int) -> Tree (String, Int) +-- This function is to replace a filesystem by name +-- Used to replace empty directories with parsed directories in code +replaceFs :: Filesystem -> String -> Filesystem -> Filesystem replaceFs (Node n xs) name fs = let (h, t) = span ((/= name) . fst . rootLabel) xs in Node (fst n, snd n + snd (rootLabel fs)) (h ++ [fs] ++ tail' t) -totalSize :: [Tree (String, Int)] -> Int +-- Sum of all filesystems in the list +-- Used to calculate sum of leaves in code +totalSize :: [Filesystem] -> Int totalSize = sum . map (snd . rootLabel) -ls :: [[String]] -> [Tree (String, Int)] +-- All directories/files are parsed here into leaves +ls :: [[String]] -> [Filesystem] ls = map (\[a, b] -> if a == "dir" then Node (b, 0) [] else Node (b, read a) []) -parse :: [[String]] -> Tree (String, Int) -> Tree (String, Int) +-- just a wrapper to apply snd +parse :: [[String]] -> Filesystem -> Filesystem parse input fs = snd $ parse' input fs -parse' :: [[String]] -> Tree (String, Int) -> ([[String]], Tree (String, Int)) +-- main function where stuff happens +parse' :: [[String]] -> Filesystem -> ([[String]], Filesystem) parse' input fs - | null input || cur !! 1 == "cd" && cur !! 2 == ".." = (tail' input, fs) - | cur !! 1 == "ls" = + | null input || cur == ["$", "cd", ".."] = (tail' input, fs) + | cur == ["$", "ls"] = let (children, rest) = span ((/= "$") . head) (tail' input) - childFs = ls children + leaves = ls children name = fst $ rootLabel fs - in parse' rest (Node (name, totalSize childFs) childFs) + in parse' rest (Node (name, totalSize leaves) leaves) | otherwise = let name = cur !! 2 (nextInput, newFs) = parse' (tail' input) (emptyFs name)