-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay08.hs
71 lines (64 loc) · 2.04 KB
/
Day08.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
-- |
-- Module : AOC2016.Day08
-- License : BSD3
--
-- Stability : experimental
-- Portability : non-portable
--
-- Day 8. See "AOC.Solver" for the types used in this module!
module AOC2016.Day08 (
day08a,
day08b,
) where
import AOC.Common.Point (parseLettersSafe)
import AOC.Solver ((:~>) (..))
import Data.Bifunctor (bimap)
import Data.Finite (Finite, modulo, packFinite, unshift)
import Data.List (foldl')
import Data.List.Split (splitOn)
import Data.Maybe (fromMaybe)
import Data.Set (Set)
import qualified Data.Set as S
import Linear (V2 (..))
import Text.Read (readMaybe)
type Screen = Set (Finite 50, Finite 6)
day08a :: [Command] :~> Int
day08a =
MkSol
{ sParse = traverse parseCommand . lines
, sShow = show
, sSolve = Just . S.size . foldl' (flip runCommand) S.empty
}
day08b :: [Command] :~> Screen
day08b =
MkSol
{ sParse = traverse parseCommand . lines
, sShow =
fromMaybe ""
. parseLettersSafe
. S.map (uncurry V2 . bimap fromIntegral fromIntegral)
, sSolve = Just . foldl' (flip runCommand) S.empty
}
data Command
= Rect (Finite 51) (Finite 7)
| RotRow (Finite 6) (Finite 50)
| RotCol (Finite 50) (Finite 6)
deriving stock (Show)
runCommand :: Command -> Screen -> Screen
runCommand = \case
Rect x y ->
let x' = fromMaybe 0 $ unshift x
y' = fromMaybe 0 $ unshift y
in S.union $ S.fromList ((,) <$> [0 .. x'] <*> [0 .. y'])
RotRow r n -> S.map (\(c, r') -> if r' == r then (c + n, r') else (c, r'))
RotCol c n -> S.map (\(c', r) -> if c' == c then (c', r + n) else (c', r))
parseCommand :: String -> Maybe Command
parseCommand str = case words str of
"rect" : s : _ -> do
x : y : _ <- Just $ splitOn "x" s
Rect <$> (packFinite =<< readMaybe x) <*> (packFinite =<< readMaybe y)
"rotate" : "row" : (_ : _ : r) : _ : n : _ -> do
RotRow <$> (packFinite =<< readMaybe r) <*> (modulo <$> readMaybe n)
"rotate" : "column" : (_ : _ : c) : _ : n : _ -> do
RotCol <$> (packFinite =<< readMaybe c) <*> (modulo <$> readMaybe n)
_ -> Nothing