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 d035570

Browse files
committed
day 17 reflections
1 parent caa6dc7 commit d035570

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

‎README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ processes and how my solutions all work. Benchmarks also included.
2727
* **[Day 14 Reflections][d14r]** *([code][d14c])* *([benchmarks][d14b])*
2828
* **[Day 15 Reflections][d15r]** *([code][d15c])* *([benchmarks][d15b])*
2929
* **[Day 16 Reflections][d16r]** *([code][d16c])* *([benchmarks][d16b])*
30-
* **Day 17 Reflections** *([code][d17c])* *([benchmarks][d17b])*
30+
* **[Day 17 Reflections][d17r]** *([code][d17c])* *([benchmarks][d17b])*
3131
* **Day 18 Reflections** *([code][d18c])* *([benchmarks][d18b])*
3232
* **Day 19 Reflections** *([code][d19c])* *([benchmarks][d19b])*
3333
* **Day 20 Reflections** *([code][d20c])* *([benchmarks][d20b])*

‎reflections.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,69 @@ Day 17
16991699

17001700
[d17c]: https://github.com/mstksg/advent-of-code-2017/blob/master/src/AOC2017/Day17.hs
17011701

1702+
For Day 17 I used `Tape` again -- for the O(1) insertions. (Even though moving
1703+
around is amortized O(n)).
1704+
1705+
```haskell
1706+
data Tape a = Tape { _tLefts :: [a]
1707+
, _tFocus :: a
1708+
, _tRights :: [a]
1709+
}
1710+
deriving Show
1711+
1712+
unshift :: a -> Tape a -> Tape a
1713+
unshift y (Tape ls x rs) = Tape (x:ls) y rs
1714+
1715+
moveRight :: Tape a -> Tape a
1716+
moveRight (Tape ls x rs) = case rs of
1717+
[] -> let l :| ls' = NE.reverse (x :| ls)
1718+
in Tape [] l ls'
1719+
r:rs' -> Tape (x:ls) r rs'
1720+
```
1721+
1722+
The only difference between this motion and the previous motion is the periodic
1723+
boundary conditions of tape motion. Before, if we went past the edge of the
1724+
tape, we'd return `Nothing`. Here, however, we want to "cycle" around, so we
1725+
reverse the left-hand list and move our focus to the last item in the list.
1726+
1727+
With that in mind, we can write our stepping function:
1728+
1729+
```haskell
1730+
step :: Int -> Tape a -> a -> Tape a
1731+
step n t0 x = unshift x . moveC n $ t0
1732+
```
1733+
1734+
We expect the number of steps to take, the initial tape, and the item to add.
1735+
This will cycle the tape the given number of steps and then insert the desired
1736+
item.
1737+
1738+
Part 1 is then just applying this as a `foldl`:
1739+
1740+
```haskell
1741+
day17a :: Int -> Int
1742+
day17a n = head . _tRights
1743+
$ foldl' (step n) (Tape [] 0 []) [1 .. 2017]
1744+
````
1745+
1746+
Part 2 can't really be done by iterating this process 50 million times. One
1747+
thing we can leverage is the fact that since 0 is there from the beginning (at
1748+
position 0), we only need to keep track of all the items that are ever inserted
1749+
at position 1:
1750+
1751+
```haskell
1752+
day17b :: Int -> Int
1753+
day17b n = last
1754+
. elemIndices @Int 1
1755+
$ scanl jump 0 [1 .. 5e7]
1756+
where
1757+
jump i x = ((i + n) `mod` x) + 1
1758+
```
1759+
1760+
At each step, we "jump" the `n` steps from the current position, being sure to
1761+
`mod` by the current size of the tape. `scanl` then gives us the position of
1762+
the cursor for all points in our process. We then find all of the positions
1763+
where the function jumps to `1` using `elemIndices`, and find the last one.
1764+
17021765
### Day 17 Benchmarks
17031766

17041767
```

‎src/AOC2017/Day17.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Data.List (elemIndices, foldl')
77
unshift :: a -> Tape a -> Tape a
88
unshift y (Tape ls x rs) = Tape (x:ls) y rs
99

10-
step :: Int -> Tape Int -> Int -> Tape Int
10+
step :: Int -> Tape a -> a -> Tape a
1111
step n t0 x = unshift x . moveC n $ t0
1212

1313
day17a :: Challenge

0 commit comments

Comments
(0)

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