-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay08.hs
51 lines (44 loc) · 1.53 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
module Day08 (solve) where
import Data.Function
import Data.List
type Tree = ((Int, Int), Int)
solve input lines = do
let forest = readTrees lines
forest
& countVisible
& print
forest
& concat
& map (scenicScore forest)
& maximum
& print
scenicScore forest tree@((x, y), candidateHeight) = do
let (mxCol, mxRow) = ((length . head) forest - 1, length forest - 1)
let up = [y-1, y-2 .. 0] & map (\y -> forest !! y !! x)
let down = [y+1, y+2 .. mxRow] & map (\y -> forest !! y !! x)
let left = [x-1, x-2 .. 0] & map (\x -> forest !! y !! x)
let right = [x+1, x+2 .. mxCol] & map (\x -> forest !! y !! x)
product $ map viewDist [up, down, left, right]
where
pick :: [Tree] -> [Tree]
pick [] = []
pick (tree@(pos, height):rest)
| height < candidateHeight = tree : pick rest
| otherwise = [tree]
viewDist = length . pick
countVisible forest = do
let flippedRows = map reverse forest
let columns = transpose forest
let flippedColumns = map reverse columns
let linesOfSight = concat [forest, flippedRows, columns, flippedColumns]
concatMap pickVisible linesOfSight & nub & length
pickVisible :: [Tree] -> [Tree]
pickVisible =
pick (-1)
where
pick mx [] = []
pick mx (tree@(_, h):rest) =
if h > mx then tree : pick h rest else pick mx rest
readTrees :: [String] -> [[Tree]]
readTrees =
zipWith (\y line -> zipWith (\x h -> ((x, y), read [h])) [0..] line) [0..]