From bab443b919e2142a963546a21479f5d393f4cdc1 Mon Sep 17 00:00:00 2001 From: eriedaberrie Date: Thu, 7 Dec 2023 23:10:02 -0800 Subject: [PATCH] 2023 day 8: add Haskell solution --- .gitignore | 1 + 2023/8/Main1.hs | 26 ++++++++++++++++++++++++++ 2023/8/Main2.hs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 2023/8/Main1.hs create mode 100644 2023/8/Main2.hs diff --git a/.gitignore b/.gitignore index 592f45e..a6db57c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *data*.txt [Mm]ain [Mm]ain-[0-9] +[Mm]ain[0-9] # Nix stuff result* diff --git a/2023/8/Main1.hs b/2023/8/Main1.hs new file mode 100644 index 0000000..f8ae9c5 --- /dev/null +++ b/2023/8/Main1.hs @@ -0,0 +1,26 @@ +import qualified Data.HashMap.Strict as HMS + +type DataMap = HMS.HashMap String (String, String) + +getDirection :: Char -> (a, a) -> a +getDirection 'L' = fst +getDirection 'R' = snd + +countTimes :: String -> DataMap -> Int +countTimes directions m = countTimes' directions "AAA" 0 + where + countTimes' (d:ds) s + | s == "ZZZ" = id + | otherwise = countTimes' ds (getDirection d $ m HMS.! s) . succ + +getDataMap :: [String] -> DataMap +getDataMap = HMS.fromList . map parseLine + where + parseLine l = (take 3 l, (take 3 $ drop 7 l, take 3 $ drop 12 l)) + +main :: IO () +main = do + allLines <- lines <$> readFile "data.txt" + let directions = cycle $ head allLines + dataMap = getDataMap $ drop 2 allLines + print $ countTimes directions dataMap diff --git a/2023/8/Main2.hs b/2023/8/Main2.hs new file mode 100644 index 0000000..27dffde --- /dev/null +++ b/2023/8/Main2.hs @@ -0,0 +1,31 @@ +import qualified Data.HashMap.Strict as HMS +import Data.List (foldl1') + +type DataMap = HMS.HashMap String (String, String) + +getDirection :: Char -> (a, a) -> a +getDirection 'L' = fst +getDirection 'R' = snd + +countTimes :: String -> DataMap -> String -> Int +countTimes directions m start = countTimes' directions start 0 + where + countTimes' (d:ds) ss@(s:_) + | s == 'Z' = id + | otherwise = countTimes' ds (getDirection d $ m HMS.! ss) . succ + +solve :: String -> DataMap -> Int +solve directions m = foldl1' lcm $ map (countTimes directions m) $ filter ((== 'A') . head) $ HMS.keys m + +getDataMap :: [String] -> DataMap +getDataMap = HMS.fromList . map parseLine + where + revTake3 = reverse . take 3 + parseLine l = (revTake3 l, (revTake3 $ drop 7 l, revTake3 $ drop 12 l)) + +main :: IO () +main = do + allLines <- lines <$> readFile "data.txt" + let directions = cycle $ head allLines + dataMap = getDataMap $ drop 2 allLines + print $ solve directions dataMap