-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay08.hs
63 lines (59 loc) · 1.52 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
-- |
-- Module : AOC2022.Day08
-- License : BSD3
--
-- Stability : experimental
-- Portability : non-portable
--
-- Day 8. See "AOC.Solver" for the types used in this module!
module AOC2022.Day08 (
day08a,
day08b,
)
where
import AOC.Common (countTrue, digitToIntSafe)
import AOC.Solver ((:~>) (..))
import Data.List (foldl', mapAccumL, transpose)
import qualified Data.Map as M
import Data.Profunctor (dimap)
import Safe.Foldable (maximumMay)
onSightLines ::
([Int] -> [a]) ->
(a -> a -> a) ->
[[Int]] ->
[a]
onSightLines f g rows =
foldl' (zipWith g) leftLines [rightLines, upLines, downLines]
where
leftLines = concatMap f rows
rightLines = concatMap (rev f) rows
upLines = concat $ tra (map f) rows
downLines = concat $ tra (map (rev f)) rows
rev = dimap reverse reverse
tra = dimap transpose transpose
day08a :: [[Int]] :~> Int
day08a =
MkSol
{ sParse = (traverse . traverse) digitToIntSafe . lines
, sShow = show
, sSolve =
Just
. countTrue id
. onSightLines (snd . mapAccumL propagateSight (-1)) (||)
}
where
propagateSight i x = (max i x, x > i)
day08b :: [[Int]] :~> Int
day08b =
MkSol
{ sParse = (traverse . traverse) digitToIntSafe . lines
, sShow = show
, sSolve =
maximumMay
. onSightLines (snd . mapAccumL findSight M.empty . zip [0 ..]) (*)
}
where
findSight lastSeeable (i, x) =
( M.fromList ((,i) <$> [0 .. x]) `M.union` lastSeeable
, i - M.findWithDefault 0 x lastSeeable
)