From e8476369b70e7314c1191c5e22966cf90c159d61 Mon Sep 17 00:00:00 2001 From: eriedaberrie Date: Mon, 18 Dec 2023 13:18:18 -0800 Subject: [PATCH] 2023 day 15 --- 2023/15/Main1.hs | 11 ++++++++++ 2023/15/Main2.hs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 2023/15/Main1.hs create mode 100644 2023/15/Main2.hs diff --git a/2023/15/Main1.hs b/2023/15/Main1.hs new file mode 100644 index 0000000..13eb47b --- /dev/null +++ b/2023/15/Main1.hs @@ -0,0 +1,11 @@ +import Data.Bits ((.&.)) +import Data.Char (ord) +import Data.List (foldl') +import Data.List.Split (splitOn) + +getHash :: String -> Int +getHash = foldl' (\acc x -> (acc + ord x) * 17 .&. 255) 0 + +main :: IO () +main = print . sum . map getHash . splitOn "," . concat . lines + =<< readFile "data.txt" diff --git a/2023/15/Main2.hs b/2023/15/Main2.hs new file mode 100644 index 0000000..ebf70d7 --- /dev/null +++ b/2023/15/Main2.hs @@ -0,0 +1,52 @@ +import Data.Bits ((.&.)) +import Data.Char (ord) +import Data.List (deleteBy, findIndex, foldl') +import Data.List.Split (splitOn) +import qualified Data.Vector as V +import qualified Data.Vector.Mutable as MV +import Data.Vector (Vector, MVector) + +type Command = (String, Maybe Int) + +getHash :: String -> Int +getHash = foldl' (\acc x -> (acc + ord x) * 17 .&. 255) 0 + +parseCommand :: String -> Command +parseCommand s + | last s == '-' = (init s, Nothing) + | otherwise = (a, Just . read $ b) + where + (a:b:_) = splitOn "=" s + +sumFocusPower :: Vector (Vector (String, Int)) -> Int +sumFocusPower = timesIndexAndSum . V.map (timesIndexAndSum . V.map snd) + where + timesIndexAndSum = V.foldl' (+) 0 . V.imap ((*) . succ) + +performCommand + :: MVector MV.RealWorld (Vector (String, Int)) -> Command -> IO () +performCommand boxes (label, mFoc) = maybe performDash performEquals mFoc + where + boxN = getHash label + + readBox = MV.read boxes boxN + + writeBox = MV.write boxes boxN + + findPred = (== label) . fst + + performDash = writeBox . V.filter (not . findPred) =<< readBox + + performEquals foc = do + box <- readBox + let newLens = (label, foc) + addNewLens = V.snoc box newLens + swapLens i = V.modify (\v -> MV.write v i newLens) box + writeBox . maybe addNewLens swapLens . V.findIndex findPred $ box + +main :: IO () +main = do + commandStrs <- splitOn "," . concat . lines <$> readFile "data.txt" + boxes <- MV.replicate 256 V.empty + mapM_ (performCommand boxes . parseCommand) commandStrs + print . sumFocusPower =<< V.unsafeFreeze boxes