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 f96fa9c

Browse files
committed
day 14 reflections
1 parent 26cc58c commit f96fa9c

File tree

3 files changed

+88
-22
lines changed

3 files changed

+88
-22
lines changed

‎reflections.md

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,33 +1072,37 @@ We can parse our input using `map read . splitOn "," :: String -> [Int]`,
10721072
Part 2 is pretty straightforward in that the *logic* is extremely simple, just
10731073
do a series of transformations.
10741074

1075+
First we can make the "knot hash" itself:
10751076

10761077
```haskell
1077-
day10b :: [Word8] -> String
1078-
day10b = toHex . process
1079-
. concat . replicate 64 . (++ salt)
1078+
knothash :: String -> [Word8]
1079+
knothash = map (foldr xor 0) . chunksOf 16 . V.toList . process
1080+
. concat . replicate 64 . (++ salt)
1081+
. map (fromIntegral . ord)
10801082
where
10811083
salt = [17, 31, 73, 47, 23]
1082-
toHex = concatMap (printf "%02x" . foldr xor 0) . chunksOf 16 . toList
1083-
strip = T.unpack . T.strip . T.pack
10841084
```
10851085

10861086
We:
10871087

1088-
3. Append the salt bytes at the end
1089-
4. `concat . replicate 64 :: [a] -> [a]`, replicate the list of inputs 64 times
1090-
5. `process` things like how we did in Part 1
1091-
7. Convert to hex:
1092-
* Break into chunks of 16 (using `chunksOf` from the *[split][]* library)
1093-
* `foldr` each chunk of 16 using `xor`
1094-
* Convert the resulting `Int` to a hex string, using `printf %02x`
1095-
* Aggregate all of the chunk results later
1088+
1. Append the salt bytes at the end
1089+
2. `concat . replicate 64 :: [a] -> [a]`, replicate the list of inputs 64 times
1090+
3. `process` things like how we did in Part 1
1091+
4. Break into chunks of 16 (using `chunksOf` from the *[split][]* library)
1092+
5. `foldr` each chunk of 16 using `xor`
10961093

1097-
Again, it's not super complicated, it's just that there are so many steps
1098-
described in the puzzle!
1094+
And our actual `day10b` is then just applying this and printing this as hex:
1095+
1096+
```haskell
1097+
day10b :: [Word8] -> String
1098+
day10b = concatMap (printf "%02x") . knothash
1099+
```
10991100

1100-
We can parse our input using `map (fromIntegral . ord) :: String -> [Word8]`,
1101-
taking care to also strip any leading and trailing whitespace first.
1101+
We leverage the `printf` formatter from `Text.Printf` to generate the hex,
1102+
being careful to ensure we pad the result.
1103+
1104+
Not super complicated, it's just that there are so many steps
1105+
described in the puzzle!
11021106

11031107
### Day 10 Benchmarks
11041108

@@ -1225,7 +1229,6 @@ instance Monoid Disjoints where
12251229
overlaps = S.filter (not . IS.null . (`IS.intersection` z)) zs
12261230
disjoints = zs `S.difference` overlaps
12271231
newGroup = IS.unions $ z : S.toList overlaps
1228-
12291232
```
12301233

12311234
The mappend action is union, but preserving disjoint connection property. If
@@ -1368,7 +1371,69 @@ Day 14
13681371

13691372
[d14c]: https://github.com/mstksg/advent-of-code-2017/blob/master/src/AOC2017/Day14.hs
13701373

1374+
Part 1 is a simple application of the "knot hash" function we wrote:
1375+
different inputs. We can make a row of a grid by running `knothash :: String
1376+
-> [Word8]` on the seed, using `printf` to format things as a binary string,
1377+
and then using `map (== '1')` to convert our binary string into a list of
1378+
`Bool`s. These represent a list of "on" or "off" cells.
1379+
1380+
```haskell
1381+
mkRow :: String -> Int -> [Bool]
1382+
mkRow seed n = map (== '1') . concatMap (printf "%08b") . knothash
1383+
$ seed ++ "-" ++ show n
1384+
```
1385+
1386+
Our grid is then just running this function for every row, to get a grid of
1387+
on/off cells:
1388+
1389+
```haskell
1390+
mkGrid :: String -> [[Bool]]
1391+
mkGrid seed = map (mkRow seed) [0..127]
1392+
```
1393+
1394+
The actual challenge is then just counting all of the `True`s:
1395+
1396+
```haskell
1397+
day14a :: String -> Int
1398+
day14a = length . filter id . concat . mkGrid
1399+
```
1400+
1401+
For Part 2, we can actually re-use the same `Disjoints` monoid that we used for
1402+
Day 12. We'll just add in sets of neighboring lit points, and count how many
1403+
disjoint sets come out at the end.
13711404

1405+
We're going to leverage `Data.Ix`, to let us enumerate over all cells in a grid
1406+
with `range :: ((Int, Int), (Int, Int)) -> [(Int, Int)]`. `Data.Ix` also gives
1407+
us `index :: (Int, Int) -> Int`, which allows us to "encode" a coordinate as an
1408+
`Int`, so we can use it with the `IntSet` that we wrote earlier.
1409+
1410+
```haskell
1411+
litGroups :: [[Bool]] -> Disjoints
1412+
litGroups grid = foldMap go (range r)
1413+
where
1414+
r = ((0,0),(127,127))
1415+
isLit (x,y) = grid !! y !! x
1416+
go p | isLit p = D . S.singleton . IS.fromList
1417+
. map (index r) . (p:) . filter isLit
1418+
$ neighbors p
1419+
| otherwise = mempty
1420+
1421+
neighbors :: (Int, Int) -> [(Int, Int)]
1422+
neighbors (x,y) = [ (x+dx, y+dy) | (dx, dy) <- [(0,1),(0,-1),(1,0),(-1,0)]
1423+
, x+dx >= 0
1424+
, y+dy >= 0
1425+
, x+dx < 128
1426+
, y+dy < 128
1427+
]
1428+
```
1429+
1430+
So part 2 is just running `litGroups` and counting the resulting number of
1431+
disjoint groups:
1432+
1433+
```haskell
1434+
day14b :: String -> Int
1435+
day14b = S.size . getD . litGroups . mkGrid
1436+
```
13721437

13731438
### Day 14 Benchmarks
13741439

‎src/AOC2017/Day10.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ day10a = show . V.product . V.take 2
3535
. map read . splitOn ","
3636

3737
day10b :: Challenge
38-
day10b = toHex . knothash . strip
39-
where
40-
toHex = concatMap (printf "%02x")
38+
day10b = concatMap (printf "%02x") . knothash . strip
4139

4240
knothash :: String -> [Word8]
4341
knothash = map (foldr xor 0) . chunksOf 16 . V.toList . process

‎src/AOC2017/Day14.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ day14a :: Challenge
2222
day14a = show . length . filter id . concat . mkGrid
2323

2424
day14b :: Challenge
25-
day14b (mkGrid->grid) = show . S.size . getD $ foldMap go (range r)
25+
day14b = show . S.size . getD . litGroups . mkGrid
26+
27+
litGroups :: [[Bool]] -> Disjoints
28+
litGroups grid = foldMap go (range r)
2629
where
2730
r = ((0,0),(127,127))
2831
isLit (x,y) = grid !! y !! x

0 commit comments

Comments
(0)

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