From 6a1a49bc962013d97176daee2a8e5dd35729947e Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Fri, 9 Dec 2022 19:10:36 +0530 Subject: [PATCH] day 7: rewrite use Data.Text Signed-off-by: Amneesh Singh --- day7'.hs | 27 ++++++++++++++++++--------- day7.hs | 31 +++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/day7'.hs b/day7'.hs index 849164e..fac21a6 100644 --- a/day7'.hs +++ b/day7'.hs @@ -1,8 +1,15 @@ +{-# LANGUAGE OverloadedStrings #-} + +import Data.Either (rights) +import Data.Text (Text) +import qualified Data.Text as T (head, lines, words) +import qualified Data.Text.Read as T (decimal) import Data.Tree +import Lib (readFile') main :: IO () main = do - tree <- snd . flip parse (emptyFs "/") . map words . lines <$> readFile "day7.in" + tree <- snd . flip parse (emptyFs "/") . map T.words . T.lines <$> readFile' "day7.in" putStr "Q1: " print $ foldTree @@ -22,24 +29,26 @@ main = do ) tree -type Filesystem = Tree (String, Int) +type Filesystem = Tree (Text, Int) tail' :: [a] -> [a] tail' = drop 1 -emptyFs :: String -> Filesystem +emptyFs :: Text -> Filesystem emptyFs n = Node (n, 0) [] -insertFs :: Filesystem -> String -> Filesystem -> Filesystem +insertFs :: Filesystem -> Text -> Filesystem -> Filesystem insertFs (Node n xs) name fs = Node (fst n, snd n + snd (rootLabel fs)) (fs : xs) +ls :: [[Text]] -> [Filesystem] +ls = + map (\[a, b] -> Node (b, fst . head $ rights [T.decimal a]) []) + . filter ((/= "dir") . head) + totalSize :: [Filesystem] -> Int totalSize = sum . map (snd . rootLabel) -ls :: [[String]] -> [Filesystem] -ls = map (\[a, b] -> Node (b, read a) []) . filter ((/= "dir") . head) - -parse :: [[String]] -> Filesystem -> ([[String]], Filesystem) +parse :: [[Text]] -> Filesystem -> ([[Text]], Filesystem) parse input fs | null input || cur == ["$", "cd", ".."] = (tail' input, fs) | cur == ["$", "ls"] = @@ -50,7 +59,7 @@ parse input fs | otherwise = let name = cur !! 2 (nextInput, newFs) = parse (tail' input) (emptyFs name) - replaced = insertFs fs name newFs -- replace empty directory + replaced = insertFs fs name newFs in parse nextInput replaced where cur = head input diff --git a/day7.hs b/day7.hs index de5fed9..0e4f7f4 100644 --- a/day7.hs +++ b/day7.hs @@ -1,12 +1,21 @@ +{-# LANGUAGE OverloadedStrings #-} + +import Data.Either (rights) +import Data.Text (Text) +import qualified Data.Text as T (head, lines, words) +import qualified Data.Text.Read as T (decimal) import Data.Tree +import Lib (readFile') -- this solution assumes that empty directories can exist, -- if you want to ignore that, there is a slightly different code in day7'.hs --- needs cleaning and improvement + +-- needs cleaning and improvement, although i like the fact +-- that the entire FS can be printed as a tree main :: IO () main = do - tree <- snd . flip parse (emptyFs "/") . map words . lines <$> readFile "day7.in" + tree <- snd . flip parse (emptyFs "/") . map T.words . T.lines <$> readFile' "day7.in" putStr "Q1: " print $ foldTree @@ -26,18 +35,18 @@ main = do ) tree -type Filesystem = Tree (String, Int) +type Filesystem = Tree (Text, Int) tail' :: [a] -> [a] tail' = drop 1 -- wrapper to create an empty tree -emptyFs :: String -> Filesystem +emptyFs :: Text -> Filesystem emptyFs n = Node (n, 0) [] -- 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 :: Filesystem -> Text -> Filesystem -> Filesystem replaceFs (Node n xs) name fs = let (h, t) = span ((/= name) . fst . rootLabel) xs in Node @@ -50,11 +59,17 @@ totalSize :: [Filesystem] -> Int totalSize = sum . map (snd . rootLabel) -- 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) []) +ls :: [[Text]] -> [Filesystem] +ls = + map + ( \[a, b] -> + if a == "dir" + then Node (b, 0) [] + else Node (b, fst . head $ rights [T.decimal a]) [] + ) -- main function where stuff happens -parse :: [[String]] -> Filesystem -> ([[String]], Filesystem) +parse :: [[Text]] -> Filesystem -> ([[Text]], Filesystem) parse input fs | null input || cur == ["$", "cd", ".."] = (tail' input, fs) | cur == ["$", "ls"] =