Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2764e12

Browse files
committed
part 1 for day 18
1 parent 1fe2763 commit 2764e12

File tree

1 file changed

+52
-3
lines changed

1 file changed

+52
-3
lines changed

‎reflections.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,14 +1990,18 @@ Now, `stepTape` is an action (in `State` and `Maybe`) that uses an underlying
19901990
get the underlying `Machine` action using:
19911991

19921992
```haskell
1993-
execTapeProg :: TapeProg a -> ProgState -> Machine ProgState
1993+
runTapeProg :: TapeProg a -> (ProgState -> Machine (a, ProgState))
1994+
runTapeProg tp ps = flip runStateT ps . runMaybeT $ tp
1995+
1996+
execTapeProg :: TapeProg a -> (ProgState -> Machine (a, ProgState))
19941997
execTapeProg tp ps = flip execStateT ps . runMaybeT $ tp
19951998
```
19961999

19972000
Which will "run" a `TapeProg a`, with a given state, to produce the `Machine`
1998-
action (basically, a tree of nested `CRcv` and `CSnd`).
2001+
action (basically, a tree of nested `CRcv` and `CSnd`). You can think of this
2002+
as "compiling" a `TapeProg a` to be a `ProgState -> Machine (a, ProgState)`
19992003

2000-
Conceptually, this is similar to how `execStateT :: StateT s IO a -> IO s`
2004+
Conceptually, this is similar to how `runStateT :: StateT s IO a -> IO (a, s)`
20012005
produces an `IO` action that computes the final state that the `execStateT`
20022006
encodes.
20032007

@@ -2020,6 +2024,51 @@ stepTape :: TapeProg ()
20202024
many stepTape :: TapeProg [()]
20212025
```
20222026

2027+
### Part 1
2028+
2029+
Okay, so, once we get a `ProgState -> Machine ProgState` that represents
2030+
repeatedly running `stepTape` until we run out of bounds, how do we get our
2031+
answer?
2032+
2033+
Part 1 asks for the first successful `rcv` ("recover"). We need to properly
2034+
interpret our `Command` in an environment that lets us recover this.
2035+
2036+
We can use `StateT (Maybe Int) (Writer [Int])`:
2037+
2038+
* The `Maybe Int` state represents the last thing "sent".
2039+
* The `[Int]` writer log represents all of the "recovered" things.
2040+
2041+
```haskell
2042+
type PartA = StateT (Maybe Int) (Writer [Int])
2043+
```
2044+
2045+
Interpreting this is straightforward:
2046+
2047+
```haskell
2048+
interpretA :: Command a -> PartA a
2049+
interpretA = \case
2050+
CSnd x -> put (Just x)
2051+
CRcv x -> do
2052+
when (x /= 0) $
2053+
lastSent <- get
2054+
forM_ lastSet $ \y ->
2055+
lift $ tell [y]
2056+
return x
2057+
```
2058+
2059+
And now we can "run" it to get our Part 1 answer!
2060+
2061+
```haskell
2062+
execPartA :: PartA a -> Int
2063+
execPartA = head . snd . runWriter . flip execStateT Nothing
2064+
2065+
day18a :: Tape Op -> Int
2066+
day18a = execPartA -- run the `PartA` to get the answer
2067+
. runPromptM interpretA -- interpret `Machine ProgState` to `PartA ProgState`
2068+
. execTapeProg (many stepTape) -- compile `many stepTape` to `Machine ProgState`
2069+
. (`PS` M.empty) -- assemble `ProgState`
2070+
```
2071+
20232072
### Day 18 Benchmarks
20242073

20252074
```

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /