···
4
+
import qualified Data.Map as Map
5
+
import Data.Map (Map)
7
+
parse :: String -> Map String [String]
8
+
parse = Map.fromList . map parseLine . lines
9
+
where parseLine :: String -> (String, [String])
12
+
in (init $ head w, tail w)
14
+
pathCount :: Map String [String] -> String -> String -> Int
15
+
pathCount edges from to =
16
+
let m = Map.fromList [(v, ct v) | v <- Map.keys edges]
17
+
ct v = if v == to then 1 else sum $ map (m Map.!) (edges Map.! v)
part1 :: String -> String
4
-
part1 _ = "Day 11 part 1"
22
+
let edges = Map.insert "out" [] $ parse input
23
+
in show $ pathCount edges "you" "out"
26
+
pathCount2 :: Map String [String] -> String -> String -> Int
27
+
pathCount2 edges from to =
28
+
let neitherMemo = Map.fromList [(v, neither v) | v <- Map.keys edges]
29
+
neither v = if v == to then 1 else sum $ map (neitherMemo Map.!) (edges Map.! v)
31
+
withDacMemo = Map.fromList [(v, withDac v) | v <- Map.keys edges]
32
+
withDac v = if v == to then
34
+
else if v == "dac" then
35
+
sum $ map (neitherMemo Map.!) (edges Map.! v)
37
+
sum $ map (withDacMemo Map.!) (edges Map.! v)
39
+
withFftMemo = Map.fromList [(v, withFft v) | v <- Map.keys edges]
40
+
withFft v = if v == to then
42
+
else if v == "fft" then
43
+
sum $ map (neitherMemo Map.!) (edges Map.! v)
45
+
sum $ map (withFftMemo Map.!) (edges Map.! v)
47
+
withBothMemo = Map.fromList [(v, withBoth v) | v <- Map.keys edges]
48
+
withBoth v = if v == to then
50
+
else if v == "dac" then
51
+
sum $ map (withFftMemo Map.!) (edges Map.! v)
52
+
else if v == "fft" then
53
+
sum $ map (withDacMemo Map.!) (edges Map.! v)
55
+
sum $ map (withBothMemo Map.!) (edges Map.! v)
part2 :: String -> String
7
-
part2 _ = "Day 11 part 2"
60
+
let edges = Map.insert "out" [] $ parse input
61
+
in show $ pathCount2 edges "svr" "out"