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 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)

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