瀏覽代碼

Day 5 Part 2

main
Jens Kadenbach 1 年之前
父節點
當前提交
d62259bf75
共有 6 個檔案被更改,包括 124 行新增79 行删除
  1. 2
    0
      aoc2022.cabal
  2. 3
    0
      src/Day5.hs
  3. 2
    79
      src/Day5/Part1.hs
  4. 24
    0
      src/Day5/Part2.hs
  5. 84
    0
      src/Day5/Shared.hs
  6. 9
    0
      test/Day5Spec.hs

+ 2
- 0
aoc2022.cabal 查看文件

@@ -41,6 +41,8 @@ library
41 41
       Day4.Shared
42 42
       Day5
43 43
       Day5.Part1
44
+      Day5.Part2
45
+      Day5.Shared
44 46
       Lib
45 47
   other-modules:
46 48
       Paths_aoc2022

+ 3
- 0
src/Day5.hs 查看文件

@@ -1,6 +1,7 @@
1 1
 module Day5 (day5) where
2 2
 
3 3
 import Day5.Part1
4
+import Day5.Part2
4 5
 
5 6
 
6 7
 day5 :: IO ()
@@ -9,3 +10,5 @@ day5 = do
9 10
    putStrLn "Day5"
10 11
    let message = day5_1 input
11 12
    putStrLn ("Message from crates: " ++ message)
13
+   let secondMessage = day5_2 input
14
+   putStrLn ("Actuale message from crates: " ++ secondMessage)

+ 2
- 79
src/Day5/Part1.hs 查看文件

@@ -1,82 +1,11 @@
1 1
 module Day5.Part1 (
2
-  StackIndex (..),
3
-  Operation (..),
4
-  Stack (..),
5
-  parseOperation,
6
-  parseStacks,
7
-  parseRow,
8
-  combineRows,
9
-  parseInput,
10 2
   executeOperation,
11
-  zipWithPadding,
12
-  findTopOfStacks,
13 3
   day5_1
14 4
 ) where
15 5
 
16 6
 import qualified Data.Sequence as S
17
-import Data.Sequence (Seq (..))
18 7
 import Data.Foldable (toList)
19
-
20
-newtype StackIndex = StackIndex Int deriving (Show, Eq, Ord)
21
-asInt :: StackIndex -> Int
22
-asInt (StackIndex i) = i - 1
23
-
24
-data Operation = Operation
25
-                    { count :: Int
26
-                    , from :: StackIndex
27
-                    , to :: StackIndex} deriving (Show, Eq)
28
-
29
-type Content = Char
30
-newtype Stack = Stack [Content] deriving (Show, Eq)
31
-
32
-content :: Stack  -> [Content]
33
-content (Stack c) = c
34
-
35
-instance Semigroup Stack where
36
-  (Stack x) <> (Stack y) = Stack (x ++ y)
37
-
38
-instance Monoid Stack where
39
-  mempty = Stack []
40
-
41
-type Row = S.Seq Stack
42
-
43
-parseOperation :: String -> Operation
44
-parseOperation line = Operation {
45
- count = read $ parts !! 1,
46
-  from = StackIndex (read $ parts !! 3),
47
-  to = StackIndex (read $ parts !! 5)
48
-  }
49
-  where
50
-    parts = words line
51
-
52
-parseStacks :: [String] -> Row
53
-parseStacks input = foldl combineRows S.empty rows
54
-  where
55
-    rows = map parseRow input
56
-
57
-parseRow :: String -> Row
58
-parseRow ('[':c:']':' ':cs) = Stack [c] :<| parseRow cs
59
-parseRow (' ':' ':' ':' ':cs) = Stack [] :<| parseRow cs
60
-parseRow ['[', c, ']'] = S.singleton $ Stack [c]
61
-parseRow [' ', ' ', ' '] = S.singleton $ Stack []
62
-parseRow (' ':'1':_) = S.empty -- skip last line
63
-parseRow cs = error ("parseRow: unexpected Row \"" ++ cs ++ "\"")
64
-
65
-combineRows :: Row -> Row -> Row
66
-combineRows S.Empty row = row
67
-combineRows row S.Empty = row
68
-combineRows up down = S.fromList [x <> y | (x,y) <- zipWithPadding up down]
69
-
70
-zipWithPadding :: (Monoid a, Monoid b) => S.Seq a -> S.Seq b -> [(a,b)]
71
-zipWithPadding (x :<| xs)  (y :<| ys)  = (x,y) : zipWithPadding xs ys
72
-zipWithPadding S.Empty (y :<| ys)  = (mempty, y) : zipWithPadding S.empty ys
73
-zipWithPadding (x :<| xs)  S.Empty = (x, mempty) : zipWithPadding xs S.empty
74
-zipWithPadding S.Empty  S.Empty = []
75
-
76
-parseInput :: String -> (Row, [Operation])
77
-parseInput input = (parseStacks stackInput, map parseOperation (drop 1 operationInput))
78
-  where
79
-    (stackInput, operationInput) = break ("" ==) $ lines input
8
+import Day5.Shared
80 9
 
