-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day10.hs
59 lines (48 loc) · 1.52 KB
/
Day10.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
module Main where
import Advent.Grid (Grid, Position)
import Advent.Grid qualified as Grid
import Advent.Utils (run)
import Data.Char (digitToInt)
type Input = Grid Int
testInput :: Input
testInput =
prepare
[ "89010123"
, "78121874"
, "87430965"
, "96549874"
, "45678903"
, "32019012"
, "01329801"
, "10456732"
]
{- | Take a starting positon and follows the trial to all
9 height endpoints. Returns the number of 9 endpoits.
-}
scoreTrail :: Input -> Position -> Int
scoreTrail g start = length $ filter id $ search (getValidNieghbors start) [] start <$> Grid.findAll (== 9) g
where
getValue :: Position -> Int
getValue = Grid.getWithDefault g 100
oneStep :: Position -> Position -> Bool
oneStep p1 p2 = getValue p2 == succ (getValue p1)
getValidNieghbors :: Position -> [Position]
getValidNieghbors p = filter (oneStep p) (Grid.cardinalNeighbors g p)
search :: [Position] -> [Position] -> Position -> Position -> Bool
search [] _ curr target = curr == target
search (v : vs) visited curr target
| curr == target = True
| otherwise =
let
newVisited = curr : visited
newToVisit = filter (`notElem` newVisited) (getValidNieghbors curr) <> vs
in
search newToVisit newVisited v target
part1 :: Input -> Int
part1 trailMap = sum $ scoreTrail trailMap <$> Grid.findAll (== 0) trailMap
part2 :: Input -> ()
part2 = const ()
prepare :: [String] -> Input
prepare = fmap digitToInt . Grid.fromList
main :: IO ()
main = run part1 part2 prepare