Skip to content

Commit 888a83d

Browse files
committed
clean(2024/Day21)
1 parent 8bf2622 commit 888a83d

File tree

1 file changed

+48
-44
lines changed

1 file changed

+48
-44
lines changed

2024/Day21/Day21.hs

+48-44
Original file line numberDiff line numberDiff line change
@@ -38,48 +38,55 @@ memoise2 :: (Ord a, Ord b) => Map (a, b) c -> (a -> b -> c) -> a -> b -> (Map (a
3838
memoise2 mem f a b
3939
| (a, b) `M.member` mem = (mem, mem M.! (a, b))
4040
| otherwise = (M.insert (a, b) res mem, res)
41-
where res = f a b
41+
where
42+
res = f a b
43+
44+
memoRec2 :: (Ord a, Ord b) => Map (a, b) c -> (Map (a, b) c -> a -> b -> (Map (a, b) c, c)) -> a -> b -> (Map (a, b) c, c)
45+
memoRec2 mem f a b
46+
| (a, b) `M.member` mem = (mem, mem M.! (a, b))
47+
| otherwise = (M.insert (a, b) res mem', res)
48+
where
49+
(mem', res) = f mem a b
4250

43-
memoise3 :: (Ord a, Ord b, Ord c) => Map (a, b, c) d -> (a -> b -> c -> d) -> a -> b -> c -> (Map (a, b, c) d, d)
51+
memoise3 :: (Ord a, Ord b, Ord c) => Map (a, b, c) d -> (a -> b -> c -> d) -> a -> b -> c -> (Map (a, b, c) d, d)
4452
memoise3 mem f a b c
4553
| (a, b, c) `M.member` mem = (mem, mem M.! (a, b, c))
4654
| otherwise = (M.insert (a, b, c) res mem, res)
47-
where res = f a b c
48-
49-
55+
where
56+
res = f a b c
5057

5158
goToY :: [(Int, Int)] -> (Int, Int) -> (Int, Int) -> String
5259
goToY possible (x, y) (x', y')
5360
| x == x' && y == y' = []
54-
| y < y' && (x, y+1) `elem` possible = 'v' : goToY possible (x, y + 1) (x', y')
55-
| y > y' && (x, y-1) `elem` possible = '^' : goToY possible (x, y - 1) (x', y')
56-
| x < x' && (x+1, y) `elem` possible = '>' : goToY possible (x + 1, y) (x', y')
57-
| x > x' && (x-1, y) `elem` possible = '<' : goToY possible (x - 1, y) (x', y')
61+
| y < y' && (x, y + 1) `elem` possible = 'v' : goToY possible (x, y + 1) (x', y')
62+
| y > y' && (x, y - 1) `elem` possible = '^' : goToY possible (x, y - 1) (x', y')
63+
| x < x' && (x + 1, y) `elem` possible = '>' : goToY possible (x + 1, y) (x', y')
64+
| x > x' && (x - 1, y) `elem` possible = '<' : goToY possible (x - 1, y) (x', y')
5865

5966
goToX :: [(Int, Int)] -> (Int, Int) -> (Int, Int) -> String
6067
goToX possible (x, y) (x', y')
6168
| x == x' && y == y' = []
62-
| x < x' && (x+1, y) `elem` possible = '>' : goToX possible (x + 1, y) (x', y')
63-
| x > x' && (x-1, y) `elem` possible = '<' : goToX possible (x - 1, y) (x', y')
64-
| y < y' && (x, y+1) `elem` possible = 'v' : goToX possible (x, y + 1) (x', y')
65-
| y > y' && (x, y-1) `elem` possible = '^' : goToX possible (x, y - 1) (x', y')
69+
| x < x' && (x + 1, y) `elem` possible = '>' : goToX possible (x + 1, y) (x', y')
70+
| x > x' && (x - 1, y) `elem` possible = '<' : goToX possible (x - 1, y) (x', y')
71+
| y < y' && (x, y + 1) `elem` possible = 'v' : goToX possible (x, y + 1) (x', y')
72+
| y > y' && (x, y - 1) `elem` possible = '^' : goToX possible (x, y - 1) (x', y')
6673

6774
isValid :: [(Int, Int)] -> (Int, Int) -> String -> Bool
6875
isValid validSpots xy [] = xy `elem` validSpots
69-
isValid validSpots (x, y) ('v':s) = (x, y) `elem` validSpots && isValid validSpots (x, y+1) s
70-
isValid validSpots (x, y) ('^':s) = (x, y) `elem` validSpots && isValid validSpots (x, y-1) s
71-
isValid validSpots (x, y) ('>':s) = (x, y) `elem` validSpots && isValid validSpots (x+1, y) s
72-
isValid validSpots (x, y) ('<':s) = (x, y) `elem` validSpots && isValid validSpots (x-1, y) s
76+
isValid validSpots (x, y) ('v' : s) = (x, y) `elem` validSpots && isValid validSpots (x, y + 1) s
77+
isValid validSpots (x, y) ('^' : s) = (x, y) `elem` validSpots && isValid validSpots (x, y - 1) s
78+
isValid validSpots (x, y) ('>' : s) = (x, y) `elem` validSpots && isValid validSpots (x + 1, y) s
79+
isValid validSpots (x, y) ('<' : s) = (x, y) `elem` validSpots && isValid validSpots (x - 1, y) s
7380

74-
generalEmulator :: Map (Int, Int) Char -> (Int, Int )-> String -> String
81+
generalEmulator :: Map (Int, Int) Char -> (Int, Int) -> String -> String
7582
generalEmulator poss posA code = sub code posA
7683
where
7784
sub [] _ = []
78-
sub ('A': l) xy = poss M.! xy : sub l xy
79-
sub ('v' : l) (x, y) = sub l (x, y+1)
80-
sub ('^' : l) (x, y) = sub l (x, y-1)
81-
sub ('>' : l) (x, y) = sub l (x+1, y)
82-
sub ('<' : l) (x, y) = sub l (x-1, y)
85+
sub ('A' : l) xy = poss M.! xy : sub l xy
86+
sub ('v' : l) (x, y) = sub l (x, y + 1)
87+
sub ('^' : l) (x, y) = sub l (x, y - 1)
88+
sub ('>' : l) (x, y) = sub l (x + 1, y)
89+
sub ('<' : l) (x, y) = sub l (x - 1, y)
8390

8491
numericalEmulator :: String -> String
8592
numericalEmulator code = generalEmulator numMap (2, 3) code
@@ -104,18 +111,18 @@ directionalEmulator code = generalEmulator dirMap (2, 0) code
104111
where
105112
dirMap = M.fromList $ [((1, 0), '^'), ((2, 0), 'A'), ((0, 1), '<'), ((1, 1), 'v'), ((2, 1), '>')]
106113

107-
108-
sequencerC :: [(Int, Int)] -> (Int, Int) -> (Int, Int) -> ((Int, Int), Set String)
109-
sequencerC valid xy' xy = (xy', S.map (++ "A") goTos)
114+
sequencerC :: [(Int, Int)] -> (Int, Int) -> (Int, Int) -> Set String
115+
sequencerC valid xy' xy = S.map (++ "A") goTos
110116
where
111117
goTos = S.fromList $ shorten . map (\gt -> gt valid xy xy') $ [goToX, goToY]
112118

113119
sequencer :: Map Char (Int, Int) -> String -> (Int, Int) -> Set String
114120
sequencer poss [] _ = S.singleton []
115121
sequencer poss (e : l) xy = sConcat $ S.map (\r -> S.map (++ r) goTos) $ nextRes
116122
where
123+
xy' = (poss M.! e)
117124
nextRes = sequencer poss l xy'
118-
(xy', goTos) = sequencerC (M.elems poss) (poss M.! e) xy
125+
goTos = sequencerC (M.elems poss) xy' xy
119126

120127
numericalSequencer :: String -> Set String
121128
numericalSequencer code = sequencer numMap code (numMap M.! 'A')
@@ -135,41 +142,38 @@ numericalSequencer code = sequencer numMap code (numMap M.! 'A')
135142
('A', (2, 3))
136143
]
137144

138-
139145
directionalSequencer :: String -> Set String
140-
directionalSequencer code = sequencer dirMap code (dirMap M.! 'A')
146+
directionalSequencer code = sequencer dirMap code (dirMap M.! 'A')
141147
where
142148
dirMap = M.fromList $ [('^', (1, 0)), ('A', (2, 0)), ('<', (0, 1)), ('v', (1, 1)), ('>', (2, 1))]
143149

144-
145150
depthMemorySequencer :: Map ((Int, Int), ((Int, Int), Int)) Int -> Int -> String -> (Map ((Int, Int), ((Int, Int), Int)) Int, Int)
146151
depthMemorySequencer mem depth code = sub mem depth code
147152
where
148153
dirMap = M.fromList $ [('^', (1, 0)), ('A', (2, 0)), ('<', (0, 1)), ('v', (1, 1)), ('>', (2, 1))]
154+
minLength = length . head . sortOn length
149155

150-
subc' :: Map ((Int, Int), ((Int, Int), Int)) Int -> Int -> (Int, Int) -> (Int, Int) -> (Map ((Int, Int), ((Int, Int), Int)) Int, Int)
151-
subc' mem' 1 c xy = memoise2 mem' (\c (xy, d) -> (length . head . sortOn length . S.toList) . snd $ sequencerC (M.elems dirMap) c xy) c (xy, 1)
152-
subc' mem' d c xy
153-
| (c, (xy, d)) `M.member` mem' = (mem', mem' M.! (c, (xy, d)))
154-
| otherwise = (M.insert (c, (xy, d)) r newMem, r)
156+
subc' :: Map ((Int, Int), ((Int, Int), Int)) Int -> (Int, Int) -> (Int, Int) -> Int -> (Map ((Int, Int), ((Int, Int), Int)) Int, Int)
157+
subc' mem' c xy 1 = memoise2 mem' f c (xy, 1)
155158
where
159+
f c (xy, 1) = minLength . S.toList $ sequencerC (M.elems dirMap) c xy
160+
subc' mem' c xy d = memoRec2 mem' f c (xy, d)
161+
where
162+
f m' c (xy, d) = S.foldl (\(m, r) s -> second (min r) $ sub m (d - 1) s) (m', maxBound) $ sequencerC (M.elems dirMap) c xy
156163

157-
(newMem, r) = S.foldl (\(m, r) s -> second (min r) $ sub m (d-1) s) (mem', maxBound) . snd $ sequencerC (M.elems dirMap) c xy
158-
159-
sub :: Map ((Int, Int), ((Int, Int), Int)) Int -> Int -> String -> (Map ((Int, Int), ((Int, Int), Int)) Int, Int)
160-
sub mem' d s = second snd $ foldl (\(m, (p, r)) e -> second (\r' -> (dirMap M.! e, r + r')) $ subc' m d (dirMap M.! e) p) (mem', ((dirMap M.! 'A'), 0)) s -- foldl
161-
162-
164+
sub :: Map ((Int, Int), ((Int, Int), Int)) Int -> Int -> String -> (Map ((Int, Int), ((Int, Int), Int)) Int, Int)
165+
sub mem' d s = second snd $ foldl f (mem', (dirMap M.! 'A', 0)) s
166+
where
167+
f (m, (p, r)) e = second (\r' -> (dirMap M.! e, r + r')) $ subc' m (dirMap M.! e) p d
163168

164169
getComplexity :: Int -> String -> Int
165-
getComplexity depth code = trace (show sequenceLength ++ "*" ++ show codeValue) codeValue * sequenceLength
170+
getComplexity depth code = trace (show sequenceLength ++ "*" ++ show codeValue) codeValue * sequenceLength
166171
where
167172
codeValue = read $ takeWhile isDigit code
168173
numSequences = numericalSequencer code
169174

170175
sequenceLength = snd $ foldl (\(m, r) s -> second (min r) $ depthMemorySequencer m depth s) (M.empty, maxBound) numSequences
171176

172-
173177
part1 :: Input -> Output
174178
part1 = sum . map (getComplexity 2)
175179

@@ -185,4 +189,4 @@ main = do
185189
print input
186190

187191
print $ part1 input -- (== 248684) $
188-
print $ part2 input --(== 307055584161760) $
192+
print $ part2 input -- (== 307055584161760) $

0 commit comments

Comments
 (0)