-
Notifications
You must be signed in to change notification settings - Fork 8
/
Day05.hs
53 lines (47 loc) · 1.24 KB
/
Day05.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
-- |
-- Module : AOC.Challenge.Day05
-- License : BSD3
--
-- Stability : experimental
-- Portability : non-portable
--
-- Day 5. See "AOC.Solver" for the types used in this module!
module AOC.Challenge.Day05 (
day05a
, day05b
) where
import AOC.Solver ((:~>)(..))
import Data.Bits (complement, shiftR, (.&.))
import Data.Char (ord)
import Data.List (foldl')
import qualified Control.Foldl as F
seatId :: String -> Int
seatId = foldl' iGuessWe'reDoingThis 0
where
-- heh
iGuessWe'reDoingThis n c =
2 * n + (complement (ord c) `shiftR` 2) .&. 1
-- | Find the first missing item in the collection, in a single pass
findHole :: F.Fold Int (Maybe Int)
findHole = do
mn <- F.minimum
mx <- F.maximum
sm <- F.sum
pure $
missingItem <$> mn <*> mx <*> pure sm
where
missingItem mn mx sm = totalSum - sm
where
totalSum = mx*(mx+1)`div`2 - mn*(mn-1)`div`2
day05a :: [String] :~> Int
day05a = MkSol
{ sParse = Just . lines
, sShow = show
, sSolve = F.fold (F.premap seatId F.maximum)
}
day05b :: [String] :~> Int
day05b = MkSol
{ sParse = Just . lines
, sShow = show
, sSolve = F.fold (F.premap seatId findHole)
}