|
@@ -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
|