Files
AoC2023/day08.hs
Amneesh Singh cd5fcfef07 day 8
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
2023-12-17 17:31:27 +05:30

45 lines
1.3 KiB
Haskell

import Data.Either (rights)
import Data.Map qualified as M
import Data.Text qualified as T
import Lib (readFile')
import Text.Parsec
main :: IO ()
main = do
(directionsRaw : _ : mapsRaw) <- T.lines <$> readFile' "day08.in"
let directions = cycle $ T.unpack directionsRaw
let maps' = rights $ map (parse parseMap "") mapsRaw
let maps = M.fromList maps'
putStr "Q1: "
print $ zzz directions maps 0 "AAA"
putStr "Q2: "
print . foldl1 lcm . map (xxz directions maps 0) . filter (\[_, _, c] -> c == 'A') . map fst $ maps'
-- dumb and good recursion
zzz :: String -> M.Map String (String, String) -> Int -> String -> Int
zzz (d : ds) m acc str
| next == "ZZZ" = acc + 1
| otherwise = zzz ds m (acc + 1) next
where
Just (left, right) = M.lookup str m
next = if d == 'L' then left else right
xxz :: String -> M.Map String (String, String) -> Int -> String -> Int
xxz (d : ds) m acc str
| [_, _, 'Z'] <- next = acc + 1
| otherwise = xxz ds m (acc + 1) next
where
Just (left, right) = M.lookup str m
next = if d == 'L' then left else right
-- Parsing --
parseMap :: (Stream s m Char) => ParsecT s u m (String, (String, String))
parseMap = do
a <- many1 letter <* string " = ("
b <- many1 letter <* string ", "
c <- many1 letter <* char ')'
return (a, (b, c))