81 10
 executeOperation :: Row -> Operation -> Row
82 11
 executeOperation row op
@@ -90,13 +19,7 @@ executeOperation row op
90 19
     updatedTarget = Stack (movedContent : content targetStack)
91 20
     updatedRow = S.update (asInt $ to op) updatedTarget $ S.update (asInt $ from op) updatedOrigin row
92 21
 
93
-findTopOfStacks :: Row -> Seq Content
94
-findTopOfStacks row = head . content <$> row
95
-
96
-executeAllOperations :: Row -> [Operation] -> Row
97
-executeAllOperations = foldl executeOperation
98
-
99 22
 day5_1 :: String -> String
100
-day5_1 input = toList . findTopOfStacks $ executeAllOperations row operations
23
+day5_1 input = toList . findTopOfStacks $ foldl executeOperation row operations
101 24
   where
102 25
     (row, operations) = parseInput input

+ 24
- 0
src/Day5/Part2.hs 查看文件

@@ -0,0 +1,24 @@
1
+module Day5.Part2 (
2
+  execute9001Operation,
3
+  day5_2
4
+) where
5
+
6
+import qualified Data.Sequence as S
7
+import Data.Foldable (toList)
8
+import Day5.Shared
9
+
10
+execute9001Operation :: Row -> Operation -> Row
11
+execute9001Operation row op
12
+  = updatedRow 
13
+  where
14
+    originStack = row `S.index` asInt (from op)
15
+    targetStack = row `S.index` asInt (to op)
16
+    movedContent = take (count op) $ content originStack
17
+    updatedOrigin = Stack (drop (count op) $ content originStack)
18
+    updatedTarget = Stack (movedContent ++ content targetStack)
19
+    updatedRow = S.update (asInt $ to op) updatedTarget $ S.update (asInt $ from op) updatedOrigin row
20
+
21
+day5_2 :: String -> String
22
+day5_2 input = toList . findTopOfStacks $ foldl execute9001Operation row operations
23
+  where
24
+    (row, operations) = parseInput input

+ 84
- 0
src/Day5/Shared.hs 查看文件

