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 3.9KB

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