finish parsing of day seven

This commit is contained in:
qvalentin 2022-12-16 20:59:53 +01:00
parent 51dbc7a1fb
commit 02b62f919b
Signed by: qvalentin
GPG Key ID: C979FA1EAFCABF1C
1 changed files with 40 additions and 10 deletions

View File

@ -1,21 +1,17 @@
-- everything stolen from http://learnyouahaskell.com/zippers#a-very-simple-file-system
data FS = FS [Inode] data FS = FS [Inode]
data Inode = Dir Name [Inode] | File Name Size deriving(Show) data Inode = Dir Name [Inode] | File Name Size deriving(Show)
type Name = String type Name = String
type Size = Int type Size = Int
data Command = Ls | Cd Name | CdUp | CdRoot deriving(Show) data Command = Ls | Cd Name | CdUp | CdRoot deriving(Show)
data Line = LineC Command | LineI Inode deriving(Show) data Line = LineC Command | LineI Inode deriving(Show)
parseCommand :: String -> Command parseCommand :: String -> Command
parseCommand ('c':'d':' ':name) =(Cd name)
parseCommand "ls" =Ls parseCommand "ls" =Ls
parseCommand "cd .." =CdUp parseCommand "cd .." =CdUp
parseCommand "cd /" =CdRoot parseCommand ('c':'d':' ':name) =(Cd name)
parseInode :: String -> Inode parseInode :: String -> Inode
parseInode ('d':'i':'r':' ': name) = Dir name [] parseInode ('d':'i':'r':' ': name) = Dir name []
@ -26,9 +22,43 @@ parseEither :: String -> Line
parseEither ('$':' ':command) =LineC $ parseCommand command parseEither ('$':' ':command) =LineC $ parseCommand command
parseEither input= LineI $ parseInode input parseEither input= LineI $ parseInode input
foldFunction :: FSZipper -> Line -> FSZipper
foldFunction zipper (LineC Ls) = zipper
foldFunction zipper (LineC (Cd name)) = fsTo name zipper
foldFunction zipper (LineC CdUp) = fsUp zipper
foldFunction zipper (LineI inode) = fsNewInode inode zipper
data FSCrumb = FSCrumb Name [Inode] [Inode] deriving (Show)
type FSZipper = (Inode,[FSCrumb])
fsUp :: FSZipper -> FSZipper
fsUp (item, FSCrumb name ls rs:bs) = (Dir name (ls ++ [item] ++ rs), bs)
fsUpToRoot :: FSZipper -> FSZipper
fsUpToRoot ((Dir "/" content),bc) = ((Dir "/" content),bc)
fsUpToRoot zipper = fsUp zipper
fsTo :: Name -> FSZipper -> FSZipper
fsTo name (Dir folderName items, bs) =
let (ls, item:rs) = break (nameIs name) items
in (item, FSCrumb folderName ls rs:bs)
nameIs :: Name -> Inode -> Bool
nameIs name (Dir folderName _) = name == folderName
nameIs name (File fileName _) = name == fileName
fsNewInode :: Inode -> FSZipper -> FSZipper
fsNewInode newInode ((Dir name content),bc) = (Dir name (newInode:content),bc)
initZipper :: FSZipper
initZipper = (Dir "/" [],[])
main = do main = do
content <- readFile "seven-input.txt" content <- readFile "seven-input.txt"
let statements = map parseEither $ lines content let statements = map parseEither $ drop 1 $ lines content
print statements let a = foldl foldFunction initZipper statements
print $ fsUpToRoot a