Skip to content

Commit 6056c98

Browse files
committed
day 15 reflections and fixing links
1 parent 5e19743 commit 6056c98

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ processes and how my solutions all work. Benchmarks also included.
2323
* **[Day 10 Reflections][d10r]** *([code][d10c])* *([benchmarks][d10b])* *([stream][d10s])*
2424
* **[Day 11 Reflections][d11r]** *([code][d11c])* *([benchmarks][d11b])*
2525
* **[Day 12 Reflections][d12r]** *([code][d12c])* *([benchmarks][d12b])*
26-
* **[Day 13 Reflections][d12r]** *([code][d13c])* *([benchmarks][d13b])*
27-
* **Day 14 Reflections** *([code][d14c])* *([benchmarks][d14b])*
28-
* **Day 15 Reflections** *([code][d15c])* *([benchmarks][d15b])*
26+
* **[Day 13 Reflections][d13r]** *([code][d13c])* *([benchmarks][d13b])*
27+
* **[Day 14 Reflections][d14r]** *([code][d14c])* *([benchmarks][d14b])*
28+
* **[Day 15 Reflections][d15r]** *([code][d15c])* *([benchmarks][d15b])*
2929
* **Day 16 Reflections** *([code][d16c])* *([benchmarks][d16b])*
3030
* **Day 17 Reflections** *([code][d17c])* *([benchmarks][d17b])*
3131
* **Day 18 Reflections** *([code][d18c])* *([benchmarks][d18b])*

reflections.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,66 @@ Day 15
14621462

14631463
[d15c]: https://github.com/mstksg/advent-of-code-2017/blob/master/src/AOC2017/Day15.hs
14641464

1465+
This one is a really "easy" one from a Haskell perspective. We can just
1466+
generate the outputs of each stream as an infinite lazily linked list, take the
1467+
number of items we need, and count the pairs that match a specific predicate.
1468+
1469+
In particular, the predicate we care about is whether or not two items have the
1470+
same final 16 bits. This is the same as checking if two integers have value
1471+
when converted to `Word16`'s (16-bit words).
1472+
1473+
The generating function, given a "factor" and a "seed", is:
1474+
1475+
```haskell
1476+
generate :: Int -> Int -> Int
1477+
generate fac = (`mod` 2147483647) . (* fac)
1478+
```
1479+
1480+
We can then just generate them infinitely (using `iterate` and an initial
1481+
seed), zip the two streams together, take the first 40000000 items, filter for
1482+
the ones where the two items match, and count the length of the resulting list.
1483+
1484+
```haskell
1485+
match :: Int -> Int -> Bool
1486+
match = (==) @Word16 `on` fromIntegral
1487+
1488+
day15a :: Int -> Int -> Int
1489+
day15a seedA seedB = length
1490+
. filter (uncurry match)
1491+
. take 4e7
1492+
$ zip (iterate (generate 16807) seedA)
1493+
(iterate (generate 48271) seedB)
1494+
```
1495+
1496+
Part 2 is pretty much the same thing, except we filter for things that are
1497+
divisible by 4 in the first list, and things that are divisible by 8 in the
1498+
second list. To gain the "asynchronous" behavior that the problem is asking
1499+
for, we have to do this on the lists before they are zipped. That way, all
1500+
`zip` ever sees (and pairs) are the pre-filtered lists.
1501+
1502+
```haskell
1503+
divBy :: Int -> Int -> Bool
1504+
x `divBy` b = x `mod` b == 0
1505+
1506+
day15b :: Int -> Int -> Int
1507+
day15b seedA seedB = length
1508+
. filter (uncurry match)
1509+
. take 5e6
1510+
$ zip (filter (`divBy` 4) . iterate (generate 16807) $ seedA)
1511+
(filter (`divBy` 8) . iterate (generate 48271) $ seedB)
1512+
```
1513+
1514+
All in all a very nice "functional" problem with a functional solution :)
1515+
1516+
Parsing is basically finding the seeds as the only numeric values on each line:
1517+
1518+
```
1519+
parse :: String -> (Int, Int)
1520+
parse inp = (a, b)
1521+
where
1522+
a:b:_ = read . filter isDigit <$> lines inp
1523+
```
1524+
14651525
### Day 15 Benchmarks
14661526

14671527
```

src/AOC2017/Day14.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import AOC2017.Day10 (knothash)
44
import AOC2017.Types (Challenge)
55
import AOC2017.Util (strip)
66
import AOC2017.Util.Disjoints (Disjoints(..), disjoint)
7-
import Control.Monad (replicateM)
8-
import Data.Char (digitToInt)
97
import Data.Ix (index, range)
108
import Text.Printf (printf)
119
import qualified Data.IntSet as IS

0 commit comments

Comments
 (0)