|
@@ -1,29 +1,40 @@
|
1
|
1
|
module Day7.Interpreter (
|
2
|
2
|
buildTree,
|
3
|
3
|
mkdir,
|
4
|
|
- Directory (..),
|
|
4
|
+ FileTree (..),
|
|
5
|
+ Directory,
|
5
|
6
|
calculateSize,
|
6
|
7
|
filterDirectories,
|
7
|
8
|
sizeOfDirectories,
|
8
|
|
- sumUp,
|
9
|
9
|
) where
|
10
|
10
|
|
11
|
11
|
import Day7.Parser
|
12
|
12
|
import Data.Map (Map)
|
13
|
13
|
import qualified Data.Map as Map
|
|
14
|
+import qualified Data.Foldable as F
|
14
|
15
|
|
15
|
|
-data Directory = Directory
|
16
|
|
- { sub :: Map String Directory
|
17
|
|
- , files :: Map String Int
|
|
16
|
+
|
|
17
|
+data FileTree a = FileTree
|
|
18
|
+ { sub :: Map String (FileTree a)
|
|
19
|
+ , files :: Map String a
|
18
|
20
|
, isRoot :: Bool
|
19
|
21
|
} deriving (Eq)
|
20
|
22
|
|
|
23
|
+-- Directory is a FileTree with file sizes of Int
|
|
24
|
+type Directory = FileTree Int
|
|
25
|
+
|
|
26
|
+-- pretty much only useful for summing up file sizes
|
|
27
|
+instance F.Foldable FileTree where
|
|
28
|
+ foldMap f dir = foldMap f (files dir) <> mconcat mappedSubfolders
|
|
29
|
+ where
|
|
30
|
+ subFolders = Map.elems $ sub dir
|
|
31
|
+ mappedSubfolders = map (foldMap f) subFolders
|
21
|
32
|
|
22
|
|
-instance Show Directory where
|
|
33
|
+instance Show a => Show (FileTree a) where
|
23
|
34
|
show d = "DIR " ++ show (Map.toList $ files d) ++ " - " ++ show (Map.toList $ sub d) ++ "\n"
|
24
|
35
|
|
25
|
36
|
mkdir :: Directory
|
26
|
|
-mkdir = Directory { sub = Map.empty, files = Map.empty, isRoot = False }
|
|
37
|
+mkdir = FileTree { sub = Map.empty, files = Map.empty, isRoot = False }
|
27
|
38
|
|
28
|
39
|
rootDirectory :: Directory
|
29
|
40
|
rootDirectory = mkdir { isRoot = True }
|
|
@@ -57,24 +68,14 @@ toFiles (_:rest) = toFiles rest
|
57
|
68
|
toFiles [] = []
|
58
|
69
|
|
59
|
70
|
calculateSize :: Directory -> Int
|
60
|
|
-calculateSize dir = sum (Map.elems (files dir)) + sum sizes
|
61
|
|
- where
|
62
|
|
- subFolders = Map.elems (sub dir)
|
63
|
|
- sizes = map calculateSize subFolders
|
|
71
|
+calculateSize = F.foldl' (+) 0
|
64
|
72
|
|
65
|
|
-flatten :: Directory -> [(String, Directory)]
|
66
|
|
-flatten dir = flatten' ("/", dir)
|
67
|
|
- where
|
68
|
|
- flatten' (name, d) = (name, d) : concatMap flatten' (Map.toList (sub d))
|
|
73
|
+flatten :: Directory -> [Directory]
|
|
74
|
+flatten d = d : concatMap flatten (Map.elems (sub d))
|
69
|
75
|
|
70
|
|
-sizeOfDirectories :: Directory -> [(String, Int)]
|
71
|
|
-sizeOfDirectories dir = map withSize allDirectories
|
72
|
|
- where
|
73
|
|
- allDirectories = flatten dir
|
74
|
|
- withSize (name, directory) = (name, calculateSize directory)
|
|
76
|
+sizeOfDirectories :: Directory -> [Int]
|
|
77
|
+sizeOfDirectories = map calculateSize . flatten
|
75
|
78
|
|
76
|
|
-filterDirectories :: (Int -> Bool) -> Directory -> [(String, Int)]
|
77
|
|
-filterDirectories predicate dir = filter (\(_, size) -> predicate size) $ sizeOfDirectories dir
|
|
79
|
+filterDirectories :: (Int -> Bool) -> Directory -> [Int]
|
|
80
|
+filterDirectories predicate dir = filter predicate $ sizeOfDirectories dir
|
78
|
81
|
|
79
|
|
-sumUp :: [(String, Int)] -> Int
|
80
|
|
-sumUp = sum . map snd
|