57 lines
2.1 KiB
Haskell
57 lines
2.1 KiB
Haskell
import Data.List
|
|
import qualified Data.Map.Strict as DMS
|
|
import Control.Monad.State.Lazy
|
|
|
|
type Path = [String]
|
|
type FilesizeEntry = (Path, Int)
|
|
|
|
path :: FilesizeEntry -> Path
|
|
path (p,_) = p
|
|
|
|
filesize :: FilesizeEntry -> Int
|
|
filesize (_,i) = i
|
|
|
|
normalizePath l|("..":_:r)<-l=r|let=l
|
|
|
|
traversePath :: Path -> [String] -> [FilesizeEntry]
|
|
traversePath currentPath (line:input)
|
|
|"$ cd .." == line = traversePath (tail currentPath) input
|
|
|("$ cd ",directory)<-splitAt 5 line,normalizedPath<-directory:currentPath = traversePath normalizedPath input
|
|
|[(filesize, "")]<-reads$fst$head$lex line, (_, filename) <- span (/=' ') line = (tail filename:currentPath,filesize):traversePath currentPath input
|
|
|let=traversePath currentPath input
|
|
traversePath _ [] = []
|
|
|
|
recFiles :: Path -> [FilesizeEntry] -> [Int]
|
|
recFiles directory = map filesize.filter(\entry->directory `isSuffixOf` path entry)
|
|
|
|
allDirectories = nub.map (tail.path)
|
|
gather :: [FilesizeEntry] -> [FilesizeEntry]
|
|
gather directoryFileEntries = [ (uniqueDirectory,sum$recFiles uniqueDirectory directoryFileEntries) | uniqueDirectory<-allDirectories directoryFileEntries]
|
|
sumsmall :: [FilesizeEntry] -> Int
|
|
sumsmall l=sum[f|(d,f)<-l, f<=100000]
|
|
main=interact$pprint[].take 20.traversePath [].lines
|
|
|
|
updateOrInsert :: Int -> Maybe Int -> Maybe Int
|
|
updateOrInsert a (Just x) = Just (x+a)
|
|
updateOrInsert a _ = Just (a)
|
|
|
|
files2folders :: [FilesizeEntry] -> State (DMS.Map Path Int) ()
|
|
files2folders [] = return ()
|
|
files2folders ((_:path, size):xs) = do
|
|
forM (init$tails path) (\part -> modify $ DMS.alter (updateOrInsert size) part)
|
|
files2folders xs
|
|
|
|
|
|
|
|
pprint _ [] = []
|
|
pprint cur (entry:list)
|
|
|cur == (tail $ path entry) = show(filesize entry) ++ " " ++ (head$path entry) ++ "\n" ++ pprint cur list
|
|
|otherwise = (tail$concat$intersperse "/"$reverse$tail$path entry) ++ "\n" ++ pprint (tail $ path entry) (entry:list)
|
|
-- t = map(\(h,t)->(h,sum t))
|
|
-- t l=groupBy(\(i,_)(j,_)->i==j)$[(o,i)|(e,_)<-l,(o,i)<-l,isPrefixOf e o]
|
|
-- main=interact$show.map(foldr1(\(d,i)(c,j)->(d,i+j))).t.sort.x.lines
|
|
--
|
|
|
|
input = readFile "day7long"
|
|
|
|
prepare = input >>= (return.traversePath [].lines)
|