-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday8.hs
88 lines (69 loc) · 3.02 KB
/
day8.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import Data.Map qualified as M
import Data.Maybe (fromJust)
import Data.List (foldl')
import GHC.Utils.Misc (countWhile)
data Elem = Elem String
deriving (Eq, Ord, Show)
endsWithChar :: Char -> Elem -> Bool
endsWithChar c (Elem e) = e !! 2 == c
data Map = Map {instrs :: [Char], nodes :: M.Map Elem (Elem, Elem)}
deriving (Show)
parseMap :: [String] -> Map
parseMap lns = Map {instrs = head lns, nodes = M.fromList (map parseMapLine (drop 2 lns))}
where
parseMapLine :: String -> (Elem, (Elem, Elem))
parseMapLine str = (Elem (take 3 str), (Elem (take 3 (drop 7 str)), Elem (take 3 (drop 12 str))))
turnsUntilResolution :: Map -> Int
turnsUntilResolution m = turnHelper m (Elem "AAA") (cycle (instrs m)) 0
where
turnHelper :: Map -> Elem -> [Char] -> Int -> Int
turnHelper _ (Elem "ZZZ") _ turn = turn
turnHelper m state instrs turn = turnHelper m ((case head instrs of
'R' -> snd
'L' -> fst
_ -> error "Unknown movement character")
(fromJust (M.lookup state (nodes m)))) (drop 1 instrs) (turn + 1)
turnsUntilResolutionStart :: Map -> Elem -> Int
turnsUntilResolutionStart m e = turnHelper m e (cycle (instrs m)) 0
where
turnHelper :: Map -> Elem -> [Char] -> Int -> Int
turnHelper _ state _ turn | endsWithZ state = turn
turnHelper m state instrs turn = turnHelper m ((case head instrs of
'R' -> snd
'L' -> fst
_ -> error "Unknown movement character")
(fromJust (M.lookup state (nodes m)))) (drop 1 instrs) (turn + 1)
endsWithA = endsWithChar 'A'
endsWithZ = endsWithChar 'Z'
transElem :: Map -> Elem -> Char -> Elem
transElem m state direc = ((case direc of
'R' -> snd
'L' -> fst
_ -> error "Unknown movement character") (fromJust (M.lookup state (nodes m))))
transitionN :: Map -> [Char] -> Elem -> Int -> Elem
transitionN m instrs state times = foldl' (transElem m) state (take times instrs)
ghostTurnsUntilResolution :: Map -> Int
ghostTurnsUntilResolution m = turnHelper m startElems (cycle (instrs m)) 0
where
endsWithA = endsWithChar 'A'
endsWithZ = endsWithChar 'Z'
startElems = filter endsWithA (M.keys (nodes m))
elemTransition :: Elem -> Char -> Elem
elemTransition state direc = ((case direc of
'R' -> snd
'L' -> fst
_ -> error "Unknown movement character") (fromJust (M.lookup state (nodes m))))
turnHelper :: Map -> [Elem] -> [Char] -> Int -> Int
turnHelper m state instrs turn = countWhile (not . all . endsWithZ) (scanl (transElem) startElems instrs)
-- turnHelper m states instrs turn
-- | all endsWithZ states = turn
-- | otherwise = turnHelper m (map (\state -> elemTransition state (head instrs)) states) (drop 1 instrs) (turn + 1)
main :: IO ()
main = do
input <- fmap lines (readFile "input")
let inputMap = parseMap input
-- print (turnsUntilResolution inputMap)
print (filter endsWithA (M.keys (nodes inputMap)))
let startNodes = filter endsWithA (M.keys (nodes inputMap))
print (map (turnsUntilResolutionStart inputMap) startNodes)
print (ghostTurnsUntilResolution inputMap)