-
Notifications
You must be signed in to change notification settings - Fork 5
/
Day14.hs
40 lines (34 loc) · 1.34 KB
/
Day14.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
module AOC2017.Day14 (day14a, day14b) where
import AOC2017.Day10 (knothash)
import AOC2017.Types (Challenge)
import AOC2017.Util (strip)
import AOC2017.Util.Disjoints (Disjoints(..), disjoint)
import Data.Ix (index, range)
import Text.Printf (printf)
import qualified Data.IntSet as IS
import qualified Data.Set as S
mkGrid :: String -> [[Bool]]
mkGrid (strip->k) = map mkRow [0..127]
where
mkRow :: Int -> [Bool]
mkRow n = map (== '1') . concatMap (printf "%08b") . knothash
$ k ++ "-" ++ show n
day14a :: Challenge
day14a = show . length . filter id . concat . mkGrid
day14b :: Challenge
day14b = show . S.size . getD . litGroups . mkGrid
litGroups :: [[Bool]] -> Disjoints
litGroups grid = foldMap go (range r)
where
r = ((0,0),(127,127))
isLit (x,y) = grid !! y !! x
go p | isLit p = disjoint . IS.fromList
. map (index r) . (p:) . filter isLit
$ neighbors p
| otherwise = mempty
neighbors :: (Int, Int) -> [(Int, Int)]
neighbors (x,y) = [ (x+dx, y+dy) | (dx, dy) <- [(0,1),(0,-1),(1,0),(-1,0)]
, inBounds (x + dx) && inBounds (y + dy)
]
where
inBounds z = z >= 0 && z < 128