This repository was archived by the owner on Nov 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathDay11.hs
108 lines (96 loc) · 3.15 KB
/
Day11.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
-- |
-- Module : AOC.Challenge.Day11
-- License : BSD3
--
-- Stability : experimental
-- Portability : non-portable
--
-- Day 11. See "AOC.Solver" for the types used in this module!
module AOC.Challenge.Day11 (
day11a
, day11b
) where
import AOC.Common (Dir(..), dirPoint, Point)
import AOC.Common.Intcode (Memory, parseMem, stepForeverAndDie, untilHalt)
import AOC.Solver ((:~>)(..))
import Advent.OCR (parseLettersWith)
import Control.DeepSeq (NFData)
import Control.Lens (view)
import Control.Monad (forever)
import Control.Monad.State (MonadState, gets, execState, modify)
import Data.Conduino (Pipe, (.|), runPipe, awaitSurely)
import Data.Functor ((<&>))
import Data.Map (Map)
import Data.Maybe (fromMaybe)
import Data.Void (Void)
import GHC.Generics (Generic)
import Linear (_x, _y)
import qualified Data.Conduino.Combinators as C
import qualified Data.Map as M
data Hull = Hull
{ hDir :: Dir
, hPos :: Point
, hMap :: Map Point Color
}
deriving (Eq, Ord, Show, Generic)
instance NFData Hull
data Color = Black | White
deriving (Eq, Ord, Enum, Show, Generic)
instance NFData Color
-- | Empty hull
emptyHull :: Hull
emptyHull = Hull North 0 M.empty
-- | Empty hull with a single colored item at the origin
singletonHull :: Color -> Hull
singletonHull c = Hull North 0 (M.singleton 0 c)
-- | The producer of signals. Sends 0 or 1 by detecting color under
-- current position on 'Hull'.
sensor
:: MonadState Hull m
=> Pipe () Int u m Void
sensor = C.repeatM . gets $ \(Hull _ p h) ->
case M.lookup p h of
Just White -> 1
_ -> 0
-- | The consumer of signals. Takes 0's and 1's to indicate color to paint
-- and direction to turn and step.
painterMover
:: MonadState Hull m
=> Pipe Int Void Void m Void
painterMover = forever $ do
color <- awaitSurely <&> \case
0 -> Black
1 -> White
_ -> undefined
turn <- awaitSurely <&> \case
0 -> West
1 -> East
_ -> undefined
modify $ \(Hull d p h) -> Hull
{ hDir = d <> turn
, hPos = p + dirPoint (d <> turn)
, hMap = M.insert p color h
}
-- | This is it
fullPipe
:: MonadState Hull m
=> Memory
-> Pipe () Void u m ()
fullPipe m = untilHalt $ sensor
.| stepForeverAndDie m
.| painterMover
day11a :: Memory :~> Int
day11a = MkSol
{ sParse = parseMem
, sShow = show
, sSolve = \m -> Just . M.size . hMap
$ execState (runPipe (fullPipe m)) emptyHull
}
day11b :: Memory :~> Map Point Color
day11b = MkSol
{ sParse = parseMem
, sShow = fromMaybe "" . parseLettersWith (view _x) (view _y)
. M.keysSet . M.filter (== White)
, sSolve = \m -> Just . hMap
$ execState (runPipe (fullPipe m)) (singletonHull White)
}