day 7: rewrite
use Data.Text Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
27
day7'.hs
27
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 Data.Tree
|
||||||
|
import Lib (readFile')
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
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: "
|
putStr "Q1: "
|
||||||
print $
|
print $
|
||||||
foldTree
|
foldTree
|
||||||
@@ -22,24 +29,26 @@ main = do
|
|||||||
)
|
)
|
||||||
tree
|
tree
|
||||||
|
|
||||||
type Filesystem = Tree (String, Int)
|
type Filesystem = Tree (Text, Int)
|
||||||
|
|
||||||
tail' :: [a] -> [a]
|
tail' :: [a] -> [a]
|
||||||
tail' = drop 1
|
tail' = drop 1
|
||||||
|
|
||||||
emptyFs :: String -> Filesystem
|
emptyFs :: Text -> Filesystem
|
||||||
emptyFs n = Node (n, 0) []
|
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)
|
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 :: [Filesystem] -> Int
|
||||||
totalSize = sum . map (snd . rootLabel)
|
totalSize = sum . map (snd . rootLabel)
|
||||||
|
|
||||||
ls :: [[String]] -> [Filesystem]
|
parse :: [[Text]] -> Filesystem -> ([[Text]], Filesystem)
|
||||||
ls = map (\[a, b] -> Node (b, read a) []) . filter ((/= "dir") . head)
|
|
||||||
|
|
||||||
parse :: [[String]] -> Filesystem -> ([[String]], Filesystem)
|
|
||||||
parse input fs
|
parse input fs
|
||||||
| null input || cur == ["$", "cd", ".."] = (tail' input, fs)
|
| null input || cur == ["$", "cd", ".."] = (tail' input, fs)
|
||||||
| cur == ["$", "ls"] =
|
| cur == ["$", "ls"] =
|
||||||
@@ -50,7 +59,7 @@ parse input fs
|
|||||||
| otherwise =
|
| otherwise =
|
||||||
let name = cur !! 2
|
let name = cur !! 2
|
||||||
(nextInput, newFs) = parse (tail' input) (emptyFs name)
|
(nextInput, newFs) = parse (tail' input) (emptyFs name)
|
||||||
replaced = insertFs fs name newFs -- replace empty directory
|
replaced = insertFs fs name newFs
|
||||||
in parse nextInput replaced
|
in parse nextInput replaced
|
||||||
where
|
where
|
||||||
cur = head input
|
cur = head input
|
||||||
|
31
day7.hs
31
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 Data.Tree
|
||||||
|
import Lib (readFile')
|
||||||
|
|
||||||
-- this solution assumes that empty directories can exist,
|
-- this solution assumes that empty directories can exist,
|
||||||
-- if you want to ignore that, there is a slightly different code in day7'.hs
|
-- 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 :: IO ()
|
||||||
main = do
|
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: "
|
putStr "Q1: "
|
||||||
print $
|
print $
|
||||||
foldTree
|
foldTree
|
||||||
@@ -26,18 +35,18 @@ main = do
|
|||||||
)
|
)
|
||||||
tree
|
tree
|
||||||
|
|
||||||
type Filesystem = Tree (String, Int)
|
type Filesystem = Tree (Text, Int)
|
||||||
|
|
||||||
tail' :: [a] -> [a]
|
tail' :: [a] -> [a]
|
||||||
tail' = drop 1
|
tail' = drop 1
|
||||||
|
|
||||||
-- wrapper to create an empty tree
|
-- wrapper to create an empty tree
|
||||||
emptyFs :: String -> Filesystem
|
emptyFs :: Text -> Filesystem
|
||||||
emptyFs n = Node (n, 0) []
|
emptyFs n = Node (n, 0) []
|
||||||
|
|
||||||
-- This function is to replace a filesystem by name
|
-- This function is to replace a filesystem by name
|
||||||
-- Used to replace empty directories with parsed directories in code
|
-- 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 =
|
replaceFs (Node n xs) name fs =
|
||||||
let (h, t) = span ((/= name) . fst . rootLabel) xs
|
let (h, t) = span ((/= name) . fst . rootLabel) xs
|
||||||
in Node
|
in Node
|
||||||
@@ -50,11 +59,17 @@ totalSize :: [Filesystem] -> Int
|
|||||||
totalSize = sum . map (snd . rootLabel)
|
totalSize = sum . map (snd . rootLabel)
|
||||||
|
|
||||||
-- All directories/files are parsed here into leaves
|
-- All directories/files are parsed here into leaves
|
||||||
ls :: [[String]] -> [Filesystem]
|
ls :: [[Text]] -> [Filesystem]
|
||||||
ls = map (\[a, b] -> if a == "dir" then Node (b, 0) [] else Node (b, read a) [])
|
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
|
-- main function where stuff happens
|
||||||
parse :: [[String]] -> Filesystem -> ([[String]], Filesystem)
|
parse :: [[Text]] -> Filesystem -> ([[Text]], Filesystem)
|
||||||
parse input fs
|
parse input fs
|
||||||
| null input || cur == ["$", "cd", ".."] = (tail' input, fs)
|
| null input || cur == ["$", "cd", ".."] = (tail' input, fs)
|
||||||
| cur == ["$", "ls"] =
|
| cur == ["$", "ls"] =
|
||||||
|
Reference in New Issue
Block a user