From 02b62f919bea776126a2229c542931291aa3ed97 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Fri, 16 Dec 2022 20:59:53 +0100 Subject: [PATCH] finish parsing of day seven --- seven.hs | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/seven.hs b/seven.hs index 9a2c80f..b54c035 100644 --- a/seven.hs +++ b/seven.hs @@ -1,21 +1,17 @@ +-- everything stolen from http://learnyouahaskell.com/zippers#a-very-simple-file-system + + data FS = FS [Inode] - data Inode = Dir Name [Inode] | File Name Size deriving(Show) - type Name = String type Size = Int - - data Command = Ls | Cd Name | CdUp | CdRoot deriving(Show) - - data Line = LineC Command | LineI Inode deriving(Show) parseCommand :: String -> Command -parseCommand ('c':'d':' ':name) =(Cd name) parseCommand "ls" =Ls parseCommand "cd .." =CdUp -parseCommand "cd /" =CdRoot +parseCommand ('c':'d':' ':name) =(Cd name) parseInode :: String -> Inode parseInode ('d':'i':'r':' ': name) = Dir name [] @@ -26,9 +22,43 @@ parseEither :: String -> Line parseEither ('$':' ':command) =LineC $ parseCommand command 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 content <- readFile "seven-input.txt" - let statements = map parseEither $ lines content - print statements + let statements = map parseEither $ drop 1 $ lines content + let a = foldl foldFunction initZipper statements + print $ fsUpToRoot a