-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay3.hs
65 lines (54 loc) · 1.69 KB
/
Day3.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 Day3
( part1
, part2
) where
import Control.Monad (void)
import Data.Char (isDigit)
import Data.Either (fromRight)
import Data.Set (Set, empty, fromList, intersection, size,
union)
import Helpers.Graph (Pos)
import Helpers.Parsers (Parser)
import Linear.V2 (V2 (..))
import Text.Megaparsec (eof, many, optional, parse, takeWhile1P)
import Text.Megaparsec.Char (char, eol, string)
type Claim = (Id, Rec)
type Rec = Set Pos
type Id = Int
findUnclaimed :: [Claim] -> Int
findUnclaimed claims =
fst . head . filter (null . intersection overclaimed . snd) $ claims
where
overclaimed = findOverlaps claims
findOverlaps :: [Claim] -> Set Pos
findOverlaps =
snd .
foldr
(\(_, a) (claimed, overclaimed) ->
(a `union` claimed, intersection a claimed `union` overclaimed))
(empty, empty)
parser :: Parser [Claim]
parser = many parseLine <* eof
parseLine :: Parser Claim
parseLine = do
void . char $ '#'
iD <- parseInt
void . string $ " @ "
ox <- parseInt
void . char $ ','
oy <- parseInt
void . string $ ": "
width <- parseInt
void . char $ 'x'
height <- parseInt
void . optional $ eol
return
( iD
, fromList
[V2 x y | x <- [ox .. ox + width - 1], y <- [oy .. oy + height - 1]])
parseInt :: Parser Int
parseInt = read <$> takeWhile1P Nothing isDigit
part1 :: Bool -> String -> String
part1 _ = show . size . findOverlaps . fromRight [] . parse parser ""
part2 :: Bool -> String -> String
part2 _ = show . findUnclaimed . fromRight [] . parse parser ""