@@ -0,0 +1,84 @@
1
+module Day5.Shared (
2
+  StackIndex (..),
3
+  Operation (..),
4
+  Stack (..),
5
+  Row,
6
+  Content,
7
+  asInt,
8
+  content,
9
+  parseOperation,
10
+  parseStacks,
11
+  parseRow,
12
+  combineRows,
13
+  parseInput,
14
+  zipWithPadding,
15
+  findTopOfStacks
16
+) where
17
+
18
+import qualified Data.Sequence as S
19
+import Data.Sequence (Seq (..))
20
+
21
+newtype StackIndex = StackIndex Int deriving (Show, Eq, Ord)
22
+asInt :: StackIndex -> Int
23
+asInt (StackIndex i) = i - 1
24
+
25
+data Operation = Operation
26
+                    { count :: Int
27
+                    , from :: StackIndex
28
+                    , to :: StackIndex} deriving (Show, Eq)
29
+
30
+type Content = Char
31
+newtype Stack = Stack [Content] deriving (Show, Eq)
32
+
33
+content :: Stack  -> [Content]
34
+content (Stack c) = c
35
+
36
+instance Semigroup Stack where
37
+  (Stack x) <> (Stack y) = Stack (x ++ y)
38
+
39
+instance Monoid Stack where
40
+  mempty = Stack []
41
+
42
+type Row = S.Seq Stack
43
+
44
+parseOperation :: String -> Operation
45
+parseOperation line = Operation {
46
+ count = read $ parts !! 1,
47
+  from = StackIndex (read $ parts !! 3),
48
+  to = StackIndex (read $ parts !! 5)
49
+  }
50
+  where
51
+    parts = words line
52
+
53
+parseStacks :: [String] -> Row
54
+parseStacks input = foldl combineRows S.empty rows
55
+  where
56
+    rows = map parseRow input
57
+
58
+parseRow :: String -> Row
59
+parseRow ('[':c:']':' ':cs) = Stack [c] :<| parseRow cs
60
+parseRow (' ':' ':' ':' ':cs) = Stack [] :<| parseRow cs
61
+parseRow ['[', c, ']'] = S.singleton $ Stack [c]
62
+parseRow [' ', ' ', ' '] = S.singleton $ Stack []
63
+parseRow (' ':'1':_) = S.empty -- skip last line
64
+parseRow cs = error ("parseRow: unexpected Row \"" ++ cs ++ "\"")
65
+
66
+combineRows :: Row -> Row -> Row
67
+combineRows S.Empty row = row
68
+combineRows row S.Empty = row
69
+combineRows up down = S.fromList [x <> y | (x,y) <- zipWithPadding up down]
70
+
71
+zipWithPadding :: (Monoid a, Monoid b) => S.Seq a -> S.Seq b -> [(a,b)]
72
+zipWithPadding (x :<| xs)  (y :<| ys)  = (x,y) : zipWithPadding xs ys
73
+zipWithPadding S.Empty (y :<| ys)  = (mempty, y) : zipWithPadding S.empty ys
74
+zipWithPadding (x :<| xs)  S.Empty = (x, mempty) : zipWithPadding xs S.empty
75
+zipWithPadding S.Empty  S.Empty = []
76
+
77
+parseInput :: String -> (Row, [Operation])
78
+parseInput input = (parseStacks stackInput, map parseOperation (drop 1 operationInput))
79
+  where
80
+    (stackInput, operationInput) = break ("" ==) $ lines input
81
+
82
+
83
+findTopOfStacks :: Row -> Seq Content
84
+findTopOfStacks row = head . content <$> row

+ 9
- 0
test/Day5Spec.hs 查看文件

@@ -6,6 +6,8 @@ import Text.Heredoc
6 6
 import qualified Data.Sequence as S
7 7
 
8 8
 import Day5.Part1
9
+import Day5.Part2
10
+import Day5.Shared
9 11
 
10 12
 inputPart1 :: String
11 13
 inputPart1 = [str|    [D]
@@ -72,4 +74,11 @@ spec =
72 74
          findTopOfStacks row `shouldBe` S.fromList "NDP"
73 75
       it "solves the demo" $ do
74 76
          day5_1 inputPart1 `shouldBe` "CMZ"
77
+    describe "Part1" $ do
78
+      it "executes 9001 operations on a row" $ do
79
+        let op = Operation { count = 2, from = StackIndex 2, to = StackIndex 3}
80
+        let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
81
+        execute9001Operation row op `shouldBe` S.fromList [Stack "NZ", Stack "M", Stack "DCP"]
82
+      it "solves the demo" $ do
83
+         day5_2 inputPart1 `shouldBe` "MCD"
75 84
 

Loading…
取消
儲存