2 コミット

作成者 SHA1 メッセージ 日付
  Jens Kadenbach 714980da64 Day 11 2年前
  Jens Kadenbach 17e4d9d0ab Day 10 2年前
10個のファイルの変更750行の追加1行の削除
  1. 14
    0
      aoc2022.cabal
  2. 3
    0
      package.yaml
  3. 139
    0
      ressources/day10-input
  4. 55
    0
      ressources/day11-input
  5. 76
    0
      src/Day10.hs
  6. 101
    0
      src/Day11.hs
  7. 98
    0
      src/Day11/Parser.hs
  8. 3
    1
      src/Lib.hs
  9. 193
    0
      test/Day10Spec.hs
  10. 68
    0
      test/Day11Spec.hs

+ 14
- 0
aoc2022.cabal ファイルの表示

@@ -27,6 +27,9 @@ library
27 27
   exposed-modules:
28 28
       Day1
29 29
       Day1.Internal
30
+      Day10
31
+      Day11
32
+      Day11.Parser
30 33
       Day2
31 34
       Day2.Part1
32 35
       Day2.Part2
@@ -62,10 +65,13 @@ library
62 65
     , containers
63 66
     , heredoc
64 67
     , hspec
68
+    , hspec-megaparsec
65 69
     , lens
66 70
     , matrix
67 71
     , megaparsec
72
+    , mtl
68 73
     , parsec
74
+    , sort
69 75
     , split
70 76
     , text
71 77
     , transformers
@@ -86,10 +92,13 @@ executable aoc2022-exe
86 92
     , containers
87 93
     , heredoc
88 94
     , hspec
95
+    , hspec-megaparsec
89 96
     , lens
90 97
     , matrix
91 98
     , megaparsec
99
+    , mtl
92 100
     , parsec
101
+    , sort
93 102
     , split
94 103
     , text
95 104
     , transformers
@@ -100,6 +109,8 @@ test-suite aoc2022-test
100 109
   type: exitcode-stdio-1.0
101 110
   main-is: Spec.hs
102 111
   other-modules:
112
+      Day10Spec
113
+      Day11Spec
103 114
       Day1Spec
104 115
       Day2Spec
105 116
       Day3Spec
@@ -120,10 +131,13 @@ test-suite aoc2022-test
120 131
     , containers
121 132
     , heredoc
122 133
     , hspec
134
+    , hspec-megaparsec
123 135
     , lens
124 136
     , matrix
125 137
     , megaparsec
138
+    , mtl
126 139
     , parsec
140
+    , sort
127 141
     , split
128 142
     , text
129 143
     , transformers

+ 3
- 0
package.yaml ファイルの表示

@@ -34,6 +34,9 @@ dependencies:
34 34
 - vector
35 35
 - megaparsec
36 36
 - transformers
37
+- hspec-megaparsec
38
+- mtl
39
+- sort
37 40
 
38 41
 ghc-options:
39 42
 - -Wall

+ 139
- 0
ressources/day10-input ファイルの表示

