-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.hs
65 lines (52 loc) · 1.8 KB
/
run.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
import AoC.Grid (parseMapGrid, MapGrid)
import AoC.Search (bfs_)
import Data.Char (ord)
import Data.List (find)
import Data.Maybe (fromJust, mapMaybe)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
parseAll :: String -> MapGrid Char
parseAll = parseMapGrid id
-- TODO: Extract as helpers to AoC.Grid
type Pos = (Int, Int)
hv :: Pos -> [Pos]
hv (i, j) = [ (i + dx, j + dy) | dx <- [-1..1]
, dy <- [-1..1]
, dx == 0 || dy == 0 ]
hvNeighbors :: HashMap Pos a -> Pos -> [(Pos, a)]
hvNeighbors m =
mapMaybe (\pos -> sequence (pos, pos `HashMap.lookup` m))
. hv
validElev :: Int -> Int -> Bool
validElev from to =
to <= from + 1
part1 :: MapGrid Char -> Int
part1 g =
let Just (start, _) = find ((== 'S') . snd) . HashMap.toList $ g
Just (end, _) = find ((== 'E') . snd) . HashMap.toList $ g
g' = HashMap.map ord
. HashMap.insert start 'a'
. HashMap.insert end 'z'
$ g
neighbors (pos, elev) = filter (validElev elev . snd) $ hvNeighbors g' pos
in fromJust $ bfs_ ((== end) . fst) neighbors (start, ord 'a')
part2 :: MapGrid Char -> Int
part2 g =
let Just (start, _) = find ((== 'S') . snd) . HashMap.toList $ g
Just (end, _) = find ((== 'E') . snd) . HashMap.toList $ g
g' = HashMap.map ord
. HashMap.insert start 'a'
. HashMap.insert end 'z'
$ g
neighbors (pos, elev) = filter (flip validElev elev . snd) $ hvNeighbors g' pos
in
fromJust $ bfs_ ((== ord 'a') . snd) neighbors (end, ord 'z')
main :: IO ()
main = main' "input.txt"
exampleMain :: IO ()
exampleMain = main' "example.txt"
main' :: FilePath -> IO ()
main' file = do
input <- parseAll <$> readFile file
print (part1 input)
print (part2 input)