8
8
module AOC2017.Day18 (day18a , day18b ) where
9
9
10
10
import AOC2017.Types (Challenge )
11
- import AOC2017.Util.Accum
11
+ import AOC2017.Util.Accum ( AccumT ( .. ), execAccumT , look , add )
12
12
import AOC2017.Util.Prompt ()
13
13
import AOC2017.Util.Tape (Tape (.. ), HasTape (.. ), move , unsafeTape )
14
14
import Control.Applicative (many , empty )
15
15
import Control.Lens (makeClassy , use , at , non , (%=) , use , (.=) , (<>=) , zoom )
16
16
import Control.Monad (guard , when )
17
- import Control.Monad.Prompt
18
- import Control.Monad.State
19
- import Control.Monad.Trans.Class (lift )
17
+ import Control.Monad.Prompt (MonadPrompt (.. ), runPromptM )
18
+ import Control.Monad.State (MonadState (.. ), execStateT , State , evalState )
20
19
import Control.Monad.Trans.Maybe (MaybeT (.. ))
21
- import Control.Monad.Writer
20
+ import Control.Monad.Writer ( First ( .. ), Last ( .. ), MonadWriter ( .. ), WriterT ( .. ), Writer , execWriter )
22
21
import Data.Char (isAlpha )
23
- import Data.Foldable
22
+ import Data.Coerce ( coerce )
24
23
import Data.Kind (Type )
25
24
import Data.Maybe (fromJust )
26
25
import qualified Data.Map as M
@@ -42,7 +41,6 @@ data Op = OSnd Addr
42
41
| OBin (Int -> Int -> Int ) Char Addr
43
42
| ORcv Char
44
43
| OJgz Addr Addr
45
- instance Show Op where show _ = " Op"
46
44
47
45
parseOp :: String -> Op
48
46
parseOp inp = case words inp of
@@ -78,7 +76,6 @@ sndMachine = prompt . CSnd
78
76
data ProgState = PS { _psTape :: Tape Op
79
77
, _psRegs :: M. Map Char Int
80
78
}
81
- deriving Show
82
79
makeClassy ''ProgState
83
80
84
81
-- | Single step through program tape.
@@ -116,23 +113,20 @@ stepTape = use (psTape . tFocus) >>= \case
116
113
117
114
-- | Context in which to interpret Command for Part A
118
115
--
119
- -- State parameter is the most recent sent item. Writer parameter is all
120
- -- of the Rcv'd items.
121
- --
122
- -- State should probably be Accum instead, but Accum is in any usable
123
- -- version of transformers yet.
124
- type PartA = AccumT (Last Int ) (Writer [Int ])
116
+ -- Accum parameter is the most recent sent item. Writer parameter is the
117
+ -- first Rcv'd item.
118
+ type PartA = AccumT (Last Int ) (Writer (First Int ))
125
119
execPartA :: PartA a -> Int
126
- execPartA = head . snd . runWriter . flip execAccumT mempty
120
+ execPartA = fromJust . getFirst . execWriter . flip execAccumT mempty
127
121
128
122
-- | Interpet Command for Part A
129
123
interpretA :: Command a -> PartA a
130
124
interpretA = \ case
131
125
CRcv x -> do
132
126
when (x /= 0 ) $
133
- lift . tell . toList =<< look
127
+ tell . coerce =<< look
134
128
return x
135
- CSnd x -> add (Last ( Just x) )
129
+ CSnd x -> add (pure x )
136
130
137
131
day18a :: Challenge
138
132
day18a = show
@@ -164,6 +158,9 @@ interpretB = \case
164
158
[] -> empty
165
159
x: xs -> put xs >> return x
166
160
161
+ -- runTapeB :: ProgState -> PartB Thread (ProgState, [Int])
162
+ -- runTapeB = zoom tBuffer . runWriterT . runPromptM interpretB . execStateT stepTape
163
+
167
164
-- | Single step through a thread. Nothing = either the thread terminates,
168
165
-- or requires extra input.
169
166
stepThread :: PartB Thread [Int ]
0 commit comments