@@ -0,0 +1,139 @@
1
+addx 1
2
+noop
3
+noop
4
+noop
5
+addx 5
6
+addx 5
7
+noop
8
+noop
9
+addx 9
10
+addx -5
11
+addx 1
12
+addx 4
13
+noop
14
+noop
15
+noop
16
+addx 6
17
+addx -1
18
+noop
19
+addx 5
20
+addx -2
21
+addx 7
22
+noop
23
+addx 3
24
+addx -2
25
+addx -38
26
+noop
27
+noop
28
+addx 32
29
+addx -22
30
+noop
31
+addx 2
32
+addx 3
33
+noop
34
+addx 2
35
+addx -2
36
+addx 7
37
+addx -2
38
+noop
39
+addx 3
40
+addx 2
41
+addx 5
42
+addx 2
43
+addx -5
44
+addx 10
45
+noop
46
+addx 3
47
+noop
48
+addx -38
49
+addx 1
50
+addx 27
51
+noop
52
+addx -20
53
+noop
54
+addx 2
55
+addx 27
56
+noop
57
+addx -22
58
+noop
59
+noop
60
+noop
61
+noop
62
+addx 3
63
+addx 5
64
+addx 2
65
+addx -11
66
+addx 16
67
+addx -2
68
+addx -17
69
+addx 24
70
+noop
71
+noop
72
+addx 1
73
+addx -38
74
+addx 15
75
+addx 10
76
+addx -15
77
+noop
78
+addx 2
79
+addx 26
80
+noop
81
+addx -21
82
+addx 19
83
+addx -33
84
+addx 19
85
+noop
86
+addx -6
87
+addx 9
88
+addx 3
89
+addx 4
90
+addx -21
91
+addx 4
92
+addx 20
93
+noop
94
+addx 3
95
+addx -38
96
+addx 28
97
+addx -21
98
+addx 9
99
+addx -8
100
+addx 2
101
+addx 5
102
+addx 2
103
+addx -9
104
+addx 14
105
+addx -2
106
+addx -5
107
+addx 12
108
+addx 3
109
+addx -2
110
+addx 2
111
+addx 7
112
+noop
113
+noop
114
+addx -27
115
+addx 28
116
+addx -36
117
+noop
118
+addx 1
119
+addx 5
120
+addx -1
121
+noop
122
+addx 6
123
+addx -1
124
+addx 5
125
+addx 5
126
+noop
127
+noop
128
+addx -2
129
+addx 20
130
+addx -10
131
+addx -3
132
+addx 1
133
+addx 3
134
+addx 2
135
+addx 4
136
+addx 3
137
+noop
138
+addx -30
139
+noop

+ 55
- 0
ressources/day11-input ファイルの表示

@@ -0,0 +1,55 @@
1
+Monkey 0:
2
+  Starting items: 52, 78, 79, 63, 51, 94
3
+  Operation: new = old * 13
4
+  Test: divisible by 5
5
+    If true: throw to monkey 1
6
+    If false: throw to monkey 6
7
+
8
+Monkey 1:
9
+  Starting items: 77, 94, 70, 83, 53
10
+  Operation: new = old + 3
11
+  Test: divisible by 7
12
+    If true: throw to monkey 5
13
+    If false: throw to monkey 3
14
+
15
+Monkey 2:
16
+  Starting items: 98, 50, 76
17
+  Operation: new = old * old
18
+  Test: divisible by 13
19
+    If true: throw to monkey 0
20
+    If false: throw to monkey 6
21
+
22
+Monkey 3:
23
+  Starting items: 92, 91, 61, 75, 99, 63, 84, 69
24
+  Operation: new = old + 5
25
+  Test: divisible by 11
26
+    If true: throw to monkey 5
27
+    If false: throw to monkey 7
28
+
29
+Monkey 4:
30
+  Starting items: 51, 53, 83, 52
31
+  Operation: new = old + 7
32
+  Test: divisible by 3
33
+    If true: throw to monkey 2
34
+    If false: throw to monkey 0
35
+
36
+Monkey 5:
37
+  Starting items: 76, 76
38
+  Operation: new = old + 4
39
+  Test: divisible by 2
40
+    If true: throw to monkey 4
41
+    If false: throw to monkey 7
42
+
43
+Monkey 6:
44
+  Starting items: 75, 59, 93, 69, 76, 96, 65
45
+  Operation: new = old * 19
46
+  Test: divisible by 17
47
+    If true: throw to monkey 1
48
+    If false: throw to monkey 3
49
+
50
+Monkey 7:
51
+  Starting items: 89
52
+  Operation: new = old + 2
53
+  Test: divisible by 19
54
+    If true: throw to monkey 2
55
+    If false: throw to monkey 4

+ 76
- 0
src/Day10.hs ファイルの表示

