-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day13.hs
65 lines (55 loc) · 1.88 KB
/
Day13.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
module Javran.AdventOfCode.Y2021.Day13 (
) where
import Control.Monad
import Data.List.Split hiding (sepBy)
import qualified Data.Set as S
import Javran.AdventOfCode.Prelude
import Text.ParserCombinators.ReadP hiding (count, many)
data Day13 deriving (Generic)
type Dot = (Int, Int)
data FoldAlong = AlongX Int | AlongY Int deriving (Show)
foldInstrP :: ReadP FoldAlong
foldInstrP =
string "fold along "
*> ( (string "y=" *> (AlongY <$> decimal1P))
<++ (string "x=" *> (AlongX <$> decimal1P))
)
foldAlongX :: Int -> S.Set Dot -> S.Set Dot
foldAlongX hw xs = S.fromList do
(x, y) <- S.toList xs
case compare x hw of
LT -> pure (x, y)
EQ -> errInvalid
GT -> pure (hw * 2 - x, y)
foldAlongY :: Int -> S.Set Dot -> S.Set Dot
foldAlongY hh xs = S.fromList do
(x, y) <- S.toList xs
case compare y hh of
LT -> pure (x, y)
EQ -> errInvalid
GT -> pure (x, hh * 2 - y)
appFoldInstr :: FoldAlong -> S.Set Dot -> S.Set Dot
appFoldInstr = \case
AlongX x -> foldAlongX x
AlongY y -> foldAlongY y
instance Solution Day13 where
solutionRun _ SolutionContext {getInputS, answerShow, answerS, terminal} = do
[dotsRaw, foldInstrsRaw] <- splitOn [""] . lines <$> getInputS
let dots =
S.fromList $
fmap ((\[x, y] -> (x, y)) . fmap read . splitOn ",") dotsRaw
foldInstrs =
consumeOrDie foldInstrP <$> foldInstrsRaw
answerShow $ S.size $ appFoldInstr (head foldInstrs) dots
let result = foldl (flip appFoldInstr) dots foldInstrs
Just (MinMax2D ((minX, maxX), (minY, maxY))) =
foldMap (Just . minMax2D) $
S.toList result
forM_ [minY .. maxY] $ \y -> do
let (ff, tt) = case terminal of
Nothing -> (".", "#")
Just _ -> (" ", "██")
answerS $
concatMap
(\x -> if S.member (x, y) result then tt else ff)
[minX .. maxX]