1+ {-# LANGUAGE NoImplicitPrelude #-}
2+
13module AdventOfCode.Year2020.Day17
24 ( main ,
35 getInput ,
@@ -6,37 +8,46 @@ module AdventOfCode.Year2020.Day17
68 )
79where
810
9- import AdventOfCode.Input (parseInput )
10- import AdventOfCode.TH (inputFilePath )
11+ import AdventOfCode.Input (parseInputAoC )
12+ import AdventOfCode.Puzzle
13+ import AdventOfCode.TH (defaultMainPuzzle )
1114import AdventOfCode.Util (neighborsOf )
12- import Control.Applicative ((<|>) )
1315import Control.Lens (ifoldl' , set )
14- import Data.Functor (($>) )
16+ import Data.List.Infinite ((!!) )
17+ import Data.List.Infinite qualified as Infinite
1518import Data.Map qualified as Map
16- import Data.Set (Set )
1719import Data.Set qualified as Set
1820import Linear (R2 (.. ), V2 (.. ), V3 (.. ), V4 (.. ))
21+ import Relude
1922import Text.Trifecta
2023
24+ type Domain f =
25+ ( Applicative f ,
26+ Traversable f ,
27+ R2 f ,
28+ Num (f Int ),
29+ Ord (f Int )
30+ ) ::
31+ Constraint
32+
33+ type Codomain f a = Set (f Int ) -> a
34+
2135main :: IO ()
22- main =
23- do
24- input <- getInput
25- putStr " Part One: "
26- print $ partOne (mkPocketDimension input)
27- putStr " Part Two: "
28- print $ partTwo (mkPocketDimension input)
36+ main = $ (defaultMainPuzzle)
2937
3038getInput :: IO [[Bool ]]
31- getInput = parseInput region $ (inputFilePath)
39+ getInput = parseInputAoC 2020 17 cubeRegion
40+
41+ partOne :: SimplePuzzle [[Bool ]] Int
42+ partOne = asks (solve . mkPocketDimension @ V3 )
3243
33- partOne :: Set ( V3 Int ) -> Int
34- partOne = Set. size . ( !! 6 ) . iterate stepCycle
44+ partTwo :: SimplePuzzle [[ Bool ]] Int
45+ partTwo = asks (solve . mkPocketDimension @ V4 )
3546
36- partTwo :: Set ( V4 Int ) -> Int
37- partTwo = Set. size . (!! 6 ) . iterate stepCycle
47+ solve :: ( Domain f ) => Codomain f Int
48+ solve = Set. size . (!! 6 ) . Infinite. iterate stepCycle
3849
39- stepCycle :: (Applicative f , Traversable f , Num ( f Int ), Ord ( f Int )) => Set ( f Int ) -> Set (f Int )
50+ stepCycle :: (Domain f ) => Codomain f ( Set (f Int ) )
4051stepCycle activeCubes = stillActive <> activated
4152 where
4253 stillActive = filterNeighborCounts (\ n -> n == 2 || n == 3 ) activeNeighborCounts
@@ -45,19 +56,22 @@ stepCycle activeCubes = stillActive <> activated
4556 inactiveNeighborCounts = neighborCounts `Map.withoutKeys` activeCubes
4657 filterNeighborCounts p = Map. keysSet . Map. filter p
4758 neighborCounts =
48- Map. unionsWith ((+) :: Int -> Int -> Int ) $
49- Map. fromSet (const 1 ) . neighborsOf
50- <$> Set. toList activeCubes
59+ Map. unionsWith ((+) :: Int -> Int -> Int )
60+ $ Map. fromSet (const 1 )
61+ . neighborsOf
62+ <$> Set. toList activeCubes
5163
52- mkPocketDimension :: (Applicative f , R2 f , Ord ( f Int ) ) => [[Bool ]] -> Set (f Int )
64+ mkPocketDimension :: (Domain f ) => [[Bool ]] -> Set (f Int )
5365mkPocketDimension = ifoldl' (ifoldl' . go) Set. empty
5466 where
55- go y x activeCubes True = Set. insert (set _xy (V2 x y) ( pure 0 ) ) activeCubes
67+ go y x activeCubes True = Set. insert (set _xy (V2 x y) 0 ) activeCubes
5668 go _ _ activeCubes False = activeCubes
5769
58- region :: Parser [[Bool ]]
59- region = some cube `sepEndBy` newline
70+ cubeRegion :: Parser [[Bool ]]
71+ cubeRegion = some cube `sepEndBy` newline
6072 where
6173 cube =
62- char ' #' $> True
63- <|> char ' .' $> False
74+ char ' #'
75+ $> True
76+ <|> char ' .'
77+ $> False
0 commit comments