@@ -0,0 +1,76 @@
1
+module Day10
2
+  ( Instruction (..),
3
+    parseProgram,
4
+    signalStrength,
5
+    executeProgram,
6
+    draw,
7
+    isSpriteDrawn,
8
+    day10
9
+  )
10
+where
11
+
12
+import Control.Arrow ((>>>))
13
+import Data.List.Split (chunksOf)
14
+
15
+data Instruction = Addx Int | Noop
16
+  deriving (Show, Eq)
17
+
18
+newtype Pixel = Pixel Bool deriving (Eq)
19
+
20
+instance Show Pixel where
21
+  show (Pixel True) = "▓"
22
+  show (Pixel False) = "░"
23
+
24
+
25
+type CRT = String
26
+
27
+parseProgram :: String -> [Instruction]
28
+parseProgram = lines >>> map parseProgram'
29
+  where
30
+    parseProgram' :: String -> Instruction
31
+    parseProgram' "noop" = Noop
32
+    parseProgram' line = splitAt 4 >>> snd >>> read >>> Addx $ line
33
+
34
+
35
+isSpriteDrawn :: Int -> Int -> Bool
36
+isSpriteDrawn x p = abs (position - x) <= 1
37
+  where
38
+    position = p `mod` 40
39
+
40
+draw :: [Int] -> CRT
41
+draw registerValues = unlines lastPicture
42
+  where
43
+    pictures = zipWith isSpriteDrawn registerValues [0..]
44
+    lastPicture = concatMap (show . Pixel) >>> chunksOf 40 $ pictures
45
+
46
+
47
+
48
+signalStrength :: [Int] -> Int
49
+signalStrength e = start + sum computedRest
50
+  where
51
+    start = e !! 20 * 20
52
+    rest = drop 20 e
53
+    withCycle = zip [60, 100..] (every 40 rest)
54
+    computedRest = [c*r | (c,r) <- withCycle]
55
+
56
+every :: Int -> [a] -> [a]
57
+every n xs = case drop (n-1) xs of
58
+              y : ys -> y : every n ys
59
+              [] -> []
60
+
61
+executeProgram :: [Instruction] -> [Int]
62
+executeProgram = scanl (+) 1 . concatMap execOne
63
+  where
64
+    execOne instruction = case instruction of
65
+        Noop   -> [0]
66
+        Addx x -> [0, x]
67
+
68
+day10 :: IO ()
69
+day10 = do
70
+  input <- readFile "ressources/day10-input"
71
+  putStrLn "Day10"
72
+  let states = parseProgram >>> executeProgram $ input
73
+  let signal = signalStrength states
74
+  let crt = draw states
75
+  putStrLn ("Signal strength: " ++ show signal)
76
+  putStrLn ("CRT picture: \n" ++ crt)

+ 101
- 0
src/Day11.hs ファイルの表示

@@ -0,0 +1,101 @@
1
+{-# LANGUAGE OverloadedStrings #-}
2
+
3
+module Day11
4
+  ( runMonkeyMachine,
5
+    mostActiveMonkeys,
6
+    monkeyBusiness,
7
+    day11,
8
+    runPart1Machine,
9
+    runPart2Machine,
10
+    worryLimit,
11
+    divideBy3,
12
+  )
13
+where
14
+
15
+import Control.Monad.State.Strict (execState, get, modify', put)
16
+import qualified Control.Monad.State.Strict as St
17
+import Data.Foldable (forM_, toList)
18
+import Data.List (sortOn)
19
+import Data.Ord (Down (..))
20
+import Data.Sequence ((|>))
21
+import qualified Data.Sequence as S
22
+import Data.Text (pack)
23
+import Day11.Parser
24
+
25
+day11 :: IO ()
26
+day11 = do
27
+  input <- readFile "ressources/day11-input"
28
+  putStrLn "Day11"
29
+  let monkeys = (monkeyBusiness . mostActiveMonkeys . runPart1Machine . parseMonkeys) (pack input)
30
+  putStrLn ("Part 1 monkey business: " ++ show monkeys)
31
+  let monkeys' = (monkeyBusiness . mostActiveMonkeys . runPart2Machine . parseMonkeys) (pack input)
32
+  putStrLn ("Part 2 monkey business: " ++ show monkeys')
33
+
34
+type MonkeyState = St.State (S.Seq Monkey)
35
+
36
+runPart1Machine :: [Monkey] -> [Monkey]
37
+runPart1Machine = runMonkeyMachine divideBy3 20
38
+
39
+runPart2Machine :: [Monkey] -> [Monkey]
40
+runPart2Machine monkeys = runMonkeyMachine (worryLimit monkeys) 10000 monkeys
41
+
42
+worryLimit :: [Monkey] -> WorryReducer
43
+worryLimit monkeys = (`mod` limit)
44
+  where
45
+    limit = product $ map _test monkeys
46
+
47
+    
48
+runMonkeyMachine :: WorryReducer -> Int -> [Monkey] -> [Monkey]
49
+runMonkeyMachine eval i monkeys = toList (infiniteMachine !! i)
50
+  where
51
+    infiniteMachine = iterate go $ S.fromList monkeys
52
+    go :: S.Seq Monkey -> S.Seq Monkey
53
+    go m = execState go' m
54
+    go' :: MonkeyState ()
55
+    go' = mapM_ (doMonkey eval) [0 .. length monkeys - 1]
56
+
57
+mostActiveMonkeys :: [Monkey] -> [Monkey]
58
+mostActiveMonkeys = take 2 . sortOn (Down . _inspectionCount)
59
+
60
+monkeyBusiness :: [Monkey] -> Int
61
+monkeyBusiness = product . map _inspectionCount
62
+
63
+-- update a sequence of monkeys according to the moves of the monkey at position idx
64
+doMonkey :: WorryReducer -> Int -> MonkeyState ()
65
+doMonkey reducer idx = do
66
+  horde <- get
67
+  let m = horde `S.index` idx
68
+  let targets = fmap (evalMonkey reducer m) (_items m)
69
+  let m' = m {_items = S.empty, _inspectionCount = _inspectionCount m + S.length (_items m)}
70
+  put $ S.update idx m' horde
71
+  forM_ targets $ \movement ->
72
+    modify' (move movement)
73
+
74
+-- update other monkeys according to a list of calculated moves
75
+move :: (Int, Int) -> S.Seq Monkey -> S.Seq Monkey
76
+move (to, item) horde
77
+  | item < 0 = error ("Item worry level overflow: " ++ show (to, item))
78
+  | otherwise =
79
+    let m = horde `S.index` to
80
+        m' = m {_items = _items m |> item}
81
+     in S.update to m' horde
82
+
83
+type WorryReducer = Int -> Int
84
+
85
+divideBy3 :: WorryReducer
86
+divideBy3 = flip div 3
87
+
88
+evalMonkey :: WorryReducer -> Monkey -> Int -> (Int, Int)
89
+evalMonkey reducer monkey item = (target, newLevel)
90
+  where
91
+    afterOp = case _operation monkey of
92
+      Add Old -> item * 2
93
+      Add (Fixed x) -> item + x
94
+      Multiply Old -> item * item
95
+      Multiply (Fixed x) -> item * x
96
+    newLevel = reducer afterOp
97
+    isDivisible = newLevel `mod` _test monkey == 0
98
+    target =
99
+      if isDivisible
100
+        then _ifDivisible monkey
101
+        else _otherwise monkey

+ 98
- 0
src/Day11/Parser.hs ファイルの表示

@@ -0,0 +1,98 @@
1
+{-# LANGUAGE OverloadedStrings #-}
2
+module Day11.Parser (
3
+  parseMonkeys,
4
+  Monkey (..),
5
+  Operation (..),
6
+  Op (..),
7
+)
8
+ where
9
+
10
+import Text.Megaparsec
11
+import Text.Megaparsec.Char
12
+import Data.Text (Text)
13
+import Data.Void (Void)
14
+import Control.Monad (void)
15
+import qualified Data.Sequence as S
16
+
17
+type Parser = Parsec Void Text
18
+
19
+data Op = Fixed Int | Old
20
+  deriving (Show, Eq)
21
+
22
+data Operation = Add Op | Multiply Op
23
+  deriving (Show, Eq)
24
+
25
+data Monkey = Monkey
26
+  { _nr :: Int
27
+  , _items :: S.Seq Int
28
+  , _operation :: Operation
29
+  , _test :: Int
30
+  , _ifDivisible :: Int
31
+  , _otherwise :: Int
32
+  , _inspectionCount :: Int }
33
+  deriving (Show, Eq)
34
+
35
+parseMonkeys :: Text -> [Monkey]
36
+parseMonkeys input = case parse (monkey `sepBy` void eol) "" input of
37
+  Left err -> error (show err)
38
+  Right result -> result
39
+
40
+monkey :: Parser Monkey
41
+monkey = do
42
+  void (string "Monkey ")
43
+  nr <- many numberChar
44
+  void (char ':')
45
+  void eol
46
+  startingItems <- items
47
+  operation <- op
48
+  d <- divisor
49
+  ifDiv <- ifDivisible
50
+  ifOther <- ifOtherwise
51
+  return Monkey
52
+   { _nr=read nr
53
+   , _items=S.fromList startingItems
54
+   , _operation=operation
55
+   , _test=d
56
+   , _ifDivisible=ifDiv
57
+   , _otherwise=ifOther
58
+   , _inspectionCount=0 }
59
+
60
+ifDivisible :: Parser Int
61
+ifDivisible = do
62
+  x <- read <$> (string "    If true: throw to monkey " >> many numberChar)
63
+  void eol
64
+  return x
65
+
66
+ifOtherwise :: Parser Int
67
+ifOtherwise = do
68
+  x <- read <$> (string "    If false: throw to monkey " >> many numberChar)
69
+  void eol
70
+  return x
71
+
72
+divisor :: Parser Int
73
+divisor = do
74
+  d <- read <$> (string "  Test: divisible by " >> many numberChar)
75
+  void eol
76
+  return d
77
+
78
+items :: Parser [Int]
79
+items = do
80
+  void (string "  Starting items: ")
81
+  startingItems <- sepBy1 (many numberChar) (string ", ")
82
+  void eol
83
+  return (map read startingItems)
84
+
85
+op :: Parser Operation
86
+op = do
87
+  o <- void (string "  Operation: new = old ") >> addOp <|> mulOp
88
+  void eol
89
+  return o
90
+  where
91
+    old = string "old" >> return Old
92
+    num = Fixed . read <$> many numberChar
93
+    addOp = do
94
+      void (string "+ ")
95
+      Add <$> (old <|> num)
96
+    mulOp = do
97
+      void (string "* ")
98
+      Multiply <$> (old <|> num)

+ 3
- 1
src/Lib.hs ファイルの表示

@@ -11,9 +11,11 @@ import Day6 (day6)
11 11
 import Day7 (day7)
12 12
 import Day8 (day8)
13 13
 import Day9 (day9)
14
+import Day10 (day10)
15
+import Day11 (day11)
14 16
 
15 17
 days :: [IO ()]
16
-days = [day1, day2, day3, day4, day5, day6, day7, day8, day9]
18
+days = [day1, day2, day3, day4, day5, day6, day7, day8, day9, day10, day11]
17 19
 
18 20
 sep :: IO ()
19 21
 sep = putStrLn "---------"

+ 193
- 0
test/Day10Spec.hs ファイルの表示

@@ -0,0 +1,193 @@
1
+{-# LANGUAGE QuasiQuotes #-}
2
+
3
+module Day10Spec (spec) where
4
+
5
+import Control.Arrow ((>>>))
6
+import Day10
7
+import Test.Hspec
8
+import Text.Heredoc
9
+
10
+testInput :: String
11
+testInput = [str|noop
12
+                |addx 3
13
+                |addx -5
14
+                |]
15
+
16
+testProgram :: [Instruction]
17
+testProgram = [Noop, Addx 3, Addx (-5)]
18
+
19
+testInput2 :: String
20
+testInput2 = [str|addx 15
21
+                 |addx -11
22
+                 |addx 6
23
+                 |addx -3
24
+                 |addx 5
25
+                 |addx -1
26
+                 |addx -8
27
+                 |addx 13
28
+                 |addx 4
29
+                 |noop
30
+                 |addx -1
31
+                 |addx 5
32
+                 |addx -1
33
+                 |addx 5
34
+                 |addx -1
35
+                 |addx 5
36
+                 |addx -1
37
+                 |addx 5
38
+                 |addx -1
39
+                 |addx -35
40
+                 |addx 1
41
+                 |addx 24
42
+                 |addx -19
43
+                 |addx 1
44
+                 |addx 16
45
+                 |addx -11
46
+                 |noop
47
+                 |noop
48
+                 |addx 21
49
+                 |addx -15
50
+                 |noop
51
+                 |noop
52
+                 |addx -3
53
+                 |addx 9
54
+                 |addx 1
55
+                 |addx -3
56
+                 |addx 8
57
+                 |addx 1
58
+                 |addx 5
59
+                 |noop
60
+                 |noop
61
+                 |noop
62
+                 |noop
63
+                 |noop
64
+                 |addx -36
65
+                 |noop
66
+                 |addx 1
67
+                 |addx 7
68
+                 |noop
69
+                 |noop
70
+                 |noop
71
+                 |addx 2
72
+                 |addx 6
73
+                 |noop
74
+                 |noop
75
+                 |noop
76
+                 |noop
77
+                 |noop
78
+                 |addx 1
79
+                 |noop
80
+                 |noop
81
+                 |addx 7
82
+                 |addx 1
83
+                 |noop
84
+                 |addx -13
85
+                 |addx 13
86
+                 |addx 7
87
+                 |noop
88
+                 |addx 1
89
+                 |addx -33
90
+                 |noop
91
+                 |noop
92
+                 |noop
93
+                 |addx 2
94
+                 |noop
95
+                 |noop
96
+                 |noop
97
+                 |addx 8
98
+                 |noop
99
+                 |addx -1
100
+                 |addx 2
101
+                 |addx 1
102
+                 |noop
103
+                 |addx 17
104
+                 |addx -9
105
+                 |addx 1
106
+                 |addx 1
107
+                 |addx -3
108
+                 |addx 11
109
+                 |noop
110
+                 |noop
111
+                 |addx 1
112
+                 |noop
113
+                 |addx 1
114
+                 |noop
115
+                 |noop
116
+                 |addx -13
117
+                 |addx -19
118
+                 |addx 1
119
+                 |addx 3
120
+                 |addx 26
121
+                 |addx -30
122
+                 |addx 12
123
+                 |addx -1
124
+                 |addx 3
125
+                 |addx 1
126
+                 |noop
127
+                 |noop
128
+                 |noop
129
+                 |addx -9
130
+                 |addx 18
131
+                 |addx 1
132
+                 |addx 2
133
+                 |noop
134
+                 |noop
135
+                 |addx 9
136
+                 |noop
137
+                 |noop
138
+                 |noop
139
+                 |addx -1
140
+                 |addx 2
141
+                 |addx -37
142
+                 |addx 1
143
+                 |addx 3
144
+                 |noop
145
+                 |addx 15
146
+                 |addx -21
147
+                 |addx 22
148
+                 |addx -6
149
+                 |addx 1
150
+                 |noop
151
+                 |addx 2
152
+                 |addx 1
153
+                 |noop
154
+                 |addx -10
155
+                 |noop
156
+                 |noop
157
+                 |addx 20
158
+                 |addx 1
159
+                 |addx 2
160
+                 |addx 2
161
+                 |addx -6
162
+                 |addx -11
163
+                 |noop
164
+                 |noop
165
+                 |noop
166
+                |]
167
+
168
+spec :: Spec
169
+spec =
170
+  describe "Day10" $ do
171
+    describe "Part1" $ do
172
+      it "parses" $ do
173
+        parseProgram testInput `shouldBe` testProgram
174
+      it "executes" $ do
175
+        executeProgram testProgram `shouldBe` [1,1,1,4,4,-1]
176
+      it "executes larger program" $ do
177
+        let registerValues = parseProgram >>> executeProgram $ testInput2
178
+        registerValues !! 20 `shouldBe` 21
179
+        registerValues !! 60 `shouldBe` 19
180
+        registerValues !! 100 `shouldBe` 18
181
+        registerValues !! 140 `shouldBe` 21
182
+        registerValues !! 180 `shouldBe` 16
183
+        registerValues !! 220 `shouldBe` 18
184
+      it "computes signal strength" $ do
185
+        let registerValues = parseProgram >>> executeProgram $ testInput2
186
+        signalStrength registerValues `shouldBe` 13140
187
+      it "prints a crt" $ do
188
+        let registerValues = parseProgram >>> executeProgram $ testInput2
189
+        putStrLn $ draw registerValues
190
+      it "sprites drawn" $ do
191
+        isSpriteDrawn 1 1 `shouldBe` True
192
+        isSpriteDrawn 1 1 `shouldBe` True
193
+

+ 68
- 0
test/Day11Spec.hs ファイルの表示

@@ -0,0 +1,68 @@
1
+{-# LANGUAGE OverloadedStrings #-}
2
+{-# LANGUAGE QuasiQuotes #-}
3
+
4
+module Day11Spec (spec) where
5
+
6
+import Data.Foldable (toList)
7
+import qualified Data.Sequence as S
8
+import Data.Text (Text)
9
+import Day11
10
+import Day11.Parser
11
+import Test.Hspec
12
+import Text.Heredoc
13
+import Data.Int (Int64)
14
+
15
+testInput :: Text
16
+testInput =
17
+  [str|Monkey 0:
18
+                |  Starting items: 79, 98
19
+                |  Operation: new = old * 19
20
+                |  Test: divisible by 23
21
+                |    If true: throw to monkey 2
22
+                |    If false: throw to monkey 3
23
+                |
24
+                |Monkey 1:
25
+                |  Starting items: 54, 65, 75, 74
26
+                |  Operation: new = old + 6
27
+                |  Test: divisible by 19
28
+                |    If true: throw to monkey 2
29
+                |    If false: throw to monkey 0
30
+                |
31
+                |Monkey 2:
32
+                |  Starting items: 79, 60, 97
33
+                |  Operation: new = old * old
34
+                |  Test: divisible by 13
35
+                |    If true: throw to monkey 1
36
+                |    If false: throw to monkey 3
37
+                |
38
+                |Monkey 3:
39
+                |  Starting items: 74
40
+                |  Operation: new = old + 3
41
+                |  Test: divisible by 17
42
+                |    If true: throw to monkey 0
43
+                |    If false: throw to monkey 1
44
+                |]
45
+
46
+exampleMonkeys :: [Monkey]
47
+exampleMonkeys = parseMonkeys testInput
48
+
49
+spec :: Spec
50
+spec =
51
+  describe "Day11" $ do
52
+    describe "Part1" $ do
53
+      it "parses" $ do
54
+        head exampleMonkeys `shouldBe` Monkey 0 (S.fromList [79, 98]) (Multiply (Fixed 19)) 23 2 3 0
55
+        _items (exampleMonkeys !! 1) `shouldBe` S.fromList [54, 65, 75, 74]
56
+      it "runs part 1 monkey machine for 20 rounds" $ do
57
+        let monkeys = runMonkeyMachine divideBy3 20 exampleMonkeys
58
+        map _inspectionCount monkeys
59
+          `shouldBe` [101, 95, 7, 105]
60
+        map _inspectionCount (mostActiveMonkeys monkeys) `shouldBe` [105, 101]
61
+        map _nr (mostActiveMonkeys monkeys) `shouldBe` [3, 0]
62
+        monkeyBusiness (mostActiveMonkeys monkeys) `shouldBe` 10605
63
+
64
+      it "runs part 2 monkey machine for 10000 rounds" $ do
65
+        let monkeys = runMonkeyMachine (worryLimit exampleMonkeys) 10000 exampleMonkeys
66
+        map _inspectionCount monkeys
67
+          `shouldBe` [52166, 47830, 1938, 52013]
68
+        monkeyBusiness (mostActiveMonkeys monkeys) `shouldBe` 2713310158

読み込み中…
キャンセル
保存