You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Day7Spec.hs 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. {-# LANGUAGE QuasiQuotes #-}
  2. module Day7Spec (spec) where
  3. import Test.Hspec
  4. import Text.Heredoc
  5. import Day7
  6. import Day7.Parser
  7. import qualified Data.Map as Map
  8. inputPart1 :: String
  9. inputPart1 = [str|$ cd /
  10. |$ ls
  11. |dir a
  12. |14848514 b.txt
  13. |8504156 c.dat
  14. |dir d
  15. |$ cd a
  16. |$ ls
  17. |dir e
  18. |29116 f
  19. |2557 g
  20. |62596 h.lst
  21. |$ cd e
  22. |$ ls
  23. |584 i
  24. |$ cd ..
  25. |$ cd ..
  26. |$ cd d
  27. |$ ls
  28. |4060174 j
  29. |8033020 d.log
  30. |5626152 d.ext
  31. |7214296 k
  32. |]
  33. cdTerm :: [TerminalCommand]
  34. cdTerm = forceRight $ parseTerminalLines
  35. [str|$ cd foo
  36. |$ ls
  37. |23 f
  38. |34 f2
  39. |dir d
  40. |$ cd ..
  41. |]
  42. cdOutTerm :: [TerminalCommand]
  43. cdOutTerm = forceRight $ parseTerminalLines
  44. [str|$ cd foo
  45. |$ ls
  46. |42 f
  47. |$ cd ..
  48. |$ cd bar
  49. |$ ls
  50. |100 baba
  51. |$ cd x
  52. |$ cd /
  53. |$ ls
  54. |23 f
  55. |dir foo
  56. |dir bar
  57. |]
  58. cdOutParsed :: [TerminalCommand]
  59. cdOutParsed = [
  60. In "foo",
  61. Listing [FileListing "f" 42],
  62. Out,
  63. In "bar",
  64. Listing [FileListing "baba" 100],
  65. In "x",
  66. Root,
  67. Listing [FileListing "f" 23, DirListing "foo", DirListing "bar"]
  68. ]
  69. forceRight :: Either a b -> b
  70. forceRight (Left _) = error "forced Right but got Left"
  71. forceRight (Right b) = b
  72. spec :: Spec
  73. spec =
  74. describe "Day7" $ do
  75. describe "Part1" $ do
  76. describe "parser" $ do
  77. it "parses an ls command" $ do
  78. parseTerminalLines "$ ls\n" `shouldBe` Right [Listing []]
  79. it "parses a cd up command" $ do
  80. parseTerminalLines "$ cd ..\n" `shouldBe` Right [Out]
  81. it "parses a cd root command" $ do
  82. parseTerminalLines "$ cd /\n" `shouldBe` Right [Root]
  83. it "parses a cd in command" $ do
  84. parseTerminalLines "$ cd dirname\n" `shouldBe` Right [In "dirname"]
  85. it "parses a file listing line" $ do
  86. parseTerminalLines "$ ls\n1234 f\n$ cd foo\n" `shouldBe` Right [Listing [FileListing "f" 1234], In "foo"]
  87. it "parses a larger shell log" $ do
  88. cdOutTerm `shouldBe` cdOutParsed
  89. describe "tree" $ do
  90. it "reads a listing" $ do
  91. buildTree [Listing [FileListing "f" 123]] `shouldBe`
  92. mkdir { files = Map.singleton "f" 123, isRoot = True }
  93. it "changes dir" $ do
  94. buildTree cdTerm `shouldBe`
  95. mkdir {
  96. sub = Map.fromList [
  97. ("foo", mkdir { files = Map.fromList [("f", 23), ("f2", 34)] })
  98. ],
  99. files = Map.empty,
  100. isRoot = True
  101. }
  102. it "changes dir outwards" $ do
  103. buildTree cdOutTerm `shouldBe`
  104. mkdir {
  105. sub = Map.fromList [
  106. ("foo", mkdir { files = Map.fromList [("f", 42)] } ),
  107. ("bar", mkdir {
  108. sub = Map.fromList [("x", mkdir)],
  109. files = Map.fromList [("baba", 100)]
  110. } )
  111. ],
  112. files = Map.fromList [("f", 23)],
  113. isRoot = True
  114. }
  115. it "calculates size of directories" $ do
  116. calculateSize mkdir { files = Map.fromList [("f", 23), ("f2", 34)] }
  117. `shouldBe` 23 + 34
  118. calculateSize mkdir {
  119. sub = Map.fromList [ ("d", mkdir { files = Map.fromList [("f", 23), ("f2", 34)] })] }
  120. `shouldBe` 23 + 34
  121. it "sums stuff up" $ do
  122. let parsed = forceRight $ parseTerminalLines inputPart1
  123. let tree = buildTree parsed
  124. let filtered = filterDirectories (<= 100000) tree
  125. let summed = sumUp filtered
  126. summed `shouldBe